diff --git a/.env.dist b/.env.dist
index b613688c..ecfe0e83 100644
--- a/.env.dist
+++ b/.env.dist
@@ -21,3 +21,4 @@ BINANCE_LOCAL_TUNNEL_SUBDOMAIN=default
## Feature Toggles
BINANCE_FEATURE_TOGGLE_NOTIFY_ORDER_CONFIRM=true
BINANCE_FEATURE_TOGGLE_NOTIFY_DEBUG=false
+BINANCE_FEATURE_TOGGLE_NOTIFY_ORDER_EXECUTE=true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67456140..3ef5832e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file.
## Unreleased
- Make the local tunnel to be disabled by default. Thanks [@pedrohusky](https://github.com/pedrohusky)
+- Support Grid strategy for buy/sell to mitigate loss/increasing profit - [#158](https://github.com/chrisleekr/binance-trading-bot/issues/158)
+- Add frontend option to disable sorting or improve sorting - [#244](https://github.com/chrisleekr/binance-trading-bot/issues/244)
## [0.0.72] - 2021-07-07
diff --git a/Dockerfile b/Dockerfile
index 92b56098..f91d7ce7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,6 +3,9 @@ FROM node:14-alpine AS dev-stage
RUN apk add --no-cache make gcc g++ python
+# Add configuration files
+COPY image-files/ /
+
WORKDIR /srv
COPY package*.json ./
@@ -23,6 +26,8 @@ ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
LABEL com.chrisleekr.binance-trading-bot.node-env=${NODE_ENV}
+ENTRYPOINT [ "docker-entrypoint.sh" ]
+
CMD [ "npm", "run", "dev" ]
# build stage
@@ -49,8 +54,13 @@ ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
LABEL com.chrisleekr.binance-trading-bot.node-env=${NODE_ENV}
+# Add configuration files
+COPY image-files/ /
+
WORKDIR /srv
COPY --from=build-stage /srv /srv
+ENTRYPOINT [ "docker-entrypoint.sh" ]
+
CMD [ "npm", "start"]
diff --git a/README.ko.md b/README.ko.md
index 3836d57c..5f19ac0c 100644
--- a/README.ko.md
+++ b/README.ko.md
@@ -32,122 +32,190 @@
이 프로그램은 가격의 하락/상승 추세를 따라가며 추적 매수/추적 매도를 하는 기법을 기반으로 작성되었습니다.
+- 이 프로그램은 환경설정에 따라 여러번의 매수/매도가 가능합니다.
- 이 프로그램은 여러개의 코인을 모니터링 가능합니다. 각 코인들은 1초마다 가격 확인 및 매수/매도 처리가 됩니다.
- 이 프로그램은 지속적인 데이터베이스로 MongoDB를 사용합니다. 하지만 라즈베리파이 32bit 지원을 위해 최신 버젼을 사용하지 않습니다. 사용된 MongoDB 버젼은 [apcheamitru](https://hub.docker.com/r/apcheamitru/arm32v7-mongo)에서 제공된 3.2.20입니다
- 이 프로그램은 리눅스와 라즈베리파이 4 32비트에서만 테스트/작동 확인하였습니다. 다른 플랫폼은 테스트하지 않았습니다.
#### 매수 신호
-이 프로그램은 설정된 기간동안의 가장 낮은 가격을 모니터링합니다. 현재 값이 가장 낮은 가격에 도달했을 경우에, 프로그램은 매수를 위한 STOP-LOSS-LIMIT 주문을 넣습니다. 현재 가격이 계속 떨어질 경우, 프로그램은 이전 주문을 취소하고, 새로운 가격으로 STOP-LOSS-LIMIT 주문을 넣습니다.
+이 프로그램은 그리드 트레이딩 환경설정에 따라 코인을 모니터링합니다.
-- 이 프로그램은 매도를 위한 코인이 충분할 경우 (보통 $10정도) 매수 주문을 넣지않습니다.
+그리드 트레이딩 #1은 가장 현재 가격이 낮은 가격에 도달했을 경우에, 매수를 위한 STOP-LOSS-LIMIT 주문을 넣습니다. 현재 가격이 계속 떨어질 경우, 이전 주문을 취소하고, 새로운 가격으로 STOP-LOSS-LIMIT 주문을 넣습니다.
+
+그리드 트리이딩 #1 이후로는, 이전 매수 가격에 따라 코인을 모니터링합니다.
+
+- 매도를 위한 코인이 충분할 경우 (보통 $10정도), 그리드 트레이딩 #1의 매수 주문을 넣지않습니다.
+- 총 금액이 매수 가격 삭제 가격보다 낮을 경우 매수 가격을 삭제하지 않습니다.
##### 매수 시나리오
-예를 들어, 매수 환경설정이 다음과 같이 되었다고 가정해봅시다:
+예를 들어, 그리드 트레이딩 매수 환경설정이 다음과 같이 되었다고 가정해봅시다:
-- 최대 매수 수량(Maximum purchase amount): $50
-- 매수 시작 퍼센트(Trigger percentage): 1.005 (0.5%)
-- 스탑 가격 퍼센트(Stop price percentage): 1.01 (1.0%)
-- 리밋 가격 퍼센트(Limit price percentage): 1.011 (1.1%)
+- 그리드 트레이드 수 (Number of grids): 2
+- 그리드 트레이드
+ | 번호# | 매수 시작 퍼센트(Trigger Percentage) | 스탑 가격 퍼센트(Stop Price Percentage) | 리밋 가격 퍼센트(Limit price percentage) | USDT |
+ | --- | ------------------- | --------------------- | ---------------------- | ---- |
+ | 1 | 1 | 1.05 | 1.051 | 50 |
+ | 2 | 0.8 | 1.03 | 1.031 | 100 |
-그리고 현재 마켓이 아래와 같다고 가정합니다:
+이해를 쉽게 할수 있도록, USDT를 `$`로 표시하도록 하겠습니다. 또한, 쉽게 계산할 수 있도록 커미션은 계산에 넣지 않았습니다. 실제 거래에서는 수량이 다를 수 있습니다.
-- 현재 가격(Current price): $101
-- 최저 가격(Lowest price): $100
-- 매수 시작 가격(Trigger price): $100.5
+첫번째 그리드 트레이드의 설정은 다음과 같습니다:
-이럴 경우 현재 가격($101)이 매수 시작 가격($100.5)보다 높기 때문에, 프로그램은 주문을 넣지 않습니다.
+- 그리드 트레이드 번호#: 1
+- 매수 시작 퍼센트 (Trigger percentage): 1
+- 스탑 가격 퍼센트 (Stop percentage): 1.05 (5.00%)
+- 리밋 가격 퍼센트 (Limit percentage): 1.051 (5.10%)
+- 최대 매수 금액 (Max purchase amount): $50
-시간이 지나, 마켓이 다음과 같이 변했다고 가정합니다:
+현재 가격이 최저 가격($100)까지 떨어지고, 전고점(All-Time High) 제한 가격보다 낮을 경우, 프로그램은 새로운 STOP-LOSS-LIMIT 매수 주문을 넣습니다.
+
+- 스탑 가격 (Stop price): $100 * 1.05 = $105
+- 리밋 가격 (Limit price): $100 * 1.051 = $105.1
+- 수량 (Quantity): 0.47573
+
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
+
+- 현재 가격 (Current price): $95
+
+그러면 프로그램은 가격 하락을 따라가면서, 새로운 STOP-LOSS-LIMIT 매수 주문을 다음과 같이 넣습니다:
-- 현재 가격(Current price): $100
-- 최저 가격(Lowest price): $100
-- 매수 시작 가격(Trigger price): $100.5
+- 스탑 가격 (Stop price): $95 * 1.05 = $99.75
+- 리밋 가격 (Limit price): $95 * 1.051 = $99.845
+- 수량 (Quantity): 0.5
-현재 가격 ($100)이 매수 시작 가격($100.5)보다 낮기 때문에, 프로그램은 매수 STOP-LOSS-LIMIT 주문을 넣습니다. 간단한 계산을 위해 커미션은 계산하지 않았습니다. 실 거래시, 주문 수량은 다를 수 있습니다. 매수 주문은 다음과 같이 넣어집니다:
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
-- 스탑 가격(Stop price): $100 \* 1.01 = $101
-- 리밋 가격(Limit price): $100 \* 1.011 = $101.1
-- 수량(Quantity): 0.49
+- 현재 가격 (Current price): $100
-시간이 지나 마켓이 다음과 같이 변했다고 가정합니다:
+이때, 첫번째 매수가 체결됩니다. 이때, 매수 가격 (Last buy price)를 `$99.845`로 기록합니다. 매수 수량은 `0.5` 입니다.
-- 현재 가격(Current price): $99
-- 현재 리밋 가격(Current limit price): $99 \* 1.011 = 100.089
-- 주문 스탑 가격(Open order stop price): $101
+매수가 체결되면, 프로그램은 매도를 위해 모니터링을 함과 동시에, 다음 매수 그리드 트레이딩를 모니터링합니다.
-주문 스탑 가격($101)이 현재 리밋 가격($100.089)보다 높기 때문에, 프로그램은 현재 주문을 취소하고 새로운 매수 STOP-LOSS-LIMIT 주문을 넣습니다:
+두번째 그리드 트레이딩의 설정은 다음과 같습니다:
-- 스탑 가격(Stop price): $99 \* 1.01 = $99.99
-- 리밋 가격(Limit price): $99 \* 1.011 = $100.089
-- 수량(Quantity): 0.49
+- 그리드 트레이딩 번호#: 2
+- 매수 가격 (Current last buy price): $99.845
+- 매수 시작 퍼센트 (Trigger percentage): 0.8 (20%)
+- 스탑 가격 퍼센트 (Stop percentage): 1.03 (3.00%)
+- 리밋 가격 퍼센트 (Limit percentage): 1.031 (3.10%)
+- 최대 매수 금액 (Max purchase amount): $100
-만약 현재 가격이 계속 떨어진다면, 새로운 매수 주문이 새로운 가격에 맞춰 다시 넣어집니다.
+만약 현재 가격이 20% 낮은 `$79.876`까지 떨어지면, 프로그램은 두번째 그리드 트레이딩을 위한 STOP-LOSS-LIMIT 매수 주문을 넣습니다.
-만약 마켓이 다음과 같이 변했다고 가정합니다:
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
-- 현재 가격(Current price): $100
+- 현재 가격 (Current price): $75
-그러면 현재 가격이 스탑 가격($99.99)에 도달하였기 때문에, 매수 주문은 리밋 가격($100.089)에 체결이 됩니다.
+이때 프로그램은 가격 하락을 따라가면서, 새로운 STOP-LOSS-LIMIT 매수 주문을 다음과 같이 넣습니다.
+
+- 스탑 가격 (Stop price): $75 * 1.03 = $77.25
+- 리밋 가격 (Limit price): $75 * 1.031 = $77.325
+- 수량 (Quantity): 1.29
+
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
+
+- 현재 가격 (Current price): $78
+
+이때, 두번째 매수가 체결됩니다. 매수 가격 (Last buy price)는 자동으로 아래와 같이 계산 됩니다:
+
+- 최종 매수 가격: : ($50 + $100)/(0.5 COIN + 1.29 COIN) = $83.80
### 매도 신호
-만약 매도를 위한 충분한 코인이 있고 매수 가격(Last buy price)가 저장되었을 경우, 프로그램은 매도 신호를 모니터링하기 시작합니다. 현재 가격이 매도 시작 가격에 도달한다면, 프로그램은 매도 STOP-LOSS-LIMIT 주문을 넣습니다. 만약 현재 가격이 계속 상승한다면, 프로그램은 이전 주문을 취소하고, 새 가격으로 매도 STOP-LOSS-LIMIT 주문을 넣습니다.
+만약 매도를 위한 충분한 코인이 있고 매수 가격(Last buy price)가 저장되었을 경우, 프로그램은 첫번째 그리드 트레이딩을 위한 매도 신호를 모니터링하기 시작합니다. 현재 가격이 매도 시작 가격에 도달한다면, 프로그램은 매도 STOP-LOSS-LIMIT 주문을 넣습니다. 만약 현재 가격이 계속 상승한다면, 프로그램은 이전 주문을 취소하고, 새 가격으로 매도 STOP-LOSS-LIMIT 주문을 넣습니다.
-- 만약 코인이 최소 주문 금액 ($10)보다 평가금이 낮다면, Binance에서 $10미만의 주문은 접수되지 않기 때문에 프로그램은 매수 가격(Last buy price) 기록을 없앴니다
- .
-- 만약 매수 가격(Last buy price)가 저장되지 않았다면, 프로그램은 코인을 매도하지 않습니다.
+- 만약 매수 가격(Last buy price)가 저장되지 않았다면, 코인을 매도하지 않습니다.
+- 만약 코인 평가금이 매수 가격 삭제 금액보다 낮다면, 매수 가격 (Last buy price) 기록을 삭제합니다.
+- 만약 코인 평가금이 최소 주문 금액보다 낮다면, 코인을 매도하지 않습니다.
#### 매도 시나리오
-예를 들어, 매도 환경설정이 다음과 같이 되었다고 가정해봅시다:
+예를 들어, 그리드 트레이딩 매도 환경설정이 다음과 같이 되었다고 가정해봅시다:
-- 매도 시작 퍼센트(Trigger percentage): 1.05 (5.0%)
-- 스탑 가격 퍼센트(Stop price percentage): 0.98 (-2.0%)
-- 리밋 가격 퍼센트(Limit price percentage): 0.979 (-2.1%)
+- 그리드 트레이딩 수: 2
+- 그리드 트레이딩
+ | 번호# | 매도 시작 퍼센트(Trigger Percentage) | 스탑 가격 퍼센트(Stop Price Percentage) | 리밋 가격 퍼센트(Limit price percentage) | 매도 수량 퍼센트(Sell Quantity Percentage) |
+ | --- | ------------------- | --------------------- | ---------------------- |------------------------- |
+ | 1st | 1.05 | 0.97 | 0.969 | 0.5 |
+ | 2nd | 1.08 | 0.95 | 0.949 | 1 |
-그리고 현재 마켓이 아래와 같다고 가정합니다:
+매수와 다르게, 매도는 수량 퍼센트를 설정합니다. 만약 보유한 모든 수량을 매도할려면, 간단하게 `1` (100%)로 설정하시면 됩니다.
-- 소유 코인 수량(Coin owned): 0.5
-- 현재 가격(Current price): $100
-- 매수 가격(Last buy price): $100
-- 매도 시작 가격(Trigger price): $100 \* 1.05 = $105
+위에서 매수한 코인은 다음과 같습니다:
-이럴 경우 매도 시작 가격($105)이 현재 가격 ($100)보다 높기 때문에 프로그램은 주문을 넣지 않습니다.
+- 현재 수량 (Current quantity): 1.79
+- 현재 매수 가격 (Current last buy price): $83.80
-만약 현재 가격이 계속 하락한다면, 프로그램은 현재 가격이 매도 시작 가격에 도달할때까지 계속 모니터링합니다.
+첫번째 그리드 트레이드의 설정은 다음과 같습니다:
-시간이 지나, 마켓이 다음과 같이 변했다고 가정합니다:
+- 그리드 트레이딩 번호# 1
+- 매도 시작 퍼센트 (Trigger percentage): 1.05
+- 스탑 가격 퍼센트 (Stop price percentage): 0.97
+- 리밋 가격 퍼센트 (Limit price percentage): 0.969
+- 매도 수량 퍼센트 (Sell amount percentage): 0.5
+
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
+
+- 현재 가격 (Current price): $88
+
+현재 가격이 매도 시작 가격 ($87.99) 보다 높기 때문에, 새로운 STOP-LOSS-LIMIT 매도 주문을 다음과 같이 넣습니다:
+
+- 스탑 가격 (Stop price): $88 * 0.97 = $85.36
+- 리밋 가격 (Limit price): $88 * 0.969 = $85.272
+- 수량 (Quantity): 0.895
+
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
+
+- 현재 가격 (Current price): $90
+
+그러면 프로그램은 가격 상승을 따라가면서, 새로운 STOP-LOSS-LIMIT 주문을 다음과 같이 넣습니다:
+
+- 스탑 가격 (Stop price): $90 * 0.97 = $87.30
+- 리밋 가격 (Limit price): $90 * 0.969 = $87.21
+- 수량 (Quantity): 0.895
+
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
+
+- 현재 가격 (Current price): $87
+
+이때, 첫번째 매도 주문이 체결됩니다. 그러면 프로그램은 두번째 그리드 트레이딩 매도 시작 가격($83.80 * 1.08 = $90.504)을 기다립니다.
+
+- 현재 수량 (Current quantity): 0.895
+- 현재 매수 가격 (Current last buy price): $83.80
+
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
+
+- 현재 가격 (Current price): $91
-- 현재 가격(Current price): $105
-- 매도 시작 가격(Trigger price): $105
+현재 가격 ($91)은 두번째 매도 시작 가격 ($90.504)보다 높기 때문에, 프로그램은 새로운 STOP-LOSS-LIMIT 주문을 다음과 같이 넣습니다:
-현재 가격 ($105)가 매도 시작 가격($105)와 같거나 높기때문에 프로그램은 새로운 매도 STOP-LOSS-LIMIT 주문을 넣습니다. 간단한 계산을 위해 커미션은 계산하지 않았습니다. 실 거래시, 주문 수량은 다를 수 있습니다. 매도 주문은 다음과 같이 넣어집니다:
+- 스탑 가격 (Stop price): $91 * 0.95 = $86.45
+- 리밋 가격 (Limit price): $91 * 0.949 = $86.359
+- 수량 (Quantity): 0.895
-- 스탑 가격(Stop price): $105 \* 0.98 = $102.9
-- 리밋 가격(Limit price): $105 \* 0.979 = $102.795
-- 수량(Quantity): 0.5
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
-시간이 지나 마켓이 다음과 같이 변했다고 가정합니다.:
+- 현재 가격 (Current price): $100
-- 현재 가격(Current price): $106
-- 현재 리밋 가격(Current limit price): $103.774
-- 주문 스탑 가격(Open order stop price): $102.29
+그러면 프로그램은 가격 상승을 따라가면서, 새로운 STOP-LOSS-LIMIT 주문을 다음과 같이 넣습니다:
-주문 스탑 가격($102.29)가 현재 리밋 가격($103.774)보다 낮기 때문에, 프로그램은 현재 주문을 취소하고 새로운 매도 STOP-LOSS-LIMIT 주문을 넣습니다:
+- 스탑 가격 (Stop price): $100 * 0.95 = $95
+- 리밋 가격 (Limit price): $100 * 0.949 = $94.9
+- 수량 (Quantity): 0.895
-- 스탑 가격(Stop price): $106 \* 0.98 = $103.88
-- 리밋 가격(Limit price): $106 \* 0.979 = $103.774
-- 수량(Quantity): 0.5
+마켓이 다음과 같이 변동되었다고 가정해봅시다:
-만약 현재 가격이 계속 상승한다면, 새로운 매도 주문이 새로운 가격에 맞춰 다시 넣어집니다.
+- 현재 가격 (Current price): $94
-만약 마켓이 다음과 같이 변했다고 가정합니다:
+이때 두번째 매도 주문이 체결됩니다.
-- 현재 가격(Current price): $103
+최종 수익은 다음과 같습니다.
-그러면 현재 가격이 스탑 가격($103.88)에 도달하였기 때문에, 매도 주문은 리밋 가격($103.774)에 체결이 됩니다.
+- 첫번째 매도: $94.9 * 0.895 = $84.9355
+- 두번째 매도: $87.21 * 0.895 = $78.05295
+- 최종 수익: $162 (8% 수익)
### 매도 스탑-로스 시나리오
@@ -183,6 +251,7 @@
- 여러 코인들을 동시에 모니터링하기
- 스탑-로스
- 최고가일 경우 매수 제한하기
+- 매수/매도 그리드 트레이딩
### 프론트엔드 + 웹 소켓
@@ -258,11 +327,11 @@
| 프론트엔드 - 모바일 | 세팅 | 수동 거래 |
| --------------- | ---- | ------- |
-| ![Frontend Mobile](https://user-images.githubusercontent.com/5715919/124752399-262e5f00-df6b-11eb-9dc1-e8f06b98aa9a.png) | ![Setting](https://user-images.githubusercontent.com/5715919/124752414-2890b900-df6b-11eb-90f4-7fa79a84bf1d.png) | ![Manual Trade](https://user-images.githubusercontent.com/5715919/124752425-2c244000-df6b-11eb-97d9-d81e494d7e40.png) |
+| ![Frontend Mobile](https://user-images.githubusercontent.com/5715919/127318555-31216c7e-f27c-4e05-a3b1-1ebda386e439.png) | ![Setting](https://user-images.githubusercontent.com/5715919/127318581-4e422ac9-b145-4e83-a90d-5c05c61d6e2f.png) | ![Manual Trade](https://user-images.githubusercontent.com/5715919/127318630-f2180e1b-3feb-48fa-a083-4cb7f90f743f.png) |
| 프론트엔드 - 데스크탑 |
| ------------------------------------------------------------------------------------------------------------------------- |
-| ![Frontend Desktop](https://user-images.githubusercontent.com/5715919/124752605-668ddd00-df6b-11eb-887b-8cf79048d798.png) |
+| ![Frontend Desktop](https://user-images.githubusercontent.com/5715919/127318831-1cbfab93-6300-4251-b757-7d51eb5fbc2d.png) |
### 샘플 거래
diff --git a/README.md b/README.md
index deeadc17..933bea0f 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ incurred directly or indirectly by using this code. Read
## How it works
-### Trailing Buy/Sell Bot
+### Trailing Grid Trade Buy/Sell Bot
This bot is using the concept of trailing buy/sell order which allows following the price fall/rise.
@@ -38,6 +38,7 @@ This bot is using the concept of trailing buy/sell order which allows following
> TL;DR
> Place orders at a fixed value or percentage when the price changes. Using this feature you can buy at the lowest possible price when buying down and sell at the highest possible price when selling up.
+- The bot supports multiple buy/sell orders based on the configuration.
- The bot can monitor multiple symbols. All symbols will be monitored per second.
- The bot is using MongoDB to provide a persistence database. However, it does not use the latest MongoDB to support Raspberry Pi 32bit. Used MongoDB version
is 3.2.20, which is provided by [apcheamitru](https://hub.docker.com/r/apcheamitru/arm32v7-mongo).
@@ -45,115 +46,189 @@ This bot is using the concept of trailing buy/sell order which allows following
#### Buy Signal
-The bot will continuously monitor the lowest value for the period of the candles. Once the current price reaches the lowest price, then the bot will place a STOP-LOSS-LIMIT order to buy. If the current price continuously falls, then the bot will cancel the previous order and re-place the new STOP-LOSS-LIMIT order with the new price.
+The bot will continuously monitor the coin based on the grid trade configuration.
-- The bot will not place a buy order if has enough coin (typically over $10 worth) to sell when reaches the trigger price for selling.
+For grid trade #1, the bot will place a STOP-LOSS-LIMIT order to buy when the current price reaches the lowest price. If the current price continuously falls, then the bot will cancel the previous order and re-place the new STOP-LOSS-LIMIT order with the new price.
+
+After grid trade #1, the bot will monitor the COIN based on the last buy price.
+
+- The bot will not place a buy order of the grid trade #1 if has enough coin (typically over $10 worth) to sell when reaches the trigger price for selling.
+- The bot will remove the last buy price if the estimated value is less than the last buy price removal threshold.
##### Buy Scenario
-Let say, if the buy configurations are set as below:
+Let say, if the buy grid trade configurations are set as below:
+
+- Number of grids: 2
+- Grids
+ | No# | Trigger Percentage | Stop Price Percentage | Limit price percentage | USDT |
+ | --- | ------------------- | --------------------- | ---------------------- | ---- |
+ | 1 | 1 | 1.05 | 1.051 | 50 |
+ | 2 | 0.8 | 1.03 | 1.031 | 100 |
-- Maximum purchase amount: $50
-- Trigger percentage: 1.005 (0.5%)
-- Stop price percentage: 1.01 (1.0%)
-- Limit price percentage: 1.011 (1.1%)
+To make it easier to understand, I will use `$` as a USDT symbol. For the simple calculation, I do not take an account for the commission. In real trading, the quantity may be different.
+
+Your 1st grid trading for buying is configured as below:
+
+- Grid No#: 1
+- Trigger percentage: 1
+- Stop percentage: 1.05 (5.00%)
+- Limit percentage: 1.051 (5.10%)
+- Max purchase amount: $50
And the market is as below:
-- Current price: $101
+- Current price: $105
- Lowest price: $100
-- Trigger price: $100.5
+- Trigger price: $100
-Then the bot will not place an order because the trigger price ($100.5) is less than the current price ($101).
+When the current price is falling to the lowest price ($100) and lower than ATH(All-Time High) restricted price if enabled, the bot will place new STOP-LOSS-LIMIT order for buying.
-In the next tick, the market changes as below:
+- Stop price: $100 * 1.05 = $105
+- Limit price: $100 * 1.051 = $105.1
+- Quantity: 0.47573
+
+Let's assume the market changes as below:
+
+- Current price: $95
+
+Then the bot will follow the price fall and place new STOP-LOSS-LIMIT order as below:
+
+- Stop price: $95 * 1.05 = $99.75
+- Limit price: $95 * 1.051 = $99.845
+- Quantity: 0.5
+
+Let's assume the market changes as below:
- Current price: $100
-- Lowest price: $100
-- Trigger price: $100.5
-The bot will place new STOP-LOSS-LIMIT order for buying because the current price ($100) is less than the trigger price ($100.5). For the simple calculation, I do not take an account for the commission. In real trading, the quantity may be different. The new buy order will be placed as below:
+Then the bot will execute 1st purchase for the coin. The last buy price will be recorded as `$99.845`. The purchased quantity will be `0.5`.
-- Stop price: $100 \* 1.01 = $101
-- Limit price: $100 \* 1.011 = $101.1
-- Quantity: 0.49
+Once the coin is purchased, the bot will start monitoring the sell signal and at the same time, monitor the next grid trading for buying.
-In the next tick, the market changes as below:
+Your 2nd grid trading for buying is configured as below:
-- Current price: $99
-- Current limit price: $99 \* 1.011 = 100.089
-- Open order stop price: $101
+- Grid#: 2
+- Current last buy price: $99.845
+- Trigger percentage: 0.8 (20%)
+- Stop percentage: 1.03 (3.00%)
+- Limit percentage: 1.031 (3.10%)
+- Max purchase amount: $100
-As the open order's stop price ($101) is higher than the current limit price ($100.089), the bot will cancel the open order and place new STOP-LOSS-LIMIT order as below:
+And if the current price is continuously falling to `$79.876` (20% lower), then the bot will place new STOP-LOSS-LIMIT order for the 2nd grid trading for the coin.
-- Stop price: $99 \* 1.01 = $99.99
-- Limit price: $99 \* 1.011 = $100.089
-- Quantity: 0.49
+Let's assume the market changes as below:
-If the price continuously falls, then the new buy order will be placed with the new price.
+- Current price: $75
-And if the market changes as below in the next tick:
+Then the bot will follow the price fall and place new STOP-LOSS-LIMT order as below:
-- Current price: $100
+- Stop price: $75 * 1.03 = $77.25
+- Limit price: $75 * 1.031 = $77.325
+- Quantity: 1.29
+
+Let's assume the market changes as below:
-Then the current price reaches the stop price ($99.99); hence, the order will be executed with the limit price ($100.089).
+- Current price: $78
+
+Then the bot will execute 2nd purchase for the coin. The last buy price will be automatically re-calculated as below:
+
+- Final last buy price: ($50 + $100)/(0.5 COIN + 1.29 COIN) = $83.80
### Sell Signal
-If there is enough balance for selling and the last buy price is recorded in the bot, then the bot will start monitoring the sell signal. Once the current price reaches the trigger price, then the bot will place a STOP-LOSS-LIMIT order to sell. If the current price continuously rises, then the bot will cancel the previous order and re-place the new STOP-LOSS-LIMIT order with the new price.
+If there is enough balance for selling and the last buy price is recorded in the bot, then the bot will start monitoring the sell signal of the grid trade #1. Once the current price reaches the trigger price of the grid trade #1, then the bot will place a STOP-LOSS-LIMIT order to sell. If the current price continuously rises, then the bot will cancel the previous order and re-place the new STOP-LOSS-LIMIT order with the new price.
-- If the coin is worth less than typically $10 (minimum notional value), then the bot will remove the last buy price because Binance does not allow to place an order of less than $10.
- If the bot does not have a record for the last buy price, the bot will not sell the coin.
+- If the coin is worth less than the last buy price removal threshold, then the bot will remove the last buy price.
+- If the coin is not worth than the minimum notional value, then the bot will not place an order.
#### Sell Scenario
-Let say, if the sell configurations are set as below:
+Let say, if the sell grid trade configurations are set as below:
-- Trigger percentage: 1.05 (5.0%)
-- Stop price percentage: 0.98 (-2.0%)
-- Limit price percentage: 0.979 (-2.1%)
+- Number of grids: 2
+- Grids
+ | No# | Trigger Percentage | Stop Price Percentage | Limit price percentage | Sell Quantity Percentage |
+ | --- | ------------------- | --------------------- | ---------------------- |------------------------- |
+ | 1st | 1.05 | 0.97 | 0.969 | 0.5 |
+ | 2nd | 1.08 | 0.95 | 0.949 | 1 |
-And the market is as below:
+Unlike buy, the sell configuration will use the percentage of a quantity. If you want to sell all of your coin quantity, then simply configure it as `1` (100%).
-- Coin owned: 0.5
-- Current price: $100
-- Last buy price: $100
-- Trigger price: $100 \* 1.05 = $105
+From the last buy actions, you now have the following balances:
-Then the bot will not place an order because the trigger price ($105) is higher than the current price ($100).
+- Current quantity: 1.79
+- Current last buy price: $83.80
-If the price is continuously falling, then the bot will keep monitoring until the price reaches the trigger price.
+Your 1st grid trading for selling is configured as below:
-In the next tick, the market changes as below:
+- Grid No# 1
+- Trigger percentage: 1.05
+- Stop price percentage: 0.97
+- Limit price percentage: 0.969
+- Sell amount percentage: 0.5
-- Current price: $105
-- Trigger price: $105
+Let's assume the market changes as below:
-The bot will place new STOP-LOSS-LIMIT order for selling because the current price ($105) is higher or equal than the trigger price ($105). For the simple calculation, I do not take an account for the commission. In real trading, the quantity may be different. The new sell order will be placed as below:
+- Current price: $88
-- Stop price: $105 \* 0.98 = $102.9
-- Limit price: $105 \* 0.979 = $102.795
-- Quantity: 0.5
+As the current price is higher than the sell trigger price($87.99), then the bot will place new STOP-LOSS-LIMIT order for selling.
-In the next tick, the market changes as below:
+- Stop price: $88 * 0.97 = $85.36
+- Limit price: $88 * 0.969 = $85.272
+- Quantity: 0.895
-- Current price: $106
-- Current limit price: $103.774
-- Open order stop price: $102.29
+Let's assume the market changes as below:
-As the open order's stop price ($102.29) is less than the current limit price ($103.774), the bot will cancel the open order and place new STOP-LOSS-LIMIT order as below:
+- Current price: $90
-- Stop price: $106 \* 0.98 = $103.88
-- Limit price: $106 \* 0.979 = $103.774
-- Quantity: 0.5
+Then the bot will follow the price rise and place new STOP-LOSS-LIMIT order as below:
+
+- Stop price: $90 * 0.97 = $87.30
+- Limit price: $90 * 0.969 = $87.21
+- Quantity: 0.895
+
+Let's assume the market changes as below:
+
+- Current price: $87
+
+Then the bot will execute 1st sell for the coin. Then the bot will now wait for 2nd selling trigger price ($83.80 * 1.08 = $90.504).
+
+- Current quantity: 0.895
+- Current last buy price: $83.80
-If the price continuously rises, then the new sell order will be placed with the new price.
+Let's assume the market changes as below:
-And if the market changes as below in the next tick:
+- Current price: $91
-- Current price: $103
+Then the current price($91) is higher than 2nd selling trigger price ($90.504), the bot will place new STOP-LOSS-LIMIT order as below:
-The the current price reaches the stop price ($103.88); hence, the order will be executed with the limit price ($103.774).
+- Stop price: $91 * 0.95 = $86.45
+- Limit price: $91 * 0.949 = $86.359
+- Quantity: 0.895
+
+Let's assume the market changes as below:
+
+- Current price: $100
+
+Then the bot will follow the price rise and place new STOP-LOSS-LIMT order as below:
+
+- Stop price: $100 * 0.95 = $95
+- Limit price: $100 * 0.949 = $94.9
+- Quantity: 0.895
+
+Let's assume the market changes as below:
+
+- Current price: $94
+
+Then the bot will execute 2nd sell for the coin.
+
+The final profit would be
+
+- 1st sell: $94.9 * 0.895 = $84.9355
+- 2nd sell: $87.21 * 0.895 = $78.05295
+- Final profit: $162 (8% profit)
#### Sell Stop-Loss Scenario
@@ -189,6 +264,7 @@ The bot will also set the symbol to be temporarily disabled for 60 minutes to av
- Monitoring multiple coins simultaneously
- Stop-Loss
- Restrict buying with ATH price
+- Grid Trade for buy/sell
### Frontend + WebSocket
@@ -226,7 +302,6 @@ Or use the frontend to adjust configurations after launching the application.
*A local tunnel makes the bot accessible from the outside. Please set the subdomain of the local tunnel as a subdomain that only you can remember.*
-
2. Launch/Update the bot with docker-compose
Pull latest code first:
@@ -274,11 +349,11 @@ Or use the frontend to adjust configurations after launching the application.
| Frontend Mobile | Setting | Manual Trade |
| --------------- | ------- | ------------ |
-| ![Frontend Mobile](https://user-images.githubusercontent.com/5715919/124752399-262e5f00-df6b-11eb-9dc1-e8f06b98aa9a.png) | ![Setting](https://user-images.githubusercontent.com/5715919/124752414-2890b900-df6b-11eb-90f4-7fa79a84bf1d.png) | ![Manual Trade](https://user-images.githubusercontent.com/5715919/124752425-2c244000-df6b-11eb-97d9-d81e494d7e40.png) |
+| ![Frontend Mobile](https://user-images.githubusercontent.com/5715919/127318555-31216c7e-f27c-4e05-a3b1-1ebda386e439.png) | ![Setting](https://user-images.githubusercontent.com/5715919/127318581-4e422ac9-b145-4e83-a90d-5c05c61d6e2f.png) | ![Manual Trade](https://user-images.githubusercontent.com/5715919/127318630-f2180e1b-3feb-48fa-a083-4cb7f90f743f.png) |
| Frontend Desktop |
| ------------------------------------------------------------------------------------------------------------------------- |
-| ![Frontend Desktop](https://user-images.githubusercontent.com/5715919/124752605-668ddd00-df6b-11eb-887b-8cf79048d798.png) |
+| ![Frontend Desktop](https://user-images.githubusercontent.com/5715919/127318831-1cbfab93-6300-4251-b757-7d51eb5fbc2d.png) |
### Sample Trade
@@ -292,22 +367,20 @@ Please refer
[CHANGELOG.md](https://github.com/chrisleekr/binance-trading-bot/blob/master/CHANGELOG.md)
to view the past changes.
-- [ ] Support Grid strategy for buy/sell to mitigate loss/increasing profit - [#158](https://github.com/chrisleekr/binance-trading-bot/issues/158)
+- [ ] Filter symbols in the frontend - [#120](https://github.com/chrisleekr/binance-trading-bot/issues/120) [#242](https://github.com/chrisleekr/binance-trading-bot/pull/242)
+- [ ] Secure frontend with the password authentication - [#240](https://github.com/chrisleekr/binance-trading-bot/pull/240)
- [ ] Improve sell strategy with conditional stop price percentage based on the profit percentage - [#94](https://github.com/chrisleekr/binance-trading-bot/issues/94)
- [ ] Add sudden drop buy strategy - [#67](https://github.com/chrisleekr/binance-trading-bot/issues/67)
-- [ ] Improve buy strategy with restricting purchase if the price is close to ATH - [#82](https://github.com/chrisleekr/binance-trading-bot/issues/82)
-- [ ] Secure frontend with the password authentication
- [ ] Display summary of transactions on the frontend - [#160](https://github.com/chrisleekr/binance-trading-bot/issues/160)
- [ ] Add minimum required order amount - [#84](https://github.com/chrisleekr/binance-trading-bot/issues/84)
- [ ] Manage setting profiles (save/change/load?/export?) - [#151](https://github.com/chrisleekr/binance-trading-bot/issues/151)
-- [ ] Filter symbols in the frontend - [#120](https://github.com/chrisleekr/binance-trading-bot/issues/120)
-- [ ] Improve notifications by supporting Apprise [#106](https://github.com/chrisleekr/binance-trading-bot/issues/106)
+- [ ] Improve notifications by supporting Apprise - [#106](https://github.com/chrisleekr/binance-trading-bot/issues/106)
- [ ] Support cool time after hitting the lowest price before buy - [#105](https://github.com/chrisleekr/binance-trading-bot/issues/105)
-- [ ] Add frontend option to disable sorting or improve sorting
- [ ] Reset global configuration to initial configuration - [#97](https://github.com/chrisleekr/binance-trading-bot/issues/97)
- [ ] Support limit for active buy/sell orders - [#147](https://github.com/chrisleekr/binance-trading-bot/issues/147)
- [ ] Develop simple setup screen for secrets
- [ ] Support multilingual frontend - [#56](https://github.com/chrisleekr/binance-trading-bot/issues/56)
+- [ ] Non linear stop price and chase function - [#246](https://github.com/chrisleekr/binance-trading-bot/issues/246)
## Donations
diff --git a/README.zh-cn.md b/README.zh-cn.md
index 6c98af17..2ef879e6 100644
--- a/README.zh-cn.md
+++ b/README.zh-cn.md
@@ -33,122 +33,197 @@
>
> 简单来说就是在价格变化时,按固定的数值或百分比进行委托。利用这个特性可以在下跌买入时买到尽可能低的价格,在上涨卖出时卖出最高的价格。
-- 该机器人可以监测多个代币,并对每个代币的价格进行每秒监测。
-- 这个机器人只在 USDT 交易对中测试过,比如 BTC/USDT,ETH/USDT。你也可以添加其他与法币锚定的稳定币,比如 BUSD、AUD。但是我并没有使用这些稳定币在生产环境测试过,请自行承担风险。
-- 该机器人使用 MongoDB 数据库。然而,它并没有没有使用最新的 MongoDB 来支持Raspberry Pi 32bit,使用的 MongoDB 版本是3.2.20,这是由 [apcheamitru](https://hub.docker.com/r/apcheamitru/arm32v7-mongo) 提供的。
+- The bot supports multiple buy/sell orders based on the configuration.
+- The bot can monitor multiple symbols. All symbols will be monitored per second.
+- The bot is using MongoDB to provide a persistence database. However, it does not use the latest MongoDB to support Raspberry Pi 32bit. Used MongoDB version
+ is 3.2.20, which is provided by [apcheamitru](https://hub.docker.com/r/apcheamitru/arm32v7-mongo).
+- The bot is tested/working with Linux and Raspberry Pi 4 32bit. Other platforms are not tested.
#### 买入信号(Buy Signal)
-该机器人将持续监测一段时间内的最低值。一旦当前价格达到最低价格,那么机器人将下达买入的 "止损限价单(STOP-LOSS-LIMIT)"指令。如果当前价格持续下跌。那么机器人将取消之前的订单,并重新放置新的"止损限价单(STOP-LOSS-LIMIT)"订单。
+The bot will continuously monitor the coin based on the grid trade configuration.
-- 当达到卖出的触发价格时,如果有足够的持仓(通常超过10美元),机器人就不会再下买单。
+For grid trade #1, the bot will place a STOP-LOSS-LIMIT order to buy when the current price reaches the lowest price. If the current price continuously falls, then the bot will cancel the previous order and re-place the new STOP-LOSS-LIMIT order with the new price.
+
+After grid trade #1, the bot will monitor the COIN based on the last buy price.
+
+- The bot will not place a buy order of the grid trade #1 if has enough coin (typically over $10 worth) to sell when reaches the trigger price for selling.
+- The bot will remove the last buy price if the estimated value is less than the last buy price removal threshold.
##### 买入方案
-比方说,使用如下买入配置设置:
+Let say, if the buy grid trade configurations are set as below:
+
+- Number of grids: 2
+- Grids
+ | No# | Trigger Percentage | Stop Price Percentage | Limit price percentage | USDT |
+ | --- | ------------------- | --------------------- | ---------------------- | ---- |
+ | 1 | 1 | 1.05 | 1.051 | 50 |
+ | 2 | 0.8 | 1.03 | 1.031 | 100 |
+
+To make it easier to understand, I will use `$` as a USDT symbol. For the simple calculation, I do not take an account for the commission. In real trading, the quantity may be different.
+
+Your 1st grid trading for buying is configured as below:
+
+- Grid No#: 1
+- Trigger percentage: 1
+- Stop percentage: 1.05 (5.00%)
+- Limit percentage: 1.051 (5.10%)
+- Max purchase amount: $50
+
+And the market is as below:
-- 最大购买金额(Maximum purchase amount): $50
-- 触发百分比(Trigger percentage): 1.005 (0.5%)
-- 止损百分比(Stop price percentage): 1.01 (1.0%)
-- 限价百分比(Limit price percentage): 1.011 (1.1%)
+- Current price: $105
+- Lowest price: $100
+- Trigger price: $100
-市场情况如下:
+When the current price is falling to the lowest price ($100) and lower than ATH(All-Time High) restricted price if enabled, the bot will place new STOP-LOSS-LIMIT order for buying.
-- 市场价: $101
-- 限价: $100
-- 触发价: $100.5
+- Stop price: $100 * 1.05 = $105
+- Limit price: $100 * 1.051 = $105.1
+- Quantity: 0.47573
-现在机器人不会下单,因为触发价(100.5)低于现价(101)
+Let's assume the market changes as below:
-在下一次市场成交后(next tick),市场情况现在如下:
+- Current price: $95
-- 市场价: $100
-- 限价: $100
-- 触发价: $100.5
+Then the bot will follow the price fall and place new STOP-LOSS-LIMIT order as below:
-现在,机器人会新建一个限价止损单来买入,因为现价(\$100)已经低于了触发价(\$100.5)。为了简化计算,这里没有考虑佣金。在真实的交易中,数量会有不同。新的买入订单会被执行如下:
+- Stop price: $95 * 1.05 = $99.75
+- Limit price: $95 * 1.051 = $99.845
+- Quantity: 0.5
-- 止损价 Stop price: \$100 \* 1.01 = $101
-- 限价 Limit price: \$100 \* 1.011 = $101.1
-- 数量: 0.49
+Let's assume the market changes as below:
-在下一次市场成交后(next tick),市场情况现在如下:
+- Current price: $100
-- 现价: $99
-- 当前限价 Current limit price: $99 \* 1.011 = 100.089
-- 未平仓止损价 Open order stop price: $101
+Then the bot will execute 1st purchase for the coin. The last buy price will be recorded as `$99.845`. The purchased quantity will be `0.5`.
-由于当前的未平仓止损价 101 高于当前限价 100.089,机器人会取消当前的订单并按以下方式重新下单
+Once the coin is purchased, the bot will start monitoring the sell signal and at the same time, monitor the next grid trading for buying.
-- 止损价 Stop price: \$99 \* 1.01 = $99.99
-- 限价 Limit price: \$99 \* 1.011 = $100.089
-- 数量 Quantity: 0.49
+Your 2nd grid trading for buying is configured as below:
-如果价格不断下跌,这个新的买单也会不断更新报价。
+- Grid#: 2
+- Current last buy price: $99.845
+- Trigger percentage: 0.8 (20%)
+- Stop percentage: 1.03 (3.00%)
+- Limit percentage: 1.031 (3.10%)
+- Max purchase amount: $100
-接下来在一次市场成交后(next tick),市场情况如下:
+And if the current price is continuously falling to `$79.876` (20% lower), then the bot will place new STOP-LOSS-LIMIT order for the 2nd grid trading for the coin.
-- 现价 Current price: $100
+Let's assume the market changes as below:
-现在当前价格到了止损价(99.99),因此,买单将会按限价 100.089 报价下单。
+- Current price: $75
+
+Then the bot will follow the price fall and place new STOP-LOSS-LIMT order as below:
+
+- Stop price: $75 * 1.03 = $77.25
+- Limit price: $75 * 1.031 = $77.325
+- Quantity: 1.29
+
+Let's assume the market changes as below:
+
+- Current price: $78
+
+Then the bot will execute 2nd purchase for the coin. The last buy price will be automatically re-calculated as below:
+
+- Final last buy price: ($50 + $100)/(0.5 COIN + 1.29 COIN) = $83.80
### 卖出信号
-如果有足够的余额用于卖出,并且最后的买入价格已被记录,那么机器人将开始监测卖出信号。一旦当前价格达到触发价格,机器人将下达一个止损限价单来卖出。如果当前价格持续上涨,那么机器人将取消之前的订单,并重新以新的价格重新下新的止损限价单。
+If there is enough balance for selling and the last buy price is recorded in the bot, then the bot will start monitoring the sell signal of the grid trade #1. Once the current price reaches the trigger price of the grid trade #1, then the bot will place a STOP-LOSS-LIMIT order to sell. If the current price continuously rises, then the bot will cancel the previous order and re-place the new STOP-LOSS-LIMIT order with the new price.
-- 如果该币的价值低于10美元(最低名义价值),那么机器人将删除最后的买入价格,因为Binance不允许下低于10美元的订单。
-- 如果机器人没有最后买入价格的记录,机器人将不会卖出该币。
+- If the bot does not have a record for the last buy price, the bot will not sell the coin.
+- If the coin is worth less than the last buy price removal threshold, then the bot will remove the last buy price.
+- If the coin is not worth than the minimum notional value, then the bot will not place an order.
#### 卖出方案
-比方说,使用如下卖出配置设置:
+Let say, if the sell grid trade configurations are set as below:
+
+- Number of grids: 2
+- Grids
+ | No# | Trigger Percentage | Stop Price Percentage | Limit price percentage | Sell Quantity Percentage |
+ | --- | ------------------- | --------------------- | ---------------------- |------------------------- |
+ | 1st | 1.05 | 0.97 | 0.969 | 0.5 |
+ | 2nd | 1.08 | 0.95 | 0.949 | 1 |
+
+Unlike buy, the sell configuration will use the percentage of a quantity. If you want to sell all of your coin quantity, then simply configure it as `1` (100%).
+
+From the last buy actions, you now have the following balances:
+
+- Current quantity: 1.79
+- Current last buy price: $83.80
+
+Your 1st grid trading for selling is configured as below:
+
+- Grid No# 1
+- Trigger percentage: 1.05
+- Stop price percentage: 0.97
+- Limit price percentage: 0.969
+- Sell amount percentage: 0.5
+
+Let's assume the market changes as below:
+
+- Current price: $88
+
+As the current price is higher than the sell trigger price($87.99), then the bot will place new STOP-LOSS-LIMIT order for selling.
+
+- Stop price: $88 * 0.97 = $85.36
+- Limit price: $88 * 0.969 = $85.272
+- Quantity: 0.895
+
+Let's assume the market changes as below:
+
+- Current price: $90
+
+Then the bot will follow the price rise and place new STOP-LOSS-LIMIT order as below:
+
+- Stop price: $90 * 0.97 = $87.30
+- Limit price: $90 * 0.969 = $87.21
+- Quantity: 0.895
-- 触发百分比 Trigger percentage: 1.05 (5.0%)
-- 止损百分比 Stop price percentage: 0.98 (-2.0%)
-- 限价百分比 Limit price percentage: 0.979 (-2.1%)
+Let's assume the market changes as below:
-同时市场行情如下:
+- Current price: $87
-- 剩余代币数量 Coin owned: 0.5
-- 市场价 Current price: $100
-- Last buy price: $100
-- 触发价 Trigger price: \$100 \* 1.05 = $105
+Then the bot will execute 1st sell for the coin. Then the bot will now wait for 2nd selling trigger price ($83.80 * 1.08 = $90.504).
-这时机器人将不会提交订单,因为触发价(\$105)低于市场价(\$100)
+- Current quantity: 0.895
+- Current last buy price: $83.80
-如果价格持续走低,机器会持续监控价格,直到价格达到触发价
+Let's assume the market changes as below:
-接下来在一次市场成交后(next tick),市场行情如下:
+- Current price: $91
-- 市场价 Current price: $105
-- 触发价 Trigger price: $105
+Then the current price($91) is higher than 2nd selling trigger price ($90.504), the bot will place new STOP-LOSS-LIMIT order as below:
-机器人将提交新的止损限价单进行卖出,因为当前的价格(\$105)高于或等于触发价格(\$105)。
-为了简化计算,我没有考虑佣金。在实际交易中,数量可能会有所不同。新的卖单将被提交如下:
+- Stop price: $91 * 0.95 = $86.45
+- Limit price: $91 * 0.949 = $86.359
+- Quantity: 0.895
-- 止损价 Stop price: \$105 \* 0.98 = $102.9
-- 限价 Limit price: \$105 \* 0.979 = $102.795
-- 数量 Quantity: 0.5
+Let's assume the market changes as below:
-接下来在一次市场成交后(next tick),市场情况如下:
+- Current price: $100
-- 市场价 Current price: $106
-- 当前限价 Current limit price: $103.774
-- 开仓止损价 Open order stop price: $102.29
+Then the bot will follow the price rise and place new STOP-LOSS-LIMT order as below:
-由于未平仓订单的止损价格(\$102.29)低于当前的限价(\$103.774),机器人将取消未平仓订单,并提交新的止损限价单,如下所示:
+- Stop price: $100 * 0.95 = $95
+- Limit price: $100 * 0.949 = $94.9
+- Quantity: 0.895
-- 止损价 Stop price: \$106 \* 0.98 = $103.88
-- 限价 Limit price: \$106 \* 0.979 = $103.774
-- 数量 Quantity: 0.5
+Let's assume the market changes as below:
-如果市场价不断升高,新的卖单也会更新报价。
+- Current price: $94
-如果市场价格变化:
+Then the bot will execute 2nd sell for the coin.
-- 市场价 Current price: $103
+The final profit would be
-目前的价格达到了止损价(\$103.88);因此,订单将以限价($103.774)执行。
+- 1st sell: $94.9 * 0.895 = $84.9355
+- 2nd sell: $87.21 * 0.895 = $78.05295
+- Final profit: $162 (8% profit)
### [功能](https://github.com/chrisleekr/binance-trading-bot/wiki/Features)
@@ -246,11 +321,11 @@
| 前端 移动端 | 设置 | 手工交易 |
| --------- | ---- | ------ |
-| ![Frontend Mobile](https://user-images.githubusercontent.com/5715919/124752399-262e5f00-df6b-11eb-9dc1-e8f06b98aa9a.png) | ![Setting](https://user-images.githubusercontent.com/5715919/124752414-2890b900-df6b-11eb-90f4-7fa79a84bf1d.png) | ![Manual Trade](https://user-images.githubusercontent.com/5715919/124752425-2c244000-df6b-11eb-97d9-d81e494d7e40.png) |
+| ![Frontend Mobile](https://user-images.githubusercontent.com/5715919/127318555-31216c7e-f27c-4e05-a3b1-1ebda386e439.png) | ![Setting](https://user-images.githubusercontent.com/5715919/127318581-4e422ac9-b145-4e83-a90d-5c05c61d6e2f.png) | ![Manual Trade](https://user-images.githubusercontent.com/5715919/127318630-f2180e1b-3feb-48fa-a083-4cb7f90f743f.png) |
| Frontend Desktop |
| ------------------------------------------------------------------------------------------------------------------------- |
-| ![Frontend Desktop](https://user-images.githubusercontent.com/5715919/124752605-668ddd00-df6b-11eb-887b-8cf79048d798.png) |
+| ![Frontend Desktop](https://user-images.githubusercontent.com/5715919/127318831-1cbfab93-6300-4251-b757-7d51eb5fbc2d.png) |
### Sample Trade
diff --git a/app/cronjob/__tests__/trailingTrade.test.js b/app/cronjob/__tests__/trailingTrade.test.js
index 6dad674f..8b19f84f 100644
--- a/app/cronjob/__tests__/trailingTrade.test.js
+++ b/app/cronjob/__tests__/trailingTrade.test.js
@@ -19,21 +19,22 @@ describe('trailingTrade', () => {
let mockGetSymbolConfiguration;
let mockGetSymbolInfo;
+ let mockGetBalances;
let mockGetOverrideAction;
let mockEnsureManualBuyOrder;
let mockEnsureOrderPlaced;
- let mockGetBalances;
+ let mockEnsureGridTradeOrderExecuted;
let mockGetOpenOrders;
let mockGetIndicators;
let mockHandleOpenOrders;
let mockDetermineAction;
let mockPlaceManualTrade;
- let mockCancelOrder;
let mockPlaceBuyOrder;
let mockPlaceSellOrder;
let mockPlaceSellStopLossOrder;
let mockRemoveLastBuyPrice;
let mockSaveDataToCache;
+ let mockCancelOrder;
beforeEach(() => {
jest.clearAllMocks().resetModules();
@@ -136,6 +137,15 @@ describe('trailingTrade', () => {
ensure: 'order-placed'
}));
+ mockEnsureGridTradeOrderExecuted = jest
+ .fn()
+ .mockImplementation((_logger, rawData) => ({
+ ...rawData,
+ ensureGridTradeOrder: {
+ ensured: 'grid-trade'
+ }
+ }));
+
mockGetBalances = jest.fn().mockImplementation((_logger, rawData) => ({
...rawData,
...{
@@ -276,6 +286,7 @@ describe('trailingTrade', () => {
getOverrideAction: mockGetOverrideAction,
ensureManualBuyOrder: mockEnsureManualBuyOrder,
ensureOrderPlaced: mockEnsureOrderPlaced,
+ ensureGridTradeOrderExecuted: mockEnsureGridTradeOrderExecuted,
getBalances: mockGetBalances,
getOpenOrders: mockGetOpenOrders,
getIndicators: mockGetIndicators,
@@ -317,24 +328,27 @@ describe('trailingTrade', () => {
symbol: 'BTCUSDT',
isLocked: false,
featureToggle: { feature1Enabled: true },
- lastCandle: { got: 'lowest value' },
accountInfo: { account: 'info' },
symbolConfiguration: { symbol: 'configuration data' },
- indicators: { some: 'value' },
symbolInfo: { symbol: 'info' },
- openOrders: [{ orderId: 'order-id-BTCUSDT', symbol: 'BTCUSDT' }],
- action: 'determined',
+ overrideAction: { action: 'override-action' },
+ ensureManualBuyOrder: { ensured: 'manual-buy-order' },
+ ensure: 'order-placed',
+ ensureGridTradeOrder: {
+ ensured: 'grid-trade'
+ },
baseAssetBalance: { baseAsset: 'balance' },
quoteAssetBalance: { quoteAsset: 'balance' },
+ lastCandle: { got: 'lowest value' },
+ indicators: { some: 'value' },
buy: { should: 'buy?', actioned: 'yes' },
sell: { should: 'sell?', actioned: 'yes' },
- order: {},
- saveToCache: true,
- overrideAction: { action: 'override-action' },
- ensureManualBuyOrder: { ensured: 'manual-buy-order' },
- ensure: 'order-placed',
+ openOrders: [{ orderId: 'order-id-BTCUSDT', symbol: 'BTCUSDT' }],
handled: 'open-orders',
+ action: 'determined',
placeManualTrade: { placed: 'manual-trade' },
+ order: {},
+ saveToCache: true,
cancelOrder: { cancelled: 'existing-order' },
stopLoss: 'processed',
removed: 'last-buy-price',
@@ -353,24 +367,27 @@ describe('trailingTrade', () => {
symbol: 'ETHUSDT',
isLocked: false,
featureToggle: { feature1Enabled: true },
- lastCandle: { got: 'lowest value' },
accountInfo: { account: 'info' },
symbolConfiguration: { symbol: 'configuration data' },
- indicators: { some: 'value' },
symbolInfo: { symbol: 'info' },
- openOrders: [{ orderId: 'order-id-ETHUSDT', symbol: 'ETHUSDT' }],
- action: 'determined',
+ overrideAction: { action: 'override-action' },
+ ensureManualBuyOrder: { ensured: 'manual-buy-order' },
+ ensure: 'order-placed',
+ ensureGridTradeOrder: {
+ ensured: 'grid-trade'
+ },
baseAssetBalance: { baseAsset: 'balance' },
quoteAssetBalance: { quoteAsset: 'balance' },
+ lastCandle: { got: 'lowest value' },
+ indicators: { some: 'value' },
buy: { should: 'buy?', actioned: 'yes' },
sell: { should: 'sell?', actioned: 'yes' },
- order: {},
- saveToCache: true,
- overrideAction: { action: 'override-action' },
- ensureManualBuyOrder: { ensured: 'manual-buy-order' },
- ensure: 'order-placed',
+ openOrders: [{ orderId: 'order-id-ETHUSDT', symbol: 'ETHUSDT' }],
handled: 'open-orders',
+ action: 'determined',
placeManualTrade: { placed: 'manual-trade' },
+ order: {},
+ saveToCache: true,
cancelOrder: { cancelled: 'existing-order' },
stopLoss: 'processed',
removed: 'last-buy-price',
@@ -389,24 +406,27 @@ describe('trailingTrade', () => {
symbol: 'LTCUSDT',
isLocked: false,
featureToggle: { feature1Enabled: true },
- lastCandle: { got: 'lowest value' },
accountInfo: { account: 'info' },
symbolConfiguration: { symbol: 'configuration data' },
- indicators: { some: 'value' },
symbolInfo: { symbol: 'info' },
- openOrders: [{ orderId: 'order-id-LTCUSDT', symbol: 'LTCUSDT' }],
- action: 'determined',
+ overrideAction: { action: 'override-action' },
+ ensureManualBuyOrder: { ensured: 'manual-buy-order' },
+ ensure: 'order-placed',
+ ensureGridTradeOrder: {
+ ensured: 'grid-trade'
+ },
baseAssetBalance: { baseAsset: 'balance' },
quoteAssetBalance: { quoteAsset: 'balance' },
+ lastCandle: { got: 'lowest value' },
+ indicators: { some: 'value' },
buy: { should: 'buy?', actioned: 'yes' },
sell: { should: 'sell?', actioned: 'yes' },
- order: {},
- saveToCache: true,
- overrideAction: { action: 'override-action' },
- ensureManualBuyOrder: { ensured: 'manual-buy-order' },
- ensure: 'order-placed',
+ openOrders: [{ orderId: 'order-id-LTCUSDT', symbol: 'LTCUSDT' }],
handled: 'open-orders',
+ action: 'determined',
placeManualTrade: { placed: 'manual-trade' },
+ order: {},
+ saveToCache: true,
cancelOrder: { cancelled: 'existing-order' },
stopLoss: 'processed',
removed: 'last-buy-price',
@@ -498,6 +518,15 @@ describe('trailingTrade', () => {
ensure: 'order-placed'
}));
+ mockEnsureGridTradeOrderExecuted = jest
+ .fn()
+ .mockImplementation((_logger, rawData) => ({
+ ...rawData,
+ ensureGridTradeOrder: {
+ ensured: 'grid-trade'
+ }
+ }));
+
mockGetBalances = jest.fn().mockImplementation((_logger, rawData) => ({
...rawData,
...{
@@ -638,6 +667,7 @@ describe('trailingTrade', () => {
getOverrideAction: mockGetOverrideAction,
ensureManualBuyOrder: mockEnsureManualBuyOrder,
ensureOrderPlaced: mockEnsureOrderPlaced,
+ ensureGridTradeOrderExecuted: mockEnsureGridTradeOrderExecuted,
getBalances: mockGetBalances,
getOpenOrders: mockGetOpenOrders,
getIndicators: mockGetIndicators,
@@ -678,31 +708,30 @@ describe('trailingTrade', () => {
data: {
symbol: 'BTCUSDT',
isLocked: true,
- featureToggle: {
- feature1Enabled: false
- },
- lastCandle: { got: 'lowest value' },
+ featureToggle: { feature1Enabled: false },
accountInfo: { account: 'info' },
symbolConfiguration: { symbol: 'configuration data' },
- indicators: { some: 'value' },
symbolInfo: { symbol: 'info' },
- openOrders: [{ orderId: 'order-id-BTCUSDT', symbol: 'BTCUSDT' }],
- action: 'determined',
+ overrideAction: { action: 'override-action' },
+ ensureManualBuyOrder: { ensured: 'manual-buy-order' },
+ ensure: 'order-placed',
+ ensureGridTradeOrder: { ensured: 'grid-trade' },
baseAssetBalance: { baseAsset: 'balance' },
quoteAssetBalance: { quoteAsset: 'balance' },
+ openOrders: [{ orderId: 'order-id-BTCUSDT', symbol: 'BTCUSDT' }],
+ lastCandle: { got: 'lowest value' },
+ indicators: { some: 'value' },
buy: { should: 'buy?', actioned: 'yes' },
sell: { should: 'sell?', actioned: 'yes' },
- order: {},
- saveToCache: true,
- overrideAction: { action: 'override-action' },
- ensureManualBuyOrder: { ensured: 'manual-buy-order' },
- ensure: 'order-placed',
handled: 'open-orders',
+ action: 'determined',
placeManualTrade: { placed: 'manual-trade' },
cancelOrder: { cancelled: 'existing-order' },
stopLoss: 'processed',
removed: 'last-buy-price',
- saved: 'data-to-cache'
+ saved: 'data-to-cache',
+ order: {},
+ saveToCache: true
}
},
'TrailingTrade: Finish process...'
@@ -716,31 +745,30 @@ describe('trailingTrade', () => {
data: {
symbol: 'ETHUSDT',
isLocked: true,
- featureToggle: {
- feature1Enabled: false
- },
- lastCandle: { got: 'lowest value' },
+ featureToggle: { feature1Enabled: false },
accountInfo: { account: 'info' },
symbolConfiguration: { symbol: 'configuration data' },
- indicators: { some: 'value' },
symbolInfo: { symbol: 'info' },
- openOrders: [{ orderId: 'order-id-ETHUSDT', symbol: 'ETHUSDT' }],
- action: 'determined',
+ overrideAction: { action: 'override-action' },
+ ensureManualBuyOrder: { ensured: 'manual-buy-order' },
+ ensure: 'order-placed',
+ ensureGridTradeOrder: { ensured: 'grid-trade' },
baseAssetBalance: { baseAsset: 'balance' },
quoteAssetBalance: { quoteAsset: 'balance' },
+ openOrders: [{ orderId: 'order-id-ETHUSDT', symbol: 'ETHUSDT' }],
+ lastCandle: { got: 'lowest value' },
+ indicators: { some: 'value' },
buy: { should: 'buy?', actioned: 'yes' },
sell: { should: 'sell?', actioned: 'yes' },
- order: {},
- saveToCache: true,
- overrideAction: { action: 'override-action' },
- ensureManualBuyOrder: { ensured: 'manual-buy-order' },
- ensure: 'order-placed',
handled: 'open-orders',
+ action: 'determined',
placeManualTrade: { placed: 'manual-trade' },
cancelOrder: { cancelled: 'existing-order' },
stopLoss: 'processed',
removed: 'last-buy-price',
- saved: 'data-to-cache'
+ saved: 'data-to-cache',
+ order: {},
+ saveToCache: true
}
},
'TrailingTrade: Finish process...'
@@ -754,31 +782,30 @@ describe('trailingTrade', () => {
data: {
symbol: 'LTCUSDT',
isLocked: true,
- featureToggle: {
- feature1Enabled: false
- },
- lastCandle: { got: 'lowest value' },
+ featureToggle: { feature1Enabled: false },
accountInfo: { account: 'info' },
symbolConfiguration: { symbol: 'configuration data' },
- indicators: { some: 'value' },
symbolInfo: { symbol: 'info' },
- openOrders: [{ orderId: 'order-id-LTCUSDT', symbol: 'LTCUSDT' }],
- action: 'determined',
+ overrideAction: { action: 'override-action' },
+ ensureManualBuyOrder: { ensured: 'manual-buy-order' },
+ ensure: 'order-placed',
+ ensureGridTradeOrder: { ensured: 'grid-trade' },
baseAssetBalance: { baseAsset: 'balance' },
quoteAssetBalance: { quoteAsset: 'balance' },
+ openOrders: [{ orderId: 'order-id-LTCUSDT', symbol: 'LTCUSDT' }],
+ lastCandle: { got: 'lowest value' },
+ indicators: { some: 'value' },
buy: { should: 'buy?', actioned: 'yes' },
sell: { should: 'sell?', actioned: 'yes' },
- order: {},
- saveToCache: true,
- overrideAction: { action: 'override-action' },
- ensureManualBuyOrder: { ensured: 'manual-buy-order' },
- ensure: 'order-placed',
handled: 'open-orders',
+ action: 'determined',
placeManualTrade: { placed: 'manual-trade' },
cancelOrder: { cancelled: 'existing-order' },
stopLoss: 'processed',
removed: 'last-buy-price',
- saved: 'data-to-cache'
+ saved: 'data-to-cache',
+ order: {},
+ saveToCache: true
}
},
'TrailingTrade: Finish process...'
diff --git a/app/cronjob/trailingTrade.js b/app/cronjob/trailingTrade.js
index f528c70a..42869389 100644
--- a/app/cronjob/trailingTrade.js
+++ b/app/cronjob/trailingTrade.js
@@ -16,21 +16,22 @@ const {
const {
getSymbolConfiguration,
getSymbolInfo,
- getBalances,
getOverrideAction,
ensureManualBuyOrder,
ensureOrderPlaced,
+ ensureGridTradeOrderExecuted,
+ getBalances,
getOpenOrders,
getIndicators,
handleOpenOrders,
determineAction,
placeManualTrade,
+ cancelOrder,
placeBuyOrder,
placeSellOrder,
placeSellStopLossOrder,
removeLastBuyPrice,
- saveDataToCache,
- cancelOrder
+ saveDataToCache
} = require('./trailingTrade/steps');
const { slack } = require('../helpers');
@@ -104,6 +105,10 @@ const execute = async logger => {
stepName: 'ensure-open-placed',
stepFunc: ensureOrderPlaced
},
+ {
+ stepName: 'ensure-grid-trade-order-executed',
+ stepFunc: ensureGridTradeOrderExecuted
+ },
{
stepName: 'get-balances',
stepFunc: getBalances
diff --git a/app/cronjob/trailingTrade/__tests__/steps.test.js b/app/cronjob/trailingTrade/__tests__/steps.test.js
index 26719d32..50e154f2 100644
--- a/app/cronjob/trailingTrade/__tests__/steps.test.js
+++ b/app/cronjob/trailingTrade/__tests__/steps.test.js
@@ -9,6 +9,7 @@ describe('steps.js', () => {
getOverrideAction: expect.any(Function),
ensureManualBuyOrder: expect.any(Function),
ensureOrderPlaced: expect.any(Function),
+ ensureGridTradeOrderExecuted: expect.any(Function),
getOpenOrders: expect.any(Function),
getIndicators: expect.any(Function),
handleOpenOrders: expect.any(Function),
diff --git a/app/cronjob/trailingTrade/step/__tests__/determine-action.test.js b/app/cronjob/trailingTrade/step/__tests__/determine-action.test.js
index f07031b2..34044a07 100644
--- a/app/cronjob/trailingTrade/step/__tests__/determine-action.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/determine-action.test.js
@@ -9,31 +9,58 @@ describe('determine-action.js', () => {
describe('execute', () => {
describe('when symbol is locked', () => {
beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: true,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.4500000' },
+ baseAssetBalance: {
+ total: 0.000312
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 172.375,
- athRestrictionPrice: 180.0
+ currentPrice: 31786.08,
+ triggerPrice: 28924.92,
+ athRestrictionPrice: 29572.2
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: null,
- triggerPrice: null
+ currentPrice: 31786.08,
+ triggerPrice: 33102.964,
+ lastBuyPrice: 32138.799999999996,
+ stopLossTriggerPrice: 25711.039999999997
}
};
@@ -47,31 +74,58 @@ describe('determine-action.js', () => {
describe('when action is buy-order-wait', () => {
beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+
rawData = {
action: 'buy-order-wait',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.4500000' },
+ baseAssetBalance: {
+ total: 0.000312
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 172.375,
- athRestrictionPrice: 180.0
+ currentPrice: 31786.08,
+ triggerPrice: 28924.92,
+ athRestrictionPrice: 29572.2
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: null,
- triggerPrice: null
+ currentPrice: 31786.08,
+ triggerPrice: 33102.964,
+ lastBuyPrice: 32138.799999999996,
+ stopLossTriggerPrice: 25711.039999999997
}
};
@@ -85,31 +139,58 @@ describe('determine-action.js', () => {
describe('when action is buy', () => {
beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+
rawData = {
action: 'buy',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.4500000' },
+ baseAssetBalance: {
+ total: 0.000312
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 172.375,
- athRestrictionPrice: 180.0
+ currentPrice: 31786.08,
+ triggerPrice: 28924.92,
+ athRestrictionPrice: 29572.2
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: null,
- triggerPrice: null
+ currentPrice: 31786.08,
+ triggerPrice: 33102.964,
+ lastBuyPrice: 32138.799999999996,
+ stopLossTriggerPrice: 25711.039999999997
}
};
@@ -125,6 +206,8 @@ describe('determine-action.js', () => {
describe('when last buy price is not configured and current price is less or equal than trigger price', () => {
describe('when base asset balance has enough to sell', () => {
beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+
cache.getWithTTL = jest.fn().mockResolvedValue([
[null, -2],
[null, null]
@@ -132,6 +215,7 @@ describe('determine-action.js', () => {
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
baseAsset: 'BTC',
@@ -139,23 +223,49 @@ describe('determine-action.js', () => {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0005
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 29572.2
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 28000,
+ triggerPrice: null,
lastBuyPrice: null,
- triggerPrice: null
+ stopLossTriggerPrice: null
}
};
@@ -165,6 +275,7 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'wait',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
baseAsset: 'BTC',
@@ -172,29 +283,190 @@ describe('determine-action.js', () => {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0005
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0,
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 29572.2,
processMessage:
- `The current price reached the trigger price. ` +
- `But you have enough BTC to sell. ` +
- `Set the last buy price to start selling. ` +
- `Do not process buy.`,
+ `The current price reached the trigger price. But you have enough BTC to sell. ` +
+ `Set the last buy price to start selling. Do not process buy.`,
updatedAt: expect.any(Object)
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 28000,
+ triggerPrice: null,
lastBuyPrice: null,
- triggerPrice: null
+ stopLossTriggerPrice: null
+ }
+ });
+ });
+ });
+
+ describe('when grid trade buy order is found', () => {
+ beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(key => {
+ if (key === `BTCUSDT-grid-trade-last-buy-order`) {
+ return JSON.stringify({
+ orderId: 27123456
+ });
+ }
+
+ return null;
+ });
+
+ cache.getWithTTL = jest.fn().mockResolvedValue([
+ [null, -2],
+ [null, null]
+ ]);
+
+ rawData = {
+ action: 'not-determined',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 29572.2
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
+ }
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({
+ action: 'buy-order-wait',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 29572.2,
+ processMessage: `There is a last gird trade buy order. Wait.`,
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
}
});
});
@@ -202,6 +474,7 @@ describe('determine-action.js', () => {
describe('when the symbol is disabled', () => {
beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(_key => null);
cache.getWithTTL = jest.fn().mockResolvedValue([
[null, 300],
[
@@ -217,29 +490,57 @@ describe('determine-action.js', () => {
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '0.0500000' },
+ baseAssetBalance: {
+ total: 0.0003
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 29572.2
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 28000,
+ triggerPrice: null,
lastBuyPrice: null,
- triggerPrice: null
+ stopLossTriggerPrice: null
}
};
@@ -249,24 +550,51 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'buy-temporary-disabled',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '0.0500000' },
+ baseAssetBalance: {
+ total: 0.0003
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0,
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 29572.2,
processMessage:
`The current price reached the trigger price. ` +
`However, the action is temporarily disabled by buy order. ` +
@@ -274,155 +602,532 @@ describe('determine-action.js', () => {
updatedAt: expect.any(Object)
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 28000,
+ triggerPrice: null,
lastBuyPrice: null,
- triggerPrice: null
+ stopLossTriggerPrice: null
}
});
});
});
describe('when the trigger price is higher than the ATH restriction price', () => {
+ beforeEach(() => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+ });
+
describe('when the ATH restriction is enabled', () => {
- beforeEach(async () => {
- cache.getWithTTL = jest.fn().mockResolvedValue([
- [null, -2],
- [null, null]
- ]);
+ describe('currentGridTradeIndex is 0', () => {
+ beforeEach(async () => {
+ cache.getWithTTL = jest.fn().mockResolvedValue([
+ [null, -2],
+ [null, null]
+ ]);
- rawData = {
- action: 'not-determined',
- isLocked: false,
- symbolInfo: {
- filterMinNotional: {
- minNotional: '10.00000000'
- }
- },
- baseAssetBalance: { total: '0.0500000' },
- symbolConfiguration: {
- buy: {
- athRestriction: {
- enabled: true
+ rawData = {
+ action: 'not-determined',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
}
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
}
- },
- buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0
- },
- sell: {
- currentPrice: 184.099,
- lastBuyPrice: null,
- triggerPrice: null
- }
- };
+ };
- result = await step.execute(logger, rawData);
- });
+ result = await step.execute(logger, rawData);
+ });
- it('returns expected result', () => {
- expect(result).toStrictEqual({
- action: 'wait',
- isLocked: false,
- symbolInfo: {
- filterMinNotional: {
- minNotional: '10.00000000'
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({
+ action: 'wait',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000,
+ processMessage:
+ 'The current price has reached the lowest price; however, it is restricted to buy the coin.',
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
}
- },
- baseAssetBalance: { total: '0.0500000' },
- symbolConfiguration: {
+ });
+ });
+ });
+
+ describe('currentGridTradeIndex is 1', () => {
+ beforeEach(async () => {
+ cache.getWithTTL = jest.fn().mockResolvedValue([
+ [null, -2],
+ [null, null]
+ ]);
+
+ rawData = {
+ action: 'not-determined',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- athRestriction: {
- enabled: true
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
+ }
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({
+ action: 'buy',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
}
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000,
+ processMessage:
+ "The current price reached the trigger price for the grid trade #2. Let's buy it.",
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
}
- },
- buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0,
- processMessage:
- 'The current price has reached the lowest price; however, it is restricted to buy the coin.',
- updatedAt: expect.any(Object)
- },
- sell: {
- currentPrice: 184.099,
- lastBuyPrice: null,
- triggerPrice: null
- }
+ });
});
});
});
describe('when the ATH restriction is disabled', () => {
- beforeEach(async () => {
- cache.getWithTTL = jest.fn().mockResolvedValue([
- [null, -2],
- [null, null]
- ]);
+ describe('currentGridTradeIndex is 0', () => {
+ beforeEach(async () => {
+ cache.getWithTTL = jest.fn().mockResolvedValue([
+ [null, -2],
+ [null, null]
+ ]);
- rawData = {
- action: 'not-determined',
- isLocked: false,
- symbolInfo: {
- filterMinNotional: {
- minNotional: '10.00000000'
- }
- },
- baseAssetBalance: { total: '0.0500000' },
- symbolConfiguration: {
- buy: {
- athRestriction: {
- enabled: false
+ rawData = {
+ action: 'not-determined',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
}
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
}
- },
- buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0
- },
- sell: {
- currentPrice: 184.099,
- lastBuyPrice: null,
- triggerPrice: null
- }
- };
+ };
- result = await step.execute(logger, rawData);
- });
+ result = await step.execute(logger, rawData);
+ });
- it('returns expected result', () => {
- expect(result).toStrictEqual({
- action: 'buy',
- isLocked: false,
- symbolInfo: {
- filterMinNotional: {
- minNotional: '10.00000000'
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({
+ action: 'buy',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000,
+ processMessage:
+ "The current price reached the trigger price for the grid trade #1. Let's buy it.",
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
}
- },
- baseAssetBalance: { total: '0.0500000' },
- symbolConfiguration: {
+ });
+ });
+ });
+
+ describe('currentGridTradeIndex is 1', () => {
+ beforeEach(async () => {
+ cache.getWithTTL = jest.fn().mockResolvedValue([
+ [null, -2],
+ [null, null]
+ ]);
+
+ rawData = {
+ action: 'not-determined',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: false
+ },
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- athRestriction: {
- enabled: false
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
+ }
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({
+ action: 'buy',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0003
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: false
+ },
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
}
+ },
+ buy: {
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000,
+ processMessage:
+ "The current price reached the trigger price for the grid trade #2. Let's buy it.",
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 28000,
+ triggerPrice: null,
+ lastBuyPrice: null,
+ stopLossTriggerPrice: null
}
- },
- buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 180.0,
- processMessage:
- "The current price reached the trigger price. Let's buy it.",
- updatedAt: expect.any(Object)
- },
- sell: {
- currentPrice: 184.099,
- lastBuyPrice: null,
- triggerPrice: null
- }
+ });
});
});
});
@@ -430,6 +1135,8 @@ describe('determine-action.js', () => {
describe('when base asset balance does not have enough to sell', () => {
beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+
cache.getWithTTL = jest.fn().mockResolvedValue([
[null, -2],
[null, null]
@@ -437,29 +1144,57 @@ describe('determine-action.js', () => {
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '0.0500000' },
+ baseAssetBalance: {
+ total: 0.0003
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 190.0
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 28001
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 28000,
+ triggerPrice: null,
lastBuyPrice: null,
- triggerPrice: null
+ stopLossTriggerPrice: null
}
};
@@ -469,32 +1204,60 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'buy',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '0.0500000' },
+ baseAssetBalance: {
+ total: 0.0003
+ },
symbolConfiguration: {
buy: {
athRestriction: {
enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
}
},
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375,
- athRestrictionPrice: 190.0,
+ currentPrice: 28000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 28001,
processMessage:
- "The current price reached the trigger price. Let's buy it.",
+ "The current price reached the trigger price for the grid trade #1. Let's buy it.",
updatedAt: expect.any(Object)
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 28000,
lastBuyPrice: null,
- triggerPrice: null
+ triggerPrice: null,
+ stopLossTriggerPrice: null
}
});
});
@@ -504,27 +1267,146 @@ describe('determine-action.js', () => {
describe('when last buy price is set and has enough to sell', () => {
describe('when current price is higher than trigger price', () => {
beforeEach(() => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375
+ currentPrice: 31000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: 175.0,
- triggerPrice: 183.75
+ currentPrice: 31000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 24000
}
};
});
+ describe('when grid trade sell order is found', () => {
+ beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(key => {
+ if (key === `BTCUSDT-grid-trade-last-sell-order`) {
+ return JSON.stringify({
+ orderId: 27123456
+ });
+ }
+
+ return null;
+ });
+
+ cache.getWithTTL = jest.fn().mockResolvedValue([
+ [null, -2],
+ [null, null]
+ ]);
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({
+ action: 'sell-order-wait',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ symbolInfo: {
+ baseAsset: 'BTC',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
+ buy: {
+ currentPrice: 31000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
+ },
+ sell: {
+ currentPrice: 31000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 24000,
+ processMessage: `There is a last gird trade sell order. Wait.`,
+ updatedAt: expect.any(Object)
+ }
+ });
+ });
+ });
+
describe('when symbol is disabled', () => {
beforeEach(async () => {
cache.getWithTTL = jest.fn().mockResolvedValue([
@@ -546,21 +1428,57 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'sell-temporary-disabled',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375
+ currentPrice: 31000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: 175.0,
- triggerPrice: 183.75,
+ currentPrice: 31000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 24000,
processMessage:
`The current price is reached the sell trigger price. ` +
`However, the action is temporarily disabled by sell order. ` +
@@ -584,21 +1502,57 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'sell',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375
+ currentPrice: 31000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: 175.0,
- triggerPrice: 183.75,
+ currentPrice: 31000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 24000,
processMessage:
"The current price is more than the trigger price. Let's sell.",
updatedAt: expect.any(Object)
@@ -609,31 +1563,65 @@ describe('determine-action.js', () => {
});
describe('when current price is less than stop loss trigger price', () => {
+ beforeEach(() => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+ });
+
describe('when stop loss is disabled', () => {
beforeEach(async () => {
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
- symbolConfiguration: {
- sell: {
- stopLoss: { enabled: false }
- }
- },
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 160.099,
- triggerPrice: 185.375
+ currentPrice: 29000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 160.099,
- lastBuyPrice: 175.0,
- triggerPrice: 170.75,
- stopLossTriggerPrice: 165
+ currentPrice: 29000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 29500
}
};
result = await step.execute(logger, rawData);
@@ -642,28 +1630,60 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'sell-wait',
+ symbol: 'BTCUSDT',
isLocked: false,
- symbolConfiguration: {
- sell: {
- stopLoss: { enabled: false }
- }
- },
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: false
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 160.099,
- triggerPrice: 185.375
+ currentPrice: 29000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 160.099,
- lastBuyPrice: 175.0,
- triggerPrice: 170.75,
- stopLossTriggerPrice: 165,
- processMessage: `The current price is lower than the selling trigger price. Wait.`,
+ currentPrice: 29000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 29500,
+ processMessage:
+ `The current price is lower than the selling trigger price ` +
+ `for the grid trade #1. Wait.`,
updatedAt: expect.any(Object)
}
});
@@ -674,27 +1694,57 @@ describe('determine-action.js', () => {
beforeEach(() => {
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
- symbolConfiguration: {
- sell: {
- stopLoss: { enabled: true }
- }
- },
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 160.099,
- triggerPrice: 185.375
+ currentPrice: 29000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 160.099,
- lastBuyPrice: 175.0,
- triggerPrice: 170.75,
- stopLossTriggerPrice: 165
+ currentPrice: 29000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 29500
}
};
});
@@ -721,27 +1771,57 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'sell-temporary-disabled',
+ symbol: 'BTCUSDT',
isLocked: false,
- symbolConfiguration: {
- sell: {
- stopLoss: { enabled: true }
- }
- },
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 160.099,
- triggerPrice: 185.375
+ currentPrice: 29000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 160.099,
- lastBuyPrice: 175.0,
- triggerPrice: 170.75,
- stopLossTriggerPrice: 165,
+ currentPrice: 29000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 29500,
processMessage:
`The current price is reached the stop-loss price. ` +
`However, the action is temporarily disabled by sell order. ` +
@@ -765,27 +1845,57 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'sell-stop-loss',
+ symbol: 'BTCUSDT',
isLocked: false,
- symbolConfiguration: {
- sell: {
- stopLoss: { enabled: true }
- }
- },
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 160.099,
- triggerPrice: 185.375
+ currentPrice: 29000,
+ triggerPrice: 28000,
+ athRestrictionPrice: 27000
},
sell: {
- currentPrice: 160.099,
- lastBuyPrice: 175.0,
- triggerPrice: 170.75,
- stopLossTriggerPrice: 165,
+ currentPrice: 29000,
+ triggerPrice: 30900,
+ lastBuyPrice: 30000,
+ stopLossTriggerPrice: 29500,
processMessage: `The current price is reached the stop-loss price. Place market sell order.`,
updatedAt: expect.any(Object)
}
@@ -797,28 +1907,61 @@ describe('determine-action.js', () => {
describe('when current price is less than trigger price', () => {
beforeEach(async () => {
+ cache.get = jest.fn().mockImplementation(_key => null);
+
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
- symbolConfiguration: {
- sell: {
- stopLoss: { enabled: false }
- }
- },
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375
+ currentPrice: 27000,
+ triggerPrice: 26000,
+ athRestrictionPrice: 25000
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: 178,
- triggerPrice: 186.9
+ currentPrice: 27000,
+ triggerPrice: 28840,
+ lastBuyPrice: 28000,
+ stopLossTriggerPrice: 22400
}
};
@@ -828,28 +1971,59 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'sell-wait',
+ symbol: 'BTCUSDT',
isLocked: false,
- symbolConfiguration: {
- sell: {
- stopLoss: { enabled: false }
- }
- },
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '1.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 184.099,
- triggerPrice: 185.375
+ currentPrice: 27000,
+ triggerPrice: 26000,
+ athRestrictionPrice: 25000
},
sell: {
- currentPrice: 184.099,
- lastBuyPrice: 178,
- triggerPrice: 186.9,
+ currentPrice: 27000,
+ triggerPrice: 28840,
+ lastBuyPrice: 28000,
+ stopLossTriggerPrice: 22400,
processMessage:
- 'The current price is lower than the selling trigger price. Wait.',
+ 'The current price is lower than the selling trigger price for the grid trade #1. Wait.',
updatedAt: expect.any(Object)
}
});
@@ -861,21 +2035,57 @@ describe('determine-action.js', () => {
beforeEach(async () => {
rawData = {
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '0.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 184.099,
- triggerPrice: 180.375
+ currentPrice: 27000,
+ triggerPrice: 26000,
+ athRestrictionPrice: 25000
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 27000,
+ triggerPrice: null,
lastBuyPrice: null,
- triggerPrice: null
+ stopLossTriggerPrice: null
}
};
@@ -885,21 +2095,57 @@ describe('determine-action.js', () => {
it('returns expected result', () => {
expect(result).toStrictEqual({
action: 'not-determined',
+ symbol: 'BTCUSDT',
isLocked: false,
symbolInfo: {
+ baseAsset: 'BTC',
filterMinNotional: {
minNotional: '10.00000000'
}
},
- baseAssetBalance: { total: '0.0500000' },
+ baseAssetBalance: {
+ total: 0.0006
+ },
+ symbolConfiguration: {
+ buy: {
+ athRestriction: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ stopLoss: {
+ enabled: true
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ }
+ },
buy: {
- currentPrice: 184.099,
- triggerPrice: 180.375
+ currentPrice: 27000,
+ triggerPrice: 26000,
+ athRestrictionPrice: 25000
},
sell: {
- currentPrice: 184.099,
+ currentPrice: 27000,
+ triggerPrice: null,
lastBuyPrice: null,
- triggerPrice: null
+ stopLossTriggerPrice: null
}
});
});
diff --git a/app/cronjob/trailingTrade/step/__tests__/ensure-grid-trade-order-executed.test.js b/app/cronjob/trailingTrade/step/__tests__/ensure-grid-trade-order-executed.test.js
new file mode 100644
index 00000000..cca4dd2d
--- /dev/null
+++ b/app/cronjob/trailingTrade/step/__tests__/ensure-grid-trade-order-executed.test.js
@@ -0,0 +1,1819 @@
+/* eslint-disable no-lonely-if */
+/* eslint-disable global-require */
+
+const _ = require('lodash');
+
+describe('ensure-grid-trade-order-executed.js', () => {
+ let result;
+ let rawData;
+
+ let binanceMock;
+ let slackMock;
+ let loggerMock;
+ let cacheMock;
+ let PubSubMock;
+
+ let mockCalculateLastBuyPrice;
+ let mockGetAPILimit;
+ let mockIsExceedAPILimit;
+ let mockDisableAction;
+ let mockSaveOrder;
+
+ let mockSaveSymbolGridTrade;
+
+ const momentDateTime = '2020-01-02T00:00:00.000Z';
+
+ describe('execute', () => {
+ beforeEach(async () => {
+ jest.clearAllMocks().resetModules();
+
+ // Mock moment to return static date
+ jest.mock(
+ 'moment',
+ () => nextCheck =>
+ jest.requireActual('moment')(nextCheck || '2020-01-02T00:00:00.000Z')
+ );
+
+ const {
+ binance,
+ slack,
+ cache,
+ logger,
+ PubSub
+ } = require('../../../../helpers');
+
+ binanceMock = binance;
+ slackMock = slack;
+ loggerMock = logger;
+ cacheMock = cache;
+ PubSubMock = PubSub;
+
+ cacheMock.get = jest.fn().mockResolvedValue(null);
+ cacheMock.set = jest.fn().mockResolvedValue(true);
+ cacheMock.del = jest.fn().mockResolvedValue(true);
+
+ PubSubMock.publish = jest.fn().mockResolvedValue(true);
+
+ slackMock.sendMessage = jest.fn().mockResolvedValue(true);
+ binanceMock.client.getOrder = jest.fn().mockResolvedValue([]);
+
+ mockCalculateLastBuyPrice = jest.fn().mockResolvedValue(true);
+ mockGetAPILimit = jest.fn().mockResolvedValue(10);
+ mockIsExceedAPILimit = jest.fn().mockReturnValue(false);
+ mockDisableAction = jest.fn().mockResolvedValue(true);
+ mockSaveOrder = jest.fn().mockResolvedValue(true);
+
+ mockSaveSymbolGridTrade = jest.fn().mockResolvedValue(true);
+ });
+
+ describe('when action is already determined', () => {
+ beforeEach(async () => {
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ calculateLastBuyPrice: mockCalculateLastBuyPrice,
+ getAPILimit: mockGetAPILimit,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ disableAction: mockDisableAction,
+ saveOrder: mockSaveOrder
+ }));
+
+ jest.mock('../../../trailingTradeHelper/configuration', () => ({
+ saveSymbolGridTrade: mockSaveSymbolGridTrade
+ }));
+
+ const step = require('../ensure-grid-trade-order-executed');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ action: 'buy',
+ featureToggle: { notifyOrderExecute: true, notifyDebug: true },
+ symbolConfiguration: {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.05,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ system: {
+ checkOrderExecutePeriod: 10,
+ temporaryDisableActionAfterConfirmingOrder: 20
+ }
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('does not trigger cache.get', () => {
+ expect(cacheMock.get).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger binance.client.getOrder', () => {
+ expect(binanceMock.client.getOrder).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
+ it('returns epxected result', () => {
+ expect(result).toStrictEqual(rawData);
+ });
+ });
+
+ describe('when api limit is exceed', () => {
+ beforeEach(async () => {
+ mockIsExceedAPILimit = jest.fn().mockReturnValue(true);
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ calculateLastBuyPrice: mockCalculateLastBuyPrice,
+ getAPILimit: mockGetAPILimit,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ disableAction: mockDisableAction,
+ saveOrder: mockSaveOrder
+ }));
+
+ jest.mock('../../../trailingTradeHelper/configuration', () => ({
+ saveSymbolGridTrade: mockSaveSymbolGridTrade
+ }));
+
+ const step = require('../ensure-grid-trade-order-executed');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ action: 'not-determined',
+ featureToggle: { notifyOrderExecute: true, notifyDebug: true },
+ symbolConfiguration: {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.05,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ system: {
+ checkOrderExecutePeriod: 10,
+ temporaryDisableActionAfterConfirmingOrder: 20
+ }
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('does not trigger cache.get', () => {
+ expect(cacheMock.get).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger binance.client.getOrder', () => {
+ expect(binanceMock.client.getOrder).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
+ it('returns epxected result', () => {
+ expect(result).toStrictEqual(rawData);
+ });
+ });
+
+ describe('when found last buy order', () => {
+ [
+ {
+ desc: 'last buy order is empty',
+ symbol: 'BNBUSDT',
+ lastBuyOrder: null,
+ getOrder: null,
+ saveSymbolGridTrade: null
+ },
+ {
+ desc: 'last buy order is FILLED - currentGridTradeIndex: 0',
+ symbol: 'BNBUSDT',
+ notifyDebug: true,
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: null,
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'BUY',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last buy order is FILLED - currentGridTradeIndex: 1',
+ symbol: 'BNBUSDT',
+ notifyDebug: false,
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: null,
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'BUY',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last buy order is NEW and still NEW before checking the order',
+ symbol: 'BNBUSDT',
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-02T00:01:00.000Z'
+ },
+ getOrder: null,
+ saveSymbolGridTrade: null
+ },
+ {
+ desc: 'last buy order is NEW and still NEW after checking the order',
+ symbol: 'BNBUSDT',
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: null
+ },
+ ...['CANCELED', 'REJECTED', 'EXPIRED', 'PENDING_CANCEL'].map(
+ status => ({
+ desc: `last buy order is NEW and become ${status}`,
+ symbol: 'BNBUSDT',
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status,
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: null
+ })
+ ),
+ {
+ desc: 'last buy order is NEW and now FILLED',
+ symbol: 'BNBUSDT',
+ notifyDebug: false,
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'BUY',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last buy order is NEW and now FILLED - currentGridTradeIndex: 1',
+ symbol: 'BNBUSDT',
+ notifyDebug: true,
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'BUY',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last buy order is NEW but error',
+ symbol: 'BNBUSDT',
+ lastBuyOrder: {
+ symbol: 'BNBUSDT',
+ side: 'BUY',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: 'error',
+ saveSymbolGridTrade: null
+ }
+ ].forEach((t, index) => {
+ describe(`${t.desc}`, () => {
+ beforeEach(async () => {
+ cacheMock.get = jest.fn().mockImplementation(key => {
+ if (key === `${t.symbol}-grid-trade-last-buy-order`) {
+ return JSON.stringify(t.lastBuyOrder);
+ }
+
+ return null;
+ });
+
+ if (t.getOrder === 'error') {
+ binanceMock.client.getOrder = jest
+ .fn()
+ .mockRejectedValue(new Error('something happened'));
+ } else {
+ binanceMock.client.getOrder = jest
+ .fn()
+ .mockResolvedValue(t.getOrder);
+ }
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ calculateLastBuyPrice: mockCalculateLastBuyPrice,
+ getAPILimit: mockGetAPILimit,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ disableAction: mockDisableAction,
+ saveOrder: mockSaveOrder
+ }));
+
+ jest.mock('../../../trailingTradeHelper/configuration', () => ({
+ saveSymbolGridTrade: mockSaveSymbolGridTrade
+ }));
+
+ const step = require('../ensure-grid-trade-order-executed');
+
+ rawData = {
+ symbol: t.symbol,
+ action: 'not-determined',
+ featureToggle: {
+ notifyOrderExecute: index % 2,
+ notifyDebug: t.notifyDebug || false
+ },
+ symbolConfiguration: {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.05,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ system: {
+ checkOrderExecutePeriod: 10,
+ temporaryDisableActionAfterConfirmingOrder: 20
+ }
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers cache.get for getting cached order', () => {
+ expect(cacheMock.get).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-buy-order`
+ );
+ });
+
+ if (t.lastBuyOrder === null) {
+ // If last order is not found
+ it('does not trigger binance.client.getOrder as order not found', () => {
+ expect(binanceMock.client.getOrder).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.set as order not found', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del as order not found', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveSymbolGridTrade', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+ } else if (t.lastBuyOrder.status.includes('FILLED')) {
+ // do filled thing
+ it('triggers calculated last buy price as order filled', () => {
+ expect(mockCalculateLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ t.symbol,
+ t.lastBuyOrder
+ );
+ });
+
+ it('triggers save symbol grid trade as order filled', () => {
+ expect(mockSaveSymbolGridTrade).toHaveBeenCalledWith(
+ loggerMock,
+ t.symbol,
+ t.saveSymbolGridTrade
+ );
+ });
+
+ it('triggers cache.del as order filled', () => {
+ expect(cacheMock.del).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-buy-order`
+ );
+ });
+
+ it('triggers disableAction as order filled', () => {
+ expect(mockDisableAction).toHaveBeenCalledWith(
+ t.symbol,
+ {
+ disabledBy: 'buy filled order',
+ message:
+ 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ 20
+ );
+ });
+
+ it('triggers saveOrder as order filled', () => {
+ const { lastBuyOrder } = t;
+
+ const order = _.cloneDeep(lastBuyOrder);
+
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order,
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has already filled and updated the last buy price.'
+ }
+ });
+ });
+ } else {
+ if (t.getOrder === 'error') {
+ // order throws an error
+ it('triggers cache.set for last buy order as order throws error', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-buy-order`,
+ JSON.stringify({
+ ...t.lastBuyOrder,
+ // 10 secs
+ nextCheck: '2020-01-02T00:00:10.000Z'
+ })
+ );
+ });
+
+ it('does not trigger saveSymbolGridTrade as order throws error', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del for last buy order as order throws error', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction as order throws error', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder as order throws error', () => {
+ const { lastBuyOrder } = t;
+
+ const order = _.cloneDeep(lastBuyOrder);
+
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order,
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order could not be found or error occurred querying the order.'
+ }
+ });
+ });
+ } else if (
+ Date.parse(t.lastBuyOrder.nextCheck) < Date.parse(momentDateTime)
+ ) {
+ // time to check order
+ it('triggers binance.client.getOrder as time to check', () => {
+ expect(binanceMock.client.getOrder).toHaveBeenCalledWith({
+ symbol: t.symbol,
+ orderId: t.lastBuyOrder.orderId
+ });
+ });
+
+ if (t.getOrder.status === 'FILLED') {
+ // do filled thing
+ it('triggers calculated last buy price as order filled after getting order result', () => {
+ expect(mockCalculateLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ t.symbol,
+ t.getOrder
+ );
+ });
+
+ it('triggers save symbol grid trade as order filled after getting order result', () => {
+ expect(mockSaveSymbolGridTrade).toHaveBeenCalledWith(
+ loggerMock,
+ t.symbol,
+ t.saveSymbolGridTrade
+ );
+ });
+
+ it('triggers cache.del as order filled after getting order result', () => {
+ expect(cacheMock.del).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-buy-order`
+ );
+ });
+
+ it('triggers disableAction after getting order result', () => {
+ expect(mockDisableAction).toHaveBeenCalledWith(
+ t.symbol,
+ {
+ disabledBy: 'buy filled order',
+ message:
+ 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ 20
+ );
+ });
+
+ it('triggers saveOrder as order filled after getting order result', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...t.lastBuyOrder,
+ ...t.getOrder
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has filled and updated the last buy price.'
+ }
+ });
+ });
+ } else if (
+ ['CANCELED', 'REJECTED', 'EXPIRED', 'PENDING_CANCEL'].includes(
+ t.getOrder.status
+ ) === true
+ ) {
+ // do cancel thing
+ it('triggers cache.del due to cancelled order', () => {
+ expect(cacheMock.del).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-buy-order`
+ );
+ });
+
+ it('does not trigger saveSymbolGridTrade due to cancelled order', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction due to cancelled order', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder due to cancelled order', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...t.lastBuyOrder,
+ ...t.getOrder
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order is no longer valid. Removed from the cache.'
+ }
+ });
+ });
+ } else {
+ // do else thing
+ it('triggers cache.set for last buy order as not filled', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-buy-order`,
+ JSON.stringify({
+ ...t.getOrder,
+ currentGridTradeIndex:
+ t.lastBuyOrder.currentGridTradeIndex,
+ // 10 secs
+ nextCheck: '2020-01-02T00:00:10.000Z'
+ })
+ );
+ });
+
+ it('does not trigger cache.del for last buy order as not filled', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveSymbolGridTrade as not filled', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction as not filled', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder as not filled', () => {
+ const { lastBuyOrder } = t;
+
+ const order = _.cloneDeep(lastBuyOrder);
+ _.unset(order, ['nextCheck']);
+ _.unset(order, ['currentGridTradeIndex']);
+
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order,
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order is not filled. Check next internal.'
+ }
+ });
+ });
+ }
+ } else if (
+ Date.parse(t.lastBuyOrder.nextCheck) > Date.parse(momentDateTime)
+ ) {
+ // no need to check
+ it('does not trigger binance.client.getOrder because time is not yet to check', () => {
+ expect(binanceMock.client.getOrder).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.set because time is not yet to check', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del because time is not yet to check', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveSymbolGridTrade because time is not yet to check', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction because time is not yet to check', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder because time is not yet to check', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+ }
+ }
+
+ it('returns result', () => {
+ expect(result).toStrictEqual(rawData);
+ });
+ });
+ });
+ });
+
+ describe('when found last sell order', () => {
+ [
+ {
+ desc: 'last sell order is empty',
+ symbol: 'BNBUSDT',
+ lastSellOrder: null,
+ getOrder: null,
+ saveSymbolGridTrade: null
+ },
+ {
+ desc: 'last sell order is FILLED - currentGridTradeIndex: 0',
+ symbol: 'BNBUSDT',
+ notifyDebug: true,
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: null,
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'SELL',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last sell order is FILLED - currentGridTradeIndex: 1',
+ symbol: 'BNBUSDT',
+ notifyDebug: true,
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: null,
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'SELL',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last sell order is NEW and still NEW before checking the order',
+ symbol: 'BNBUSDT',
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-02T00:01:00.000Z'
+ },
+ getOrder: null,
+ saveSymbolGridTrade: null
+ },
+ {
+ desc: 'last sell order is NEW and still NEW after checking the order',
+ symbol: 'BNBUSDT',
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: null
+ },
+ ...['CANCELED', 'REJECTED', 'EXPIRED', 'PENDING_CANCEL'].map(
+ status => ({
+ desc: `last sell order is NEW and become ${status}`,
+ symbol: 'BNBUSDT',
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status,
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: null
+ })
+ ),
+ {
+ desc: 'last sell order is NEW and now FILLED - currentGridTradeIndex: 0',
+ symbol: 'BNBUSDT',
+ notifyDebug: true,
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'SELL',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last sell order is NEW and now FILLED - currentGridTradeIndex: 1',
+ symbol: 'BNBUSDT',
+ notifyDebug: false,
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'FILLED',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000'
+ },
+ saveSymbolGridTrade: {
+ buy: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.025,
+ triggerPercentage: 0.8
+ }
+ ],
+ sell: [
+ {
+ executed: false,
+ executedOrder: null,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ stopPercentage: 0.985,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: true,
+ executedOrder: {
+ currentGridTradeIndex: 1,
+ nextCheck: '2020-01-01T23:59:00.000Z',
+ orderId: 2705449295,
+ origQty: '0.03320000',
+ price: '302.09000000',
+ side: 'SELL',
+ status: 'FILLED',
+ stopPrice: '301.80000000',
+ symbol: 'BNBUSDT',
+ type: 'STOP_LOSS_LIMIT'
+ },
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ stopPercentage: 0.975,
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ },
+ {
+ desc: 'last sell order is NEW but error',
+ symbol: 'BNBUSDT',
+ lastSellOrder: {
+ symbol: 'BNBUSDT',
+ side: 'SELL',
+ status: 'NEW',
+ type: 'STOP_LOSS_LIMIT',
+ orderId: 2705449295,
+ price: '302.09000000',
+ origQty: '0.03320000',
+ stopPrice: '301.80000000',
+ currentGridTradeIndex: 0,
+ nextCheck: '2020-01-01T23:59:00.000Z'
+ },
+ getOrder: 'error',
+ saveSymbolGridTrade: {}
+ }
+ ].forEach((t, index) => {
+ describe(`${t.desc}`, () => {
+ beforeEach(async () => {
+ cacheMock.get = jest.fn().mockImplementation(key => {
+ if (key === `${t.symbol}-grid-trade-last-sell-order`) {
+ return JSON.stringify(t.lastSellOrder);
+ }
+
+ return null;
+ });
+
+ if (t.getOrder === 'error') {
+ binanceMock.client.getOrder = jest
+ .fn()
+ .mockRejectedValue(new Error('something happened'));
+ } else {
+ binanceMock.client.getOrder = jest
+ .fn()
+ .mockResolvedValue(t.getOrder);
+ }
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ calculateLastBuyPrice: mockCalculateLastBuyPrice,
+ getAPILimit: mockGetAPILimit,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ disableAction: mockDisableAction,
+ saveOrder: mockSaveOrder
+ }));
+
+ jest.mock('../../../trailingTradeHelper/configuration', () => ({
+ saveSymbolGridTrade: mockSaveSymbolGridTrade
+ }));
+
+ const step = require('../ensure-grid-trade-order-executed');
+
+ rawData = {
+ symbol: t.symbol,
+ action: 'not-determined',
+ featureToggle: {
+ notifyOrderExecute: index % 2,
+ notifyDebug: index % 2
+ },
+ symbolConfiguration: {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.8,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.05,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ },
+ system: {
+ checkOrderExecutePeriod: 10,
+ temporaryDisableActionAfterConfirmingOrder: 20
+ }
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers cache.get for getting cached order', () => {
+ expect(cacheMock.get).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-sell-order`
+ );
+ });
+
+ if (t.lastSellOrder === null) {
+ // If last order is not found
+ it('does not trigger binance.client.getOrder as order not found', () => {
+ expect(binanceMock.client.getOrder).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.set as order not found', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del as order not found', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+ } else if (t.lastSellOrder.status.includes('FILLED')) {
+ // do filled thing
+
+ it('triggers save symbol grid trade as order filled', () => {
+ expect(mockSaveSymbolGridTrade).toHaveBeenCalledWith(
+ loggerMock,
+ t.symbol,
+ t.saveSymbolGridTrade
+ );
+ });
+
+ it('triggers cache.del as order filled', () => {
+ expect(cacheMock.del).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-sell-order`
+ );
+ });
+
+ it('triggers disableAction as order filled', () => {
+ expect(mockDisableAction).toHaveBeenCalledWith(
+ t.symbol,
+ {
+ disabledBy: 'sell filled order',
+ message:
+ 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ 20
+ );
+ });
+
+ it('triggers saveOrder as order filled', () => {
+ const { lastSellOrder } = t;
+
+ const order = _.cloneDeep(lastSellOrder);
+
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order,
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has already filled and updated the last buy price.'
+ }
+ });
+ });
+ } else {
+ if (t.getOrder === 'error') {
+ // order throws an error
+ it('triggers cache.set for last sell order as order throws error', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-sell-order`,
+ JSON.stringify({
+ ...t.lastSellOrder,
+ // 10 secs
+ nextCheck: '2020-01-02T00:00:10.000Z'
+ })
+ );
+ });
+
+ it('does not trigger saveSymbolGridTrade as order throws error', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del for last sell order as order throws error', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction as order throws error', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder as order throws error', () => {
+ const { lastSellOrder } = t;
+
+ const order = _.cloneDeep(lastSellOrder);
+
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order,
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order could not be found or error occurred querying the order.'
+ }
+ });
+ });
+ } else if (
+ Date.parse(t.lastSellOrder.nextCheck) < Date.parse(momentDateTime)
+ ) {
+ // time to check order
+ it('triggers binance.client.getOrder as time to check', () => {
+ expect(binanceMock.client.getOrder).toHaveBeenCalledWith({
+ symbol: t.symbol,
+ orderId: t.lastSellOrder.orderId
+ });
+ });
+
+ if (t.getOrder.status === 'FILLED') {
+ // do filled thing
+ it('triggers save symbol grid trade as order filled after getting order result', () => {
+ expect(mockSaveSymbolGridTrade).toHaveBeenCalledWith(
+ loggerMock,
+ t.symbol,
+ t.saveSymbolGridTrade
+ );
+ });
+
+ it('triggers cache.del as order filled after getting order result', () => {
+ expect(cacheMock.del).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-sell-order`
+ );
+ });
+
+ it('triggers disableAction after getting order result', () => {
+ expect(mockDisableAction).toHaveBeenCalledWith(
+ t.symbol,
+ {
+ disabledBy: 'sell filled order',
+ message:
+ 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ 20
+ );
+ });
+
+ it('triggers saveOrder as order filled after getting order result', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...t.lastSellOrder,
+ ...t.getOrder
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has filled and updated the last buy price.'
+ }
+ });
+ });
+ } else if (
+ ['CANCELED', 'REJECTED', 'EXPIRED', 'PENDING_CANCEL'].includes(
+ t.getOrder.status
+ ) === true
+ ) {
+ // do cancel thing
+ it('triggers cache.del due to cancelled order', () => {
+ expect(cacheMock.del).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-sell-order`
+ );
+ });
+
+ it('does not trigger saveSymbolGridTrade due to cancelled order', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction due to cancelled order', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder due to cancelled order', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...t.lastSellOrder,
+ ...t.getOrder
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order is no longer valid. Removed from the cache.'
+ }
+ });
+ });
+ } else {
+ // do else thing
+ it('triggers cache.set for last sell order as not filled', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ `${t.symbol}-grid-trade-last-sell-order`,
+ JSON.stringify({
+ ...t.getOrder,
+ currentGridTradeIndex:
+ t.lastSellOrder.currentGridTradeIndex,
+ // 10 secs
+ nextCheck: '2020-01-02T00:00:10.000Z'
+ })
+ );
+ });
+
+ it('does not trigger cache.del for last sell order as not filled', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveSymbolGridTrade as not filled', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction as not filled', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder as not filled', () => {
+ const { lastSellOrder } = t;
+
+ const order = _.cloneDeep(lastSellOrder);
+ _.unset(order, ['nextCheck']);
+ _.unset(order, ['currentGridTradeIndex']);
+
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order,
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order is not filled. Check next internal.'
+ }
+ });
+ });
+ }
+ } else if (
+ Date.parse(t.lastSellOrder.nextCheck) > Date.parse(momentDateTime)
+ ) {
+ // no need to check
+ it('does not trigger binance.client.getOrder because time is not yet to check', () => {
+ expect(binanceMock.client.getOrder).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.set because time is not yet to check', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger cache.del because time is not yet to check', () => {
+ expect(cacheMock.del).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveSymbolGridTrade because time is not yet to check', () => {
+ expect(mockSaveSymbolGridTrade).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger disableAction because time is not yet to check', () => {
+ expect(mockDisableAction).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder because time is not yet to check', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+ }
+ }
+
+ it('returns result', () => {
+ expect(result).toStrictEqual(rawData);
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/app/cronjob/trailingTrade/step/__tests__/ensure-manual-buy-order.test.js b/app/cronjob/trailingTrade/step/__tests__/ensure-manual-buy-order.test.js
index f1ef4b01..afd76990 100644
--- a/app/cronjob/trailingTrade/step/__tests__/ensure-manual-buy-order.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/ensure-manual-buy-order.test.js
@@ -11,9 +11,9 @@ describe('ensure-manual-buy-order.js', () => {
let cacheMock;
let PubSubMock;
- let mockGetLastBuyPrice;
- let mockSaveLastBuyPrice;
+ let mockCalculateLastBuyPrice;
let mockGetAPILimit;
+ let mockSaveOrder;
describe('execute', () => {
beforeEach(() => {
@@ -44,17 +44,17 @@ describe('ensure-manual-buy-order.js', () => {
slackMock.sendMessage = jest.fn().mockResolvedValue(true);
binanceMock.client.getOrder = jest.fn().mockResolvedValue([]);
- mockGetLastBuyPrice = jest.fn().mockReturnValue(null);
- mockSaveLastBuyPrice = jest.fn().mockResolvedValue(true);
+ mockCalculateLastBuyPrice = jest.fn().mockResolvedValue(true);
mockGetAPILimit = jest.fn().mockResolvedValue(10);
+ mockSaveOrder = jest.fn().mockResolvedValue(true);
});
describe('when manual buy order is not available', () => {
beforeEach(async () => {
jest.mock('../../../trailingTradeHelper/common', () => ({
- getLastBuyPrice: mockGetLastBuyPrice,
- saveLastBuyPrice: mockSaveLastBuyPrice,
- getAPILimit: mockGetAPILimit
+ calculateLastBuyPrice: mockCalculateLastBuyPrice,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
cacheMock.hgetall = jest.fn().mockResolvedValue(null);
@@ -82,8 +82,8 @@ describe('ensure-manual-buy-order.js', () => {
expect(cacheMock.hdel).not.toHaveBeenCalled();
});
- it('does not trigger saveLastBuyPrice', () => {
- expect(mockSaveLastBuyPrice).not.toHaveBeenCalled();
+ it('does not trigger calculateLastBuyPrice', () => {
+ expect(mockCalculateLastBuyPrice).not.toHaveBeenCalled();
});
it('returns expected result', () => {
@@ -119,10 +119,6 @@ describe('ensure-manual-buy-order.js', () => {
type: 'LIMIT',
side: 'BUY'
})
- },
- expectedSaveLastPrice: {
- lastBuyPrice: 27.38725,
- quantity: 4
}
},
{
@@ -149,10 +145,6 @@ describe('ensure-manual-buy-order.js', () => {
}
]
})
- },
- expectedSaveLastPrice: {
- lastBuyPrice: 406.46999999999997,
- quantity: 0.123
}
},
{
@@ -182,23 +174,15 @@ describe('ensure-manual-buy-order.js', () => {
}
]
})
- },
- expectedSaveLastPrice: {
- lastBuyPrice: 20.59439592969473,
- quantity: 5.404999999999999
}
}
].forEach(testData => {
describe(`${testData.desc}`, () => {
beforeEach(async () => {
- mockGetLastBuyPrice = jest
- .fn()
- .mockResolvedValue(testData.lastBuyPriceDoc);
-
jest.mock('../../../trailingTradeHelper/common', () => ({
- getLastBuyPrice: mockGetLastBuyPrice,
- saveLastBuyPrice: mockSaveLastBuyPrice,
- getAPILimit: mockGetAPILimit
+ calculateLastBuyPrice: mockCalculateLastBuyPrice,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
cacheMock.hgetall = jest
@@ -220,11 +204,11 @@ describe('ensure-manual-buy-order.js', () => {
result = await step.execute(loggerMock, rawData);
});
- it('triggers saveLastBuyPrice', () => {
- expect(mockSaveLastBuyPrice).toHaveBeenCalledWith(
+ it('triggers calculateLastBuyPrice', () => {
+ expect(mockCalculateLastBuyPrice).toHaveBeenCalledWith(
loggerMock,
testData.symbol,
- testData.expectedSaveLastPrice
+ JSON.parse(testData.cacheResults[testData.orderId])
);
});
@@ -234,6 +218,18 @@ describe('ensure-manual-buy-order.js', () => {
testData.orderId
);
});
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: JSON.parse(testData.cacheResults[testData.orderId]),
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order has already filled and updated the last buy price.'
+ }
+ });
+ });
});
});
});
@@ -272,10 +268,7 @@ describe('ensure-manual-buy-order.js', () => {
type: 'LIMIT',
side: 'BUY'
},
- expectedSaveLastPrice: {
- lastBuyPrice: 27.38725,
- quantity: 4
- }
+ expectedCalculateLastBuyPrice: true
},
{
desc: 'with MARKET order and FILLED',
@@ -309,10 +302,7 @@ describe('ensure-manual-buy-order.js', () => {
type: 'MARKET',
side: 'BUY'
},
- expectedSaveLastPrice: {
- lastBuyPrice: 27.38725,
- quantity: 4
- }
+ expectedCalculateLastBuyPrice: true
},
{
desc: 'with MARKET order and FILLED, but not yet to check',
@@ -346,14 +336,16 @@ describe('ensure-manual-buy-order.js', () => {
type: 'MARKET',
side: 'BUY'
},
- expectedSaveLastPrice: null
+ expectedCalculateLastBuyPrice: false
}
].forEach(testData => {
describe(`${testData.desc}`, () => {
beforeEach(async () => {
- mockGetLastBuyPrice = jest
- .fn()
- .mockResolvedValue(testData.lastBuyPriceDoc);
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ calculateLastBuyPrice: mockCalculateLastBuyPrice,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
cacheMock.hgetall = jest
.fn()
@@ -378,12 +370,12 @@ describe('ensure-manual-buy-order.js', () => {
result = await step.execute(loggerMock, rawData);
});
- if (testData.expectedSaveLastPrice) {
- it('triggers saveLastBuyPrice', () => {
- expect(mockSaveLastBuyPrice).toHaveBeenCalledWith(
+ if (testData.expectedCalculateLastBuyPrice) {
+ it('triggers calculateLastBuyPrice', () => {
+ expect(mockCalculateLastBuyPrice).toHaveBeenCalledWith(
loggerMock,
testData.symbol,
- testData.expectedSaveLastPrice
+ testData.getOrderResult
);
});
@@ -393,14 +385,33 @@ describe('ensure-manual-buy-order.js', () => {
testData.orderId
);
});
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...JSON.parse(testData.cacheResults[testData.orderId]),
+ ...testData.getOrderResult
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order has filled and updated the last buy price.'
+ }
+ });
+ });
} else {
- it('does not trigger saveLastBuyPrice', () => {
- expect(mockSaveLastBuyPrice).not.toHaveBeenCalled();
+ it('does not trigger calculateLastBuyPrice', () => {
+ expect(mockCalculateLastBuyPrice).not.toHaveBeenCalled();
});
it('does not trigger cache.hdel', () => {
expect(cacheMock.hdel).not.toHaveBeenCalled();
});
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
}
it('does not trigger cache.hset', () => {
@@ -413,10 +424,6 @@ describe('ensure-manual-buy-order.js', () => {
{
desc: 'with LIMIT order and CANCELED',
symbol: 'CAKEUSDT',
- lastBuyPriceDoc: {
- lastBuyPrice: 30,
- quantity: 3
- },
orderId: 159653829,
cacheResults: {
159653829: JSON.stringify({
@@ -446,10 +453,6 @@ describe('ensure-manual-buy-order.js', () => {
{
desc: 'with LIMIT order and REJECTED',
symbol: 'CAKEUSDT',
- lastBuyPriceDoc: {
- lastBuyPrice: 30,
- quantity: 3
- },
orderId: 159653829,
cacheResults: {
159653829: JSON.stringify({
@@ -479,10 +482,6 @@ describe('ensure-manual-buy-order.js', () => {
{
desc: 'with LIMIT order and EXPIRED',
symbol: 'CAKEUSDT',
- lastBuyPriceDoc: {
- lastBuyPrice: 30,
- quantity: 3
- },
orderId: 159653829,
cacheResults: {
159653829: JSON.stringify({
@@ -512,10 +511,6 @@ describe('ensure-manual-buy-order.js', () => {
{
desc: 'with LIMIT order and PENDING_CANCEL',
symbol: 'CAKEUSDT',
- lastBuyPriceDoc: {
- lastBuyPrice: 30,
- quantity: 3
- },
orderId: 159653829,
cacheResults: {
159653829: JSON.stringify({
@@ -545,10 +540,6 @@ describe('ensure-manual-buy-order.js', () => {
{
desc: 'with LIMIT order and CANCELED',
symbol: 'CAKEUSDT',
- lastBuyPriceDoc: {
- lastBuyPrice: 30,
- quantity: 3
- },
orderId: 159653829,
cacheResults: {
159653829: JSON.stringify({
@@ -578,10 +569,6 @@ describe('ensure-manual-buy-order.js', () => {
].forEach(testData => {
describe(`${testData.desc}`, () => {
beforeEach(async () => {
- mockGetLastBuyPrice = jest
- .fn()
- .mockResolvedValue(testData.lastBuyPriceDoc);
-
cacheMock.hgetall = jest
.fn()
.mockResolvedValue(testData.cacheResults);
@@ -605,8 +592,8 @@ describe('ensure-manual-buy-order.js', () => {
result = await step.execute(loggerMock, rawData);
});
- it('does not trigger saveLastBuyPrice', () => {
- expect(mockSaveLastBuyPrice).not.toHaveBeenCalled();
+ it('does not trigger calculateLastBuyPrice', () => {
+ expect(mockCalculateLastBuyPrice).not.toHaveBeenCalled();
});
it('triggers cache.hdel', () => {
@@ -615,6 +602,21 @@ describe('ensure-manual-buy-order.js', () => {
testData.orderId
);
});
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...JSON.parse(testData.cacheResults[testData.orderId]),
+ ...testData.getOrderResult
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order is no longer valid. Removed from the cache.'
+ }
+ });
+ });
});
});
@@ -622,10 +624,6 @@ describe('ensure-manual-buy-order.js', () => {
{
desc: 'with LIMIT order and still NEW',
symbol: 'CAKEUSDT',
- lastBuyPriceDoc: {
- lastBuyPrice: 30,
- quantity: 3
- },
orderId: 159653829,
cacheResults: {
159653829: JSON.stringify({
@@ -655,10 +653,6 @@ describe('ensure-manual-buy-order.js', () => {
].forEach(testData => {
describe(`${testData.desc}`, () => {
beforeEach(async () => {
- mockGetLastBuyPrice = jest
- .fn()
- .mockResolvedValue(testData.lastBuyPriceDoc);
-
cacheMock.hgetall = jest
.fn()
.mockResolvedValue(testData.cacheResults);
@@ -682,8 +676,8 @@ describe('ensure-manual-buy-order.js', () => {
result = await step.execute(loggerMock, rawData);
});
- it('does not trigger saveLastBuyPrice', () => {
- expect(mockSaveLastBuyPrice).not.toHaveBeenCalled();
+ it('does not trigger calculateLastBuyPrice', () => {
+ expect(mockCalculateLastBuyPrice).not.toHaveBeenCalled();
});
it('does not trigger cache.hdel', () => {
@@ -697,16 +691,24 @@ describe('ensure-manual-buy-order.js', () => {
expect.any(String)
);
});
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...testData.getOrderResult
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage: 'The order is not filled. Check next internal.'
+ }
+ });
+ });
});
});
describe('when binance.client.getOrder throws an error', () => {
beforeEach(async () => {
- mockGetLastBuyPrice = jest.fn().mockResolvedValue({
- lastBuyPrice: 30,
- quantity: 3
- });
-
cacheMock.hgetall = jest.fn().mockResolvedValue({
159653829: JSON.stringify({
symbol: 'CAKEUSDT',
@@ -742,8 +744,8 @@ describe('ensure-manual-buy-order.js', () => {
result = await step.execute(loggerMock, rawData);
});
- it('does not trigger saveLastBuyPrice', () => {
- expect(mockSaveLastBuyPrice).not.toHaveBeenCalled();
+ it('does not trigger calculateLastBuyPrice', () => {
+ expect(mockCalculateLastBuyPrice).not.toHaveBeenCalled();
});
it('does not trigger cache.hdel', () => {
@@ -757,6 +759,28 @@ describe('ensure-manual-buy-order.js', () => {
expect.any(String)
);
});
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'CAKEUSDT',
+ orderId: 159653829,
+ origQty: '1.00000000',
+ executedQty: '1.00000000',
+ cummulativeQuoteQty: '19.54900000',
+ status: 'NEW',
+ type: 'LIMIT',
+ side: 'BUY',
+ nextCheck: expect.any(String)
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order could not be found or error occurred querying the order.'
+ }
+ });
+ });
});
});
});
diff --git a/app/cronjob/trailingTrade/step/__tests__/ensure-order-placed.test.js b/app/cronjob/trailingTrade/step/__tests__/ensure-order-placed.test.js
index d1896180..a52d873b 100644
--- a/app/cronjob/trailingTrade/step/__tests__/ensure-order-placed.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/ensure-order-placed.test.js
@@ -13,6 +13,7 @@ describe('ensure-order-placed.js', () => {
let mockGetAccountInfoFromAPI;
let mockDisableAction;
let mockGetAPILimit;
+ let mockSaveOrder;
beforeEach(() => {
jest.clearAllMocks().resetModules();
@@ -33,6 +34,7 @@ describe('ensure-order-placed.js', () => {
mockDisableAction = jest.fn().mockResolvedValue(true);
mockGetAPILimit = jest.fn().mockReturnValue(10);
+ mockSaveOrder = jest.fn().mockResolvedValue(true);
});
describe('when there is no order', () => {
@@ -57,7 +59,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
rawData = {
@@ -100,6 +103,10 @@ describe('ensure-order-placed.js', () => {
expect(cacheMock.del).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
@@ -160,7 +167,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
});
@@ -209,6 +217,21 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).not.toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ orderId: 123,
+ symbol: 'BTCUSDT',
+ status: 'NEW'
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-order-placed',
+ savedMessage: 'The order is found in the open orders.'
+ }
+ });
+ });
+
it('triggers disableAction', () => {
expect(mockDisableAction).toHaveBeenCalledWith(
'BTCUSDT',
@@ -299,6 +322,21 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ orderId: 123,
+ symbol: 'BTCUSDT',
+ status: 'NEW'
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-order-placed',
+ savedMessage: 'The order is found in the open orders.'
+ }
+ });
+ });
+
it('triggers disableAction', () => {
expect(mockDisableAction).toHaveBeenCalledWith(
'BTCUSDT',
@@ -382,7 +420,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
});
@@ -433,6 +472,10 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
@@ -499,6 +542,10 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
@@ -566,7 +613,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
rawData = {
@@ -618,6 +666,21 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).not.toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ orderId: 123,
+ symbol: 'BTCUSDT',
+ status: 'NEW'
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-order-placed',
+ savedMessage: 'The order is found in the open orders.'
+ }
+ });
+ });
+
it('triggers disableAction', () => {
expect(mockDisableAction).toHaveBeenCalledWith(
'BTCUSDT',
@@ -707,7 +770,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
rawData = {
@@ -759,6 +823,21 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ orderId: 123,
+ symbol: 'BTCUSDT',
+ status: 'NEW'
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'ensure-order-placed',
+ savedMessage: 'The order is found in the open orders.'
+ }
+ });
+ });
+
it('triggers disableAction', () => {
expect(mockDisableAction).toHaveBeenCalledWith(
'BTCUSDT',
@@ -843,7 +922,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
rawData = {
@@ -888,6 +968,10 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).not.toHaveBeenCalled();
});
+ it('does not trigger saveORder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
@@ -943,7 +1027,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
rawData = {
@@ -988,6 +1073,10 @@ describe('ensure-order-placed.js', () => {
expect(slackMock.sendMessage).toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
@@ -1031,7 +1120,8 @@ describe('ensure-order-placed.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
rawData = {
@@ -1058,6 +1148,10 @@ describe('ensure-order-placed.js', () => {
expect(cacheMock.get).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
diff --git a/app/cronjob/trailingTrade/step/__tests__/get-indicators.test.js b/app/cronjob/trailingTrade/step/__tests__/get-indicators.test.js
index 61bb9a69..4047cfe6 100644
--- a/app/cronjob/trailingTrade/step/__tests__/get-indicators.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/get-indicators.test.js
@@ -60,16 +60,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
@@ -92,16 +97,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: {
maxLossPercentage: 0.8
}
@@ -137,7 +147,7 @@ describe('get-indicators.js', () => {
},
sell: {
currentPrice: 15555.09,
- limitPrice: 15228.43311,
+ limitPrice: null,
lastBuyPrice: null,
triggerPrice: null,
difference: null,
@@ -198,16 +208,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: false,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
@@ -230,16 +245,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: false,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: {
maxLossPercentage: 0.8
}
@@ -275,7 +295,7 @@ describe('get-indicators.js', () => {
},
sell: {
currentPrice: 15555.09,
- limitPrice: 15228.43311,
+ limitPrice: null,
lastBuyPrice: null,
triggerPrice: null,
difference: null,
@@ -292,199 +312,1121 @@ describe('get-indicators.js', () => {
});
describe('with no open orders but has last buy price', () => {
- beforeEach(async () => {
- const { cache, logger } = require('../../../../helpers');
- cacheMock = cache;
- loggerMock = logger;
+ describe('when buy grid trade index is null', () => {
+ beforeEach(async () => {
+ const { cache, logger } = require('../../../../helpers');
+ cacheMock = cache;
+ loggerMock = logger;
+
+ mockGetLastBuyPrice = jest
+ .fn()
+ .mockResolvedValue({ lastBuyPrice: 9000, quantity: 1 });
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getLastBuyPrice: mockGetLastBuyPrice
+ }));
+
+ cacheMock.hget = jest.fn().mockImplementation((hash, key) => {
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-indicator-data'
+ ) {
+ return JSON.stringify({
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ });
+ }
- mockGetLastBuyPrice = jest
- .fn()
- .mockResolvedValue({ lastBuyPrice: 9000, quantity: 1 });
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getLastBuyPrice: mockGetLastBuyPrice
- }));
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-latest-candle'
+ ) {
+ return JSON.stringify({
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ });
+ }
- cacheMock.hget = jest.fn().mockImplementation((hash, key) => {
- if (
- hash === 'trailing-trade-symbols' &&
- key === 'BTCUSDT-indicator-data'
- ) {
- return JSON.stringify({
+ return null;
+ });
+
+ step = require('../get-indicators');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: -1,
+ currentGridTrade: null,
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: null,
+ stopLoss: { maxLossPercentage: 0.8 }
+ }
+ },
+ baseAssetBalance: { total: 0.1 },
+ openOrders: []
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mockGetLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers expected value', () => {
+ expect(result).toStrictEqual({
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: -1,
+ currentGridTrade: null,
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: null,
+ stopLoss: {
+ maxLossPercentage: 0.8
+ }
+ }
+ },
+ baseAssetBalance: {
+ total: 0.1,
+ estimatedValue: 1555.509,
+ isLessThanMinNotionalValue: false
+ },
+ openOrders: [],
+ indicators: {
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ },
+ lastCandle: {
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ },
+ buy: {
+ currentPrice: 15555.09,
+ limitPrice: null,
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000,
+ athRestrictionPrice: 8100,
+ triggerPrice: null,
+ difference: null,
+ openOrders: [],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 15555.09,
+ limitPrice: null,
+ lastBuyPrice: 9000,
+ triggerPrice: null,
+ difference: null,
+ currentProfit: 655.509,
+ currentProfitPercentage: 42.14112550939918,
+ stopLossDifference: 53.712900407519335,
+ stopLossTriggerPrice: 7200,
+ openOrders: [],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ }
+ });
+ });
+ });
+
+ describe('when buy grid trade index is 0', () => {
+ beforeEach(async () => {
+ const { cache, logger } = require('../../../../helpers');
+ cacheMock = cache;
+ loggerMock = logger;
+
+ mockGetLastBuyPrice = jest
+ .fn()
+ .mockResolvedValue({ lastBuyPrice: 9000, quantity: 1 });
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getLastBuyPrice: mockGetLastBuyPrice
+ }));
+
+ cacheMock.hget = jest.fn().mockImplementation((hash, key) => {
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-indicator-data'
+ ) {
+ return JSON.stringify({
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ });
+ }
+
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-latest-candle'
+ ) {
+ return JSON.stringify({
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ });
+ }
+
+ return null;
+ });
+
+ step = require('../get-indicators');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: { maxLossPercentage: 0.8 }
+ }
+ },
+ baseAssetBalance: { total: 0.1 },
+ openOrders: []
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mockGetLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers expected value', () => {
+ expect(result).toStrictEqual({
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: {
+ maxLossPercentage: 0.8
+ }
+ }
+ },
+ baseAssetBalance: {
+ total: 0.1,
+ estimatedValue: 1555.509,
+ isLessThanMinNotionalValue: false
+ },
+ openOrders: [],
+ indicators: {
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ },
+ lastCandle: {
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ },
+ buy: {
+ currentPrice: 15555.09,
+ limitPrice: 15881.746889999999,
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000,
+ athRestrictionPrice: 8100,
+ triggerPrice: 8981.9603,
+ difference: 73.18146017634923,
+ openOrders: [],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 15555.09,
+ limitPrice: 15228.43311,
+ lastBuyPrice: 9000,
+ triggerPrice: 9540,
+ difference: 38.669593039963125,
+ currentProfit: 655.509,
+ currentProfitPercentage: 42.14112550939918,
+ stopLossDifference: 53.712900407519335,
+ stopLossTriggerPrice: 7200,
+ openOrders: [],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ }
+ });
+ });
+ });
+
+ describe('when buy grid trade index is 1', () => {
+ beforeEach(async () => {
+ const { cache, logger } = require('../../../../helpers');
+ cacheMock = cache;
+ loggerMock = logger;
+
+ mockGetLastBuyPrice = jest
+ .fn()
+ .mockResolvedValue({ lastBuyPrice: 9000, quantity: 1 });
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getLastBuyPrice: mockGetLastBuyPrice
+ }));
+
+ cacheMock.hget = jest.fn().mockImplementation((hash, key) => {
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-indicator-data'
+ ) {
+ return JSON.stringify({
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ });
+ }
+
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-latest-candle'
+ ) {
+ return JSON.stringify({
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ });
+ }
+
+ return null;
+ });
+
+ step = require('../get-indicators');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: { maxLossPercentage: 0.8 }
+ }
+ },
+ baseAssetBalance: { total: 0.1 },
+ openOrders: []
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mockGetLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers expected value', () => {
+ expect(result).toStrictEqual({
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: {
+ maxLossPercentage: 0.8
+ }
+ }
+ },
+ baseAssetBalance: {
+ total: 0.1,
+ estimatedValue: 1555.509,
+ isLessThanMinNotionalValue: false
+ },
+ openOrders: [],
+ indicators: {
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ },
+ lastCandle: {
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ },
+ buy: {
+ currentPrice: 15555.09,
+ limitPrice: 15881.746889999999,
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000,
+ athRestrictionPrice: 8100,
+ triggerPrice: 9090,
+ difference: 71.12310231023102,
+ openOrders: [],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 15555.09,
+ limitPrice: 15228.43311,
+ lastBuyPrice: 9000,
+ triggerPrice: 9540,
+ difference: 38.669593039963125,
+ currentProfit: 655.509,
+ currentProfitPercentage: 42.14112550939918,
+ stopLossDifference: 53.712900407519335,
+ stopLossTriggerPrice: 7200,
+ openOrders: [],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ }
+ });
+ });
+ });
+ });
+
+ describe('with open orders and has last buy price', () => {
+ describe('when buy grid trade index is null', () => {
+ beforeEach(async () => {
+ const { cache, logger } = require('../../../../helpers');
+ cacheMock = cache;
+ loggerMock = logger;
+
+ mockGetLastBuyPrice = jest
+ .fn()
+ .mockResolvedValue({ lastBuyPrice: 9000, quantity: 1 });
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getLastBuyPrice: mockGetLastBuyPrice
+ }));
+
+ cacheMock.hget = jest.fn().mockImplementation((hash, key) => {
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-indicator-data'
+ ) {
+ return JSON.stringify({
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ });
+ }
+
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-latest-candle'
+ ) {
+ return JSON.stringify({
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ });
+ }
+
+ return null;
+ });
+
+ step = require('../get-indicators');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: -1,
+ currentGridTrade: null,
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: null,
+ stopLoss: { maxLossPercentage: 0.8 }
+ }
+ },
+ baseAssetBalance: { total: 0.1 },
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162
+ },
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162
+ }
+ ]
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mockGetLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers expected value', () => {
+ expect(result).toStrictEqual({
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: -1,
+ currentGridTrade: null,
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: null,
+ stopLoss: {
+ maxLossPercentage: 0.8
+ }
+ }
+ },
+ baseAssetBalance: {
+ total: 0.1,
+ estimatedValue: 1555.509,
+ isLessThanMinNotionalValue: false
+ },
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ updatedAt: expect.any(Object)
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: null,
+ differenceToExecute: -3.5030976998525976,
+ updatedAt: expect.any(Object)
+ },
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: null,
+ differenceToExecute: -2.2173449333947826,
+ minimumProfit: 35,
+ minimumProfitPercentage: 43.75,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ indicators: {
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ },
+ lastCandle: {
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ },
+ buy: {
+ currentPrice: 15555.09,
+ limitPrice: null,
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000,
+ athRestrictionPrice: 8100,
+ triggerPrice: null,
+ difference: null,
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ updatedAt: expect.any(Object)
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: null,
+ differenceToExecute: -3.5030976998525976,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 15555.09,
+ limitPrice: null,
+ lastBuyPrice: 9000,
+ triggerPrice: null,
+ difference: null,
+ currentProfit: 655.509,
+ currentProfitPercentage: 42.14112550939918,
+ stopLossDifference: 53.712900407519335,
+ stopLossTriggerPrice: 7200,
+ openOrders: [
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: null,
+ differenceToExecute: -2.2173449333947826,
+ minimumProfit: 35,
+ minimumProfitPercentage: 43.75,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ }
+ });
+ });
+ });
+
+ describe('when buy grid trade index is 0', () => {
+ beforeEach(async () => {
+ const { cache, logger } = require('../../../../helpers');
+ cacheMock = cache;
+ loggerMock = logger;
+
+ mockGetLastBuyPrice = jest
+ .fn()
+ .mockResolvedValue({ lastBuyPrice: 9000, quantity: 1 });
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getLastBuyPrice: mockGetLastBuyPrice
+ }));
+
+ cacheMock.hget = jest.fn().mockImplementation((hash, key) => {
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-indicator-data'
+ ) {
+ return JSON.stringify({
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ });
+ }
+
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-latest-candle'
+ ) {
+ return JSON.stringify({
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ });
+ }
+
+ return null;
+ });
+
+ step = require('../get-indicators');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: { maxLossPercentage: 0.8 }
+ }
+ },
+ baseAssetBalance: { total: 0.1 },
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162
+ },
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162
+ }
+ ]
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mockGetLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers expected value', () => {
+ expect(result).toStrictEqual({
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: {
+ maxLossPercentage: 0.8
+ }
+ }
+ },
+ baseAssetBalance: {
+ total: 0.1,
+ estimatedValue: 1555.509,
+ isLessThanMinNotionalValue: false
+ },
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ updatedAt: expect.any(Object)
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: -1.37423868741684,
+ differenceToExecute: -3.5030976998525976,
+ updatedAt: expect.any(Object)
+ },
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: -4.40995396669539,
+ differenceToExecute: -2.2173449333947826,
+ minimumProfit: 35,
+ minimumProfitPercentage: 43.75,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ indicators: {
highestPrice: 10000,
lowestPrice: 8893.03,
athPrice: 9000
- });
- }
-
- if (
- hash === 'trailing-trade-symbols' &&
- key === 'BTCUSDT-latest-candle'
- ) {
- return JSON.stringify({
+ },
+ lastCandle: {
symbol: 'BTCUSDT',
close: '15555.09000000'
- });
- }
-
- return null;
- });
-
- step = require('../get-indicators');
-
- rawData = {
- symbol: 'BTCUSDT',
- symbolInfo: {
- filterMinNotional: { minNotional: '10.000' }
- },
- symbolConfiguration: {
+ },
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
- athRestriction: {
- enabled: true,
- restrictionPercentage: 0.9
- }
+ currentPrice: 15555.09,
+ limitPrice: 15881.746889999999,
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000,
+ athRestrictionPrice: 8100,
+ triggerPrice: 8981.9603,
+ difference: 73.18146017634923,
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ updatedAt: expect.any(Object)
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: -1.37423868741684,
+ differenceToExecute: -3.5030976998525976,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ processMessage: '',
+ updatedAt: expect.any(Object)
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
- stopLoss: { maxLossPercentage: 0.8 }
+ currentPrice: 15555.09,
+ limitPrice: 15228.43311,
+ lastBuyPrice: 9000,
+ triggerPrice: 9540,
+ difference: 38.669593039963125,
+ currentProfit: 655.509,
+ currentProfitPercentage: 42.14112550939918,
+ stopLossDifference: 53.712900407519335,
+ stopLossTriggerPrice: 7200,
+ openOrders: [
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: -4.40995396669539,
+ differenceToExecute: -2.2173449333947826,
+ minimumProfit: 35,
+ minimumProfitPercentage: 43.75,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ processMessage: '',
+ updatedAt: expect.any(Object)
}
- },
- baseAssetBalance: { total: 0.1 },
- openOrders: [
- {
- orderId: 1,
- symbol: 'BTCUSDT',
- type: 'LIMIT',
- side: 'BUY',
- price: '13000.000',
- origQty: '0.005',
- time: 1615465601162
- },
- {
- orderId: 2,
- symbol: 'BTCUSDT',
- type: 'STOP_LOSS_LIMIT',
- side: 'BUY',
- price: '16000.000',
- origQty: '0.005',
- stopPrice: '16100.000',
- time: 1615465601162
- },
- {
- orderId: 3,
- symbol: 'BTCUSDT',
- type: 'STOP_LOSS_LIMIT',
- side: 'SELL',
- price: '16000.000',
- origQty: '0.005',
- stopPrice: '15900.000',
- time: 1615465601162
+ });
+ });
+ });
+
+ describe('when buy grid trade index is 1', () => {
+ beforeEach(async () => {
+ const { cache, logger } = require('../../../../helpers');
+ cacheMock = cache;
+ loggerMock = logger;
+
+ mockGetLastBuyPrice = jest
+ .fn()
+ .mockResolvedValue({ lastBuyPrice: 9000, quantity: 1 });
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getLastBuyPrice: mockGetLastBuyPrice
+ }));
+
+ cacheMock.hget = jest.fn().mockImplementation((hash, key) => {
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-indicator-data'
+ ) {
+ return JSON.stringify({
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ });
}
- ]
- };
- result = await step.execute(logger, rawData);
- });
+ if (
+ hash === 'trailing-trade-symbols' &&
+ key === 'BTCUSDT-latest-candle'
+ ) {
+ return JSON.stringify({
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ });
+ }
- it('triggers getLastBuyPrice', () => {
- expect(mockGetLastBuyPrice).toHaveBeenCalledWith(loggerMock, 'BTCUSDT');
- });
+ return null;
+ });
- it('triggers expected value', () => {
- expect(result).toStrictEqual({
- symbol: 'BTCUSDT',
- symbolInfo: {
- filterMinNotional: { minNotional: '10.000' }
- },
- symbolConfiguration: {
- buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
- athRestriction: {
- enabled: true,
- restrictionPercentage: 0.9
+ step = require('../get-indicators');
+
+ rawData = {
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: { maxLossPercentage: 0.8 }
}
},
- sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
- stopLoss: {
- maxLossPercentage: 0.8
+ baseAssetBalance: { total: 0.1 },
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162
+ },
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162
}
- }
- },
- baseAssetBalance: {
- total: 0.1,
- estimatedValue: 1555.509,
- isLessThanMinNotionalValue: false
- },
- openOrders: [
- {
- orderId: 1,
- symbol: 'BTCUSDT',
- type: 'LIMIT',
- side: 'BUY',
- price: '13000.000',
- origQty: '0.005',
- time: 1615465601162,
- currentPrice: 15555.09,
- updatedAt: expect.any(Object)
+ ]
+ };
+
+ result = await step.execute(logger, rawData);
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mockGetLastBuyPrice).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers expected value', () => {
+ expect(result).toStrictEqual({
+ symbol: 'BTCUSDT',
+ symbolInfo: {
+ filterMinNotional: { minNotional: '10.000' }
},
- {
- orderId: 2,
- symbol: 'BTCUSDT',
- type: 'STOP_LOSS_LIMIT',
- side: 'BUY',
- price: '16000.000',
- origQty: '0.005',
- stopPrice: '16100.000',
- time: 1615465601162,
- currentPrice: 15555.09,
- limitPrice: 15881.746889999999,
- limitPercentage: 1.021,
- differenceToExecute: -3.5030976998525976,
- differenceToCancel: -1.37423868741684,
- updatedAt: expect.any(Object)
+ symbolConfiguration: {
+ buy: {
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
+ athRestriction: {
+ enabled: true,
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
+ stopLoss: {
+ maxLossPercentage: 0.8
+ }
+ }
+ },
+ baseAssetBalance: {
+ total: 0.1,
+ estimatedValue: 1555.509,
+ isLessThanMinNotionalValue: false
},
- {
- orderId: 3,
- symbol: 'BTCUSDT',
- type: 'STOP_LOSS_LIMIT',
- side: 'SELL',
- price: '16000.000',
- origQty: '0.005',
- stopPrice: '15900.000',
- time: 1615465601162,
- currentPrice: 15555.09,
- limitPrice: 15228.43311,
- limitPercentage: 0.979,
- differenceToExecute: -2.2173449333947826,
- differenceToCancel: -4.40995396669539,
- minimumProfit: 35,
- minimumProfitPercentage: 43.75,
- updatedAt: expect.any(Object)
- }
- ],
- indicators: {
- highestPrice: 10000,
- lowestPrice: 8893.03,
- athPrice: 9000
- },
- lastCandle: {
- symbol: 'BTCUSDT',
- close: '15555.09000000'
- },
- buy: {
- currentPrice: 15555.09,
- limitPrice: 15881.746889999999,
- highestPrice: 10000,
- lowestPrice: 8893.03,
- athPrice: 9000,
- athRestrictionPrice: 8100,
- triggerPrice: 8981.9603,
- difference: 73.18146017634923,
openOrders: [
{
orderId: 1,
@@ -507,27 +1449,10 @@ describe('get-indicators.js', () => {
stopPrice: '16100.000',
time: 1615465601162,
currentPrice: 15555.09,
- limitPrice: 15881.746889999999,
- limitPercentage: 1.021,
- differenceToExecute: -3.5030976998525976,
differenceToCancel: -1.37423868741684,
+ differenceToExecute: -3.5030976998525976,
updatedAt: expect.any(Object)
- }
- ],
- processMessage: '',
- updatedAt: expect.any(Object)
- },
- sell: {
- currentPrice: 15555.09,
- limitPrice: 15228.43311,
- lastBuyPrice: 9000,
- triggerPrice: 9540,
- difference: 38.669593039963125,
- currentProfit: 655.509,
- currentProfitPercentage: 42.14112550939918,
- stopLossDifference: 53.712900407519335,
- stopLossTriggerPrice: 7200,
- openOrders: [
+ },
{
orderId: 3,
symbol: 'BTCUSDT',
@@ -538,18 +1463,93 @@ describe('get-indicators.js', () => {
stopPrice: '15900.000',
time: 1615465601162,
currentPrice: 15555.09,
- limitPrice: 15228.43311,
- limitPercentage: 0.979,
- differenceToExecute: -2.2173449333947826,
differenceToCancel: -4.40995396669539,
+ differenceToExecute: -2.2173449333947826,
minimumProfit: 35,
minimumProfitPercentage: 43.75,
updatedAt: expect.any(Object)
}
],
- processMessage: '',
- updatedAt: expect.any(Object)
- }
+ indicators: {
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000
+ },
+ lastCandle: {
+ symbol: 'BTCUSDT',
+ close: '15555.09000000'
+ },
+ buy: {
+ currentPrice: 15555.09,
+ limitPrice: 15881.746889999999,
+ highestPrice: 10000,
+ lowestPrice: 8893.03,
+ athPrice: 9000,
+ athRestrictionPrice: 8100,
+ triggerPrice: 9090,
+ difference: 71.12310231023102,
+ openOrders: [
+ {
+ orderId: 1,
+ symbol: 'BTCUSDT',
+ type: 'LIMIT',
+ side: 'BUY',
+ price: '13000.000',
+ origQty: '0.005',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ updatedAt: expect.any(Object)
+ },
+ {
+ orderId: 2,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'BUY',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '16100.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: -1.37423868741684,
+ differenceToExecute: -3.5030976998525976,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ },
+ sell: {
+ currentPrice: 15555.09,
+ limitPrice: 15228.43311,
+ lastBuyPrice: 9000,
+ triggerPrice: 9540,
+ difference: 38.669593039963125,
+ currentProfit: 655.509,
+ currentProfitPercentage: 42.14112550939918,
+ stopLossDifference: 53.712900407519335,
+ stopLossTriggerPrice: 7200,
+ openOrders: [
+ {
+ orderId: 3,
+ symbol: 'BTCUSDT',
+ type: 'STOP_LOSS_LIMIT',
+ side: 'SELL',
+ price: '16000.000',
+ origQty: '0.005',
+ stopPrice: '15900.000',
+ time: 1615465601162,
+ currentPrice: 15555.09,
+ differenceToCancel: -4.40995396669539,
+ differenceToExecute: -2.2173449333947826,
+ minimumProfit: 35,
+ minimumProfitPercentage: 43.75,
+ updatedAt: expect.any(Object)
+ }
+ ],
+ processMessage: '',
+ updatedAt: expect.any(Object)
+ }
+ });
});
});
});
@@ -598,16 +1598,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
@@ -658,16 +1663,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: {
maxLossPercentage: 0.8
}
@@ -700,8 +1710,6 @@ describe('get-indicators.js', () => {
stopPrice: '16100.000',
time: 1615465601162,
currentPrice: 15555.09,
- limitPrice: 15881.746889999999,
- limitPercentage: 1.021,
differenceToExecute: -3.5030976998525976,
differenceToCancel: -1.37423868741684,
updatedAt: expect.any(Object)
@@ -716,10 +1724,8 @@ describe('get-indicators.js', () => {
stopPrice: '15900.000',
time: 1615465601162,
currentPrice: 15555.09,
- limitPrice: 15228.43311,
- limitPercentage: 0.979,
differenceToExecute: -2.2173449333947826,
- differenceToCancel: -4.40995396669539,
+ differenceToCancel: null,
minimumProfit: null,
minimumProfitPercentage: null,
updatedAt: expect.any(Object)
@@ -765,8 +1771,6 @@ describe('get-indicators.js', () => {
stopPrice: '16100.000',
time: 1615465601162,
currentPrice: 15555.09,
- limitPrice: 15881.746889999999,
- limitPercentage: 1.021,
differenceToExecute: -3.5030976998525976,
differenceToCancel: -1.37423868741684,
updatedAt: expect.any(Object)
@@ -777,7 +1781,7 @@ describe('get-indicators.js', () => {
},
sell: {
currentPrice: 15555.09,
- limitPrice: 15228.43311,
+ limitPrice: null,
lastBuyPrice: null,
triggerPrice: null,
difference: null,
@@ -796,10 +1800,8 @@ describe('get-indicators.js', () => {
stopPrice: '15900.000',
time: 1615465601162,
currentPrice: 15555.09,
- limitPrice: 15228.43311,
- limitPercentage: 0.979,
differenceToExecute: -2.2173449333947826,
- differenceToCancel: -4.40995396669539,
+ differenceToCancel: null,
minimumProfit: null,
minimumProfitPercentage: null,
updatedAt: expect.any(Object)
@@ -857,16 +1859,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.011,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.011
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 0.99,
- limitPercentage: 0.98,
+ currentGridTrade: {
+ triggerPercentage: 0.99,
+ limitPercentage: 0.98
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
@@ -893,16 +1900,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.011,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.011
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 0.99,
- limitPercentage: 0.98,
+ currentGridTrade: {
+ triggerPercentage: 0.99,
+ limitPercentage: 0.98
+ },
stopLoss: {
maxLossPercentage: 0.8
}
@@ -938,7 +1950,7 @@ describe('get-indicators.js', () => {
},
sell: {
currentPrice: 15555.09,
- limitPrice: 15243.9882,
+ limitPrice: null,
lastBuyPrice: null,
triggerPrice: null,
difference: null,
@@ -988,16 +2000,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
@@ -1016,16 +2033,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
@@ -1069,16 +2091,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
@@ -1097,16 +2124,21 @@ describe('get-indicators.js', () => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: 1.01,
- limitPercentage: 1.021,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.01,
+ limitPercentage: 1.021
+ },
athRestriction: {
enabled: true,
restrictionPercentage: 0.9
}
},
sell: {
- triggerPercentage: 1.06,
- limitPercentage: 0.979,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ limitPercentage: 0.979
+ },
stopLoss: { maxLossPercentage: 0.8 }
}
},
diff --git a/app/cronjob/trailingTrade/step/__tests__/get-override-action.test.js b/app/cronjob/trailingTrade/step/__tests__/get-override-action.test.js
index ba820555..3f139473 100644
--- a/app/cronjob/trailingTrade/step/__tests__/get-override-action.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/get-override-action.test.js
@@ -183,6 +183,54 @@ describe('get-override-action.js', () => {
});
});
+ describe('when action is buy', () => {
+ beforeEach(async () => {
+ const { logger } = require('../../../../helpers');
+
+ loggerMock = logger;
+
+ mockGetOverrideDataForSymbol = jest.fn().mockResolvedValue({
+ action: 'buy'
+ });
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getOverrideDataForSymbol: mockGetOverrideDataForSymbol,
+ removeOverrideDataForSymbol: mockRemoveOverrideDataForSymbol
+ }));
+
+ rawData = {
+ action: 'not-determined',
+ symbol: 'BTCUSDT',
+ isLocked: false
+ };
+
+ const step = require('../get-override-action');
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers getOverrideDataForSymbol', () => {
+ expect(mockGetOverrideDataForSymbol).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers removeOverrideDataForSymbol', () => {
+ expect(mockRemoveOverrideDataForSymbol).toHaveBeenCalledWith(
+ loggerMock,
+ 'BTCUSDT'
+ );
+ });
+
+ it('retruns expected result', () => {
+ expect(result).toStrictEqual({
+ action: 'buy',
+ symbol: 'BTCUSDT',
+ isLocked: false,
+ order: {}
+ });
+ });
+ });
+
describe('when action is not matching', () => {
beforeEach(async () => {
const { logger } = require('../../../../helpers');
diff --git a/app/cronjob/trailingTrade/step/__tests__/place-buy-order.test.js b/app/cronjob/trailingTrade/step/__tests__/place-buy-order.test.js
index 13e604bf..c7122416 100644
--- a/app/cronjob/trailingTrade/step/__tests__/place-buy-order.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/place-buy-order.test.js
@@ -13,6 +13,7 @@ describe('place-buy-order.js', () => {
let mockGetAccountInfoFromAPI;
let mockIsExceedAPILimit;
let mockGetAPILimit;
+ let mockSaveOrder;
describe('execute', () => {
beforeEach(() => {
@@ -41,6 +42,7 @@ describe('place-buy-order.js', () => {
mockIsExceedAPILimit = jest.fn().mockReturnValue(false);
mockGetAPILimit = jest.fn().mockResolvedValue(10);
+ mockSaveOrder = jest.fn().mockResolvedValue(true);
});
describe('when symbol is locked', () => {
@@ -54,7 +56,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -62,6 +65,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCUPUSDT',
isLocked: true,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -72,9 +78,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'not-determined',
@@ -97,6 +112,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual(rawData);
});
@@ -113,7 +132,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -121,6 +141,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCUPUSDT',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -131,9 +154,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'not-determined',
@@ -156,6 +188,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual(rawData);
});
@@ -172,7 +208,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -180,6 +217,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCUPUSDT',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -190,9 +230,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -227,6 +276,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -244,7 +297,90 @@ describe('place-buy-order.js', () => {
}
],
processMessage:
- 'There are open orders for BTCUPUSDT. Do not place an order.',
+ 'There are open orders for BTCUPUSDT. Do not place an order for the grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
+ });
+
+ describe('when current grid trade is not defined', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([]);
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'BTCUPUSDT',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'BTCUP',
+ quoteAsset: 'USDT',
+ filterLotSize: { stepSize: '0.01000000' },
+ filterPrice: { tickSize: '0.00100000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: -1,
+ currentGridTrade: null
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 0 },
+ buy: {
+ currentPrice: 200,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('does not trigger binance.client.order', () => {
+ expect(binanceMock.client.order).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ buy: {
+ currentPrice: 200,
+ openOrders: [],
+ processMessage:
+ 'Current grid trade is not defined. Cannot place an order.',
updatedAt: expect.any(Object)
}
}
@@ -263,7 +399,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -271,6 +408,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCUPUSDT',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -281,9 +421,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: -1,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: -1,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -309,6 +458,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -337,7 +490,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -345,6 +499,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCUPUSDT',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -355,9 +512,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -383,6 +549,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -391,7 +561,7 @@ describe('place-buy-order.js', () => {
currentPrice: 200,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough USDT to buy BTCUP.',
+ 'Do not place a buy order for the grid trade #1 as not enough USDT to buy BTCUP.',
updatedAt: expect.any(Object)
}
}
@@ -410,7 +580,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -418,6 +589,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'ETHBTC',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'ETH',
quoteAsset: 'BTC',
@@ -428,9 +602,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 0.001,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -456,6 +639,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -464,7 +651,7 @@ describe('place-buy-order.js', () => {
currentPrice: 0.044866,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough BTC to buy ETH.',
+ 'Do not place a buy order for the grid trade #1 as not enough BTC to buy ETH.',
updatedAt: expect.any(Object)
}
}
@@ -483,7 +670,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -491,6 +679,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'ALPHABTC',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'ALPHA',
quoteAsset: 'BTC',
@@ -501,9 +692,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 0.001,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -529,6 +729,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -537,7 +741,7 @@ describe('place-buy-order.js', () => {
currentPrice: 0.00003771,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough BTC to buy ALPHA.',
+ 'Do not place a buy order for the grid trade #1 as not enough BTC to buy ALPHA.',
updatedAt: expect.any(Object)
}
}
@@ -556,7 +760,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -564,6 +769,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCBRL',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTC',
quoteAsset: 'BRL',
@@ -574,9 +782,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -602,6 +819,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -610,7 +831,7 @@ describe('place-buy-order.js', () => {
currentPrice: 268748,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough BRL to buy BTC.',
+ 'Do not place a buy order for the grid trade #1 as not enough BRL to buy BTC.',
updatedAt: expect.any(Object)
}
}
@@ -631,7 +852,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -639,6 +861,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCUPUSDT',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -649,9 +874,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -677,6 +911,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -685,7 +923,9 @@ describe('place-buy-order.js', () => {
currentPrice: 200,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough USDT to buy BTCUP after calculation.',
+ `Do not place a buy order for the grid trade #1 as not enough ` +
+ `USDT to buy BTCUP after calculating commission - ` +
+ `Order amount: 8.088 USDT, Minimum notional: 10.00000000.`,
updatedAt: expect.any(Object)
}
}
@@ -704,7 +944,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -712,6 +953,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'ETHBTC',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'ETH',
quoteAsset: 'BTC',
@@ -722,9 +966,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 0.001,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -750,6 +1003,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -758,7 +1015,9 @@ describe('place-buy-order.js', () => {
currentPrice: 0.044866,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough BTC to buy ETH after calculation.',
+ `Do not place a buy order for the grid trade #1 ` +
+ `as not enough BTC to buy ETH after calculating commission - ` +
+ `Order amount: 0.00009 BTC, Minimum notional: 0.00010000.`,
updatedAt: expect.any(Object)
}
}
@@ -777,7 +1036,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -785,6 +1045,9 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'ALPHABTC',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'ALPHA',
quoteAsset: 'BTC',
@@ -795,9 +1058,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 0.001,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -823,6 +1095,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -831,7 +1107,9 @@ describe('place-buy-order.js', () => {
currentPrice: 0.00003771,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough BTC to buy ALPHA after calculation.',
+ `Do not place a buy order for the grid trade #1 ` +
+ `as not enough BTC to buy ALPHA after calculating commission - ` +
+ `Order amount: 0.00007624 BTC, Minimum notional: 0.00010000.`,
updatedAt: expect.any(Object)
}
}
@@ -850,7 +1128,8 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
@@ -858,9 +1137,12 @@ describe('place-buy-order.js', () => {
rawData = {
symbol: 'BTCBRL',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTC',
- quoteAsset: 'USDT',
+ quoteAsset: 'BRL',
filterLotSize: { stepSize: '0.00000100', minQty: '0.00000100' },
filterPrice: { tickSize: '1.00000000' },
filterMinNotional: { minNotional: '10.00000000' }
@@ -868,9 +1150,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -896,6 +1187,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -904,7 +1199,9 @@ describe('place-buy-order.js', () => {
currentPrice: 268748,
openOrders: [],
processMessage:
- 'Do not place a buy order as not enough USDT to buy BTC after calculation.',
+ `Do not place a buy order for the grid trade #1 as not enough ` +
+ `BRL to buy BTC after calculating commission - Order amount: ` +
+ `9 BRL, Minimum notional: 10.00000000.`,
updatedAt: expect.any(Object)
}
}
@@ -924,13 +1221,17 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
rawData = {
symbol: 'BTCUPUSDT',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -941,9 +1242,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: false,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -969,6 +1279,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -977,7 +1291,7 @@ describe('place-buy-order.js', () => {
currentPrice: 200,
openOrders: [],
processMessage:
- 'Trading for BTCUPUSDT is disabled. Do not place an order.',
+ 'Trading for BTCUPUSDT is disabled. Do not place an order for the grid trade #1.',
updatedAt: expect.any(Object)
}
}
@@ -998,13 +1312,17 @@ describe('place-buy-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-buy-order');
rawData = {
symbol: 'BTCUPUSDT',
isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
symbolInfo: {
baseAsset: 'BTCUP',
quoteAsset: 'USDT',
@@ -1015,9 +1333,18 @@ describe('place-buy-order.js', () => {
symbolConfiguration: {
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'buy',
@@ -1043,6 +1370,10 @@ describe('place-buy-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1060,128 +1391,161 @@ describe('place-buy-order.js', () => {
});
describe('when has enough balance', () => {
- describe('BTCUPUSDT', () => {
- beforeEach(async () => {
- mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
- {
- orderId: 123,
+ describe('when max purchase amount is exactly same as minimum notional value', () => {
+ describe('BTCUPUSDT', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 202.2,
+ quantity: 0.05,
+ side: 'buy',
+ stopPrice: 202,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'BTCUPUSDT',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'BTCUP',
+ quoteAsset: 'USDT',
+ filterLotSize: { stepSize: '0.01000000', minQty: '0.01000000' },
+ filterPrice: { tickSize: '0.00100000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 50 },
+ buy: {
+ currentPrice: 200,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
price: 202.2,
- quantity: 0.24,
+ quantity: 0.05,
side: 'buy',
stopPrice: 202,
symbol: 'BTCUPUSDT',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
- }
- ]);
- mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
- account: 'info'
+ });
});
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
- }));
-
- const step = require('../place-buy-order');
-
- rawData = {
- symbol: 'BTCUPUSDT',
- isLocked: false,
- symbolInfo: {
- baseAsset: 'BTCUP',
- quoteAsset: 'USDT',
- filterLotSize: { stepSize: '0.01000000', minQty: '0.01000000' },
- filterPrice: { tickSize: '0.00100000' },
- filterMinNotional: { minNotional: '10.00000000' }
- },
- symbolConfiguration: {
- buy: {
- enabled: true,
- maxPurchaseAmount: 50,
- stopPercentage: 1.01,
- limitPercentage: 1.011
- }
- },
- action: 'buy',
- quoteAssetBalance: { free: 101 },
- buy: {
- currentPrice: 200,
- openOrders: []
- }
- };
-
- result = await step.execute(loggerMock, rawData);
- });
-
- it('triggers binance.client.order', () => {
- expect(binanceMock.client.order).toHaveBeenCalledWith({
- price: 202.2,
- quantity: 0.24,
- side: 'buy',
- stopPrice: 202,
- symbol: 'BTCUPUSDT',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCUPUSDT-last-buy-order',
+ JSON.stringify({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
});
- });
- it('triggers mongo.upsertOne', () => {
- expect(mongoMock.upsertOne).toHaveBeenCalledWith(
- loggerMock,
- 'trailing-trade-symbols',
- {
- key: 'BTCUPUSDT-last-buy-price'
- },
- {
- key: 'BTCUPUSDT-last-buy-price',
- lastBuyPrice: 202.2,
- quantity: 0.24
- }
- );
- });
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCUPUSDT-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
- it('triggers cache.set', () => {
- expect(cacheMock.set).toHaveBeenCalledWith(
- 'BTCUPUSDT-last-buy-order',
- 'true',
- 120
- );
- });
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
- it('triggers getAndCacheOpenOrdersForSymbol', () => {
- expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
- });
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
- it('triggers getAccountInfoFromAPI', () => {
- expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
- });
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
+ }
+ });
+ });
- it('retruns expected value', () => {
- expect(result).toStrictEqual({
- ...rawData,
- ...{
- openOrders: [
- {
- orderId: 123,
- price: 202.2,
- quantity: 0.24,
- side: 'buy',
- stopPrice: 202,
- symbol: 'BTCUPUSDT',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
- }
- ],
- buy: {
- currentPrice: 200,
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
openOrders: [
{
orderId: 123,
price: 202.2,
- quantity: 0.24,
+ quantity: 0.05,
side: 'buy',
stopPrice: 202,
symbol: 'BTCUPUSDT',
@@ -1189,268 +1553,1282 @@ describe('place-buy-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
],
- processMessage: 'Placed new stop loss limit order for buying.',
- updatedAt: expect.any(Object)
+ buy: {
+ currentPrice: 200,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 202.2,
+ quantity: 0.05,
+ side: 'buy',
+ stopPrice: 202,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
}
- }
+ });
});
});
- });
- describe('ETHBTC', () => {
- beforeEach(async () => {
- mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
- {
- orderId: 456,
+ describe('ETHBTC', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 456,
+ price: 0.045359,
+ quantity: 0.003,
+ side: 'buy',
+ stopPrice: 0.045314,
+ symbol: 'ETHBTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'ETHBTC',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'ETH',
+ quoteAsset: 'BTC',
+ filterLotSize: { stepSize: '0.00100000', minQty: '0.00100000' },
+ filterPrice: { tickSize: '0.00000100' },
+ filterMinNotional: { minNotional: '0.00010000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.0001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 0.002 },
+ buy: {
+ currentPrice: 0.044866,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
price: 0.045359,
- quantity: 0.022,
+ quantity: 0.003,
side: 'buy',
stopPrice: 0.045314,
symbol: 'ETHBTC',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
- }
- ]);
- mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
- account: 'info'
+ });
});
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
- }));
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'ETHBTC-last-buy-order',
+ JSON.stringify({
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
+ });
- const step = require('../place-buy-order');
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'ETHBTC-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
- rawData = {
- symbol: 'ETHBTC',
- isLocked: false,
- symbolInfo: {
- baseAsset: 'ETH',
- quoteAsset: 'BTC',
- filterLotSize: { stepSize: '0.00100000', minQty: '0.00100000' },
- filterPrice: { tickSize: '0.00000100' },
- filterMinNotional: { minNotional: '0.00010000' }
- },
- symbolConfiguration: {
- buy: {
- enabled: true,
- maxPurchaseAmount: 0.001,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
}
- },
- action: 'buy',
- quoteAssetBalance: { free: 0.002 },
- buy: {
- currentPrice: 0.044866,
- openOrders: []
- }
- };
+ });
+ });
- result = await step.execute(loggerMock, rawData);
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 456,
+ price: 0.045359,
+ quantity: 0.003,
+ side: 'buy',
+ stopPrice: 0.045314,
+ symbol: 'ETHBTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ buy: {
+ currentPrice: 0.044866,
+ openOrders: [
+ {
+ orderId: 456,
+ price: 0.045359,
+ quantity: 0.003,
+ side: 'buy',
+ stopPrice: 0.045314,
+ symbol: 'ETHBTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
- it('triggers binance.client.order', () => {
- expect(binanceMock.client.order).toHaveBeenCalledWith({
- price: 0.045359,
- quantity: 0.022,
- side: 'buy',
- stopPrice: 0.045314,
- symbol: 'ETHBTC',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ describe('ALPHABTC', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 456,
+ price: 0.00003812,
+ quantity: 3,
+ side: 'buy',
+ stopPrice: 0.00003808,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'ALPHABTC',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'ALPHA',
+ quoteAsset: 'BTC',
+ filterLotSize: { stepSize: '1.00000000', minQty: '1.00000000' },
+ filterPrice: { tickSize: '0.00000001' },
+ filterMinNotional: { minNotional: '0.00010000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.0001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 0.002 },
+ buy: {
+ currentPrice: 0.00003771,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
});
- });
- it('triggers mongo.upsertOne', () => {
- expect(mongoMock.upsertOne).toHaveBeenCalledWith(
- loggerMock,
- 'trailing-trade-symbols',
- {
- key: 'ETHBTC-last-buy-price'
- },
- {
- key: 'ETHBTC-last-buy-price',
- lastBuyPrice: 0.045359,
- quantity: 0.022
- }
- );
- });
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 0.00003812,
+ quantity: 3,
+ side: 'buy',
+ stopPrice: 0.00003808,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
- it('triggers cache.set', () => {
- expect(cacheMock.set).toHaveBeenCalledWith(
- 'ETHBTC-last-buy-order',
- 'true',
- 120
- );
- });
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'ALPHABTC-last-buy-order',
+ JSON.stringify({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
+ });
+
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'ALPHABTC-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
- it('triggers getAndCacheOpenOrdersForSymbol', () => {
- expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
+ }
+ });
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 456,
+ price: 0.00003812,
+ quantity: 3,
+ side: 'buy',
+ stopPrice: 0.00003808,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ buy: {
+ currentPrice: 0.00003771,
+ openOrders: [
+ {
+ orderId: 456,
+ price: 0.00003812,
+ quantity: 3,
+ side: 'buy',
+ stopPrice: 0.00003808,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
- it('triggers getAccountInfoFromAPI', () => {
- expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ describe('BTCBRL', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 456,
+ price: 271704,
+ quantity: 0.000037,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'BTCBRL',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'BTC',
+ quoteAsset: 'BRL',
+ filterLotSize: { stepSize: '0.00000100', minQty: '0.00000100' },
+ filterPrice: { tickSize: '1.00000000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 10,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 15 },
+ buy: {
+ currentPrice: 268748,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 271704,
+ quantity: 0.000037,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
+
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCBRL-last-buy-order',
+ JSON.stringify({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
+ });
+
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCBRL-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
+ }
+ });
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 456,
+ price: 271704,
+ quantity: 0.000037,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ buy: {
+ currentPrice: 268748,
+ openOrders: [
+ {
+ orderId: 456,
+ price: 271704,
+ quantity: 0.000037,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
- it('retruns expected value', () => {
- expect(result).toStrictEqual({
- ...rawData,
- ...{
- openOrders: [
- {
- orderId: 456,
- price: 0.045359,
- quantity: 0.022,
- side: 'buy',
- stopPrice: 0.045314,
- symbol: 'ETHBTC',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ describe('BNBUSDT', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 456,
+ price: 271704,
+ quantity: 0.000037,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BNBUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BNBUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'BNBUSDT',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'BNB',
+ quoteAsset: 'USDT',
+ filterLotSize: { stepSize: '0.00010000', minQty: '0.00010000' },
+ filterPrice: { tickSize: '0.01000000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 1,
+ currentGridTrade: {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
- ],
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 100 },
buy: {
- currentPrice: 0.044866,
+ currentPrice: 289.48,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 297,
+ quantity: 0.0338,
+ side: 'buy',
+ stopPrice: 296.71,
+ symbol: 'BNBUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
+
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BNBUSDT-last-buy-order',
+ JSON.stringify({
+ symbol: 'BNBUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
+ });
+
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BNBUSDT-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BNBUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 1,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BNBUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
+ }
+ });
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
openOrders: [
{
orderId: 456,
- price: 0.045359,
- quantity: 0.022,
+ price: 271704,
+ quantity: 0.000037,
side: 'buy',
- stopPrice: 0.045314,
- symbol: 'ETHBTC',
+ stopPrice: 271435,
+ symbol: 'BNBUSDT',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
}
],
- processMessage: 'Placed new stop loss limit order for buying.',
- updatedAt: expect.any(Object)
+ buy: {
+ currentPrice: 289.48,
+ openOrders: [
+ {
+ orderId: 456,
+ price: 271704,
+ quantity: 0.000037,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BNBUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #2.',
+ updatedAt: expect.any(Object)
+ }
}
- }
+ });
});
});
});
- describe('ALPHABTC', () => {
- beforeEach(async () => {
- mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
- {
- orderId: 456,
- price: 0.00003812,
- quantity: 26,
+ describe('when max purchase amount is not same as minimum notional value', () => {
+ describe('BTCUPUSDT', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 202.2,
+ quantity: 0.24,
+ side: 'buy',
+ stopPrice: 202,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'BTCUPUSDT',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'BTCUP',
+ quoteAsset: 'USDT',
+ filterLotSize: { stepSize: '0.01000000', minQty: '0.01000000' },
+ filterPrice: { tickSize: '0.00100000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 50,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 101 },
+ buy: {
+ currentPrice: 200,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 202.2,
+ quantity: 0.24,
side: 'buy',
- stopPrice: 0.00003808,
- symbol: 'ALPHABTC',
+ stopPrice: 202,
+ symbol: 'BTCUPUSDT',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
- }
- ]);
- mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
- account: 'info'
+ });
});
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
- }));
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCUPUSDT-last-buy-order',
+ JSON.stringify({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
+ });
- const step = require('../place-buy-order');
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCUPUSDT-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
- rawData = {
- symbol: 'ALPHABTC',
- isLocked: false,
- symbolInfo: {
- baseAsset: 'ALPHA',
- quoteAsset: 'BTC',
- filterLotSize: { stepSize: '1.00000000', minQty: '1.00000000' },
- filterPrice: { tickSize: '0.00000001' },
- filterMinNotional: { minNotional: '0.00010000' }
- },
- symbolConfiguration: {
- buy: {
- enabled: true,
- maxPurchaseAmount: 0.001,
- stopPercentage: 1.01,
- limitPercentage: 1.011
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
}
- },
- action: 'buy',
- quoteAssetBalance: { free: 0.002 },
- buy: {
- currentPrice: 0.00003771,
- openOrders: []
- }
- };
+ });
+ });
- result = await step.execute(loggerMock, rawData);
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 123,
+ price: 202.2,
+ quantity: 0.24,
+ side: 'buy',
+ stopPrice: 202,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ buy: {
+ currentPrice: 200,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 202.2,
+ quantity: 0.24,
+ side: 'buy',
+ stopPrice: 202,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
- it('triggers binance.client.order', () => {
- expect(binanceMock.client.order).toHaveBeenCalledWith({
- price: 0.00003812,
- quantity: 26,
- side: 'buy',
- stopPrice: 0.00003808,
- symbol: 'ALPHABTC',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ describe('ETHBTC', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 456,
+ price: 0.045359,
+ quantity: 0.022,
+ side: 'buy',
+ stopPrice: 0.045314,
+ symbol: 'ETHBTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'ETHBTC',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: true
+ },
+ symbolInfo: {
+ baseAsset: 'ETH',
+ quoteAsset: 'BTC',
+ filterLotSize: { stepSize: '0.00100000', minQty: '0.00100000' },
+ filterPrice: { tickSize: '0.00000100' },
+ filterMinNotional: { minNotional: '0.00010000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 0.002 },
+ buy: {
+ currentPrice: 0.044866,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
});
- });
- it('triggers cache.set', () => {
- expect(cacheMock.set).toHaveBeenCalledWith(
- 'ALPHABTC-last-buy-order',
- 'true',
- 120
- );
- });
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 0.045359,
+ quantity: 0.022,
+ side: 'buy',
+ stopPrice: 0.045314,
+ symbol: 'ETHBTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
- it('triggers mongo.upsertOne', () => {
- expect(mongoMock.upsertOne).toHaveBeenCalledWith(
- loggerMock,
- 'trailing-trade-symbols',
- {
- key: 'ALPHABTC-last-buy-price'
- },
- {
- key: 'ALPHABTC-last-buy-price',
- lastBuyPrice: 0.00003812,
- quantity: 26
- }
- );
- });
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'ETHBTC-last-buy-order',
+ JSON.stringify({
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
+ });
- it('triggers getAndCacheOpenOrdersForSymbol', () => {
- expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
- });
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'ETHBTC-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ETHBTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
+ }
+ });
+ });
- it('triggers getAccountInfoFromAPI', () => {
- expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 456,
+ price: 0.045359,
+ quantity: 0.022,
+ side: 'buy',
+ stopPrice: 0.045314,
+ symbol: 'ETHBTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ buy: {
+ currentPrice: 0.044866,
+ openOrders: [
+ {
+ orderId: 456,
+ price: 0.045359,
+ quantity: 0.022,
+ side: 'buy',
+ stopPrice: 0.045314,
+ symbol: 'ETHBTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
- it('retruns expected value', () => {
- expect(result).toStrictEqual({
- ...rawData,
- ...{
- openOrders: [
- {
- orderId: 456,
- price: 0.00003812,
- quantity: 26,
- side: 'buy',
- stopPrice: 0.00003808,
- symbol: 'ALPHABTC',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ describe('ALPHABTC', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 456,
+ price: 0.00003812,
+ quantity: 26,
+ side: 'buy',
+ stopPrice: 0.00003808,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'ALPHABTC',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: false
+ },
+ symbolInfo: {
+ baseAsset: 'ALPHA',
+ quoteAsset: 'BTC',
+ filterLotSize: { stepSize: '1.00000000', minQty: '1.00000000' },
+ filterPrice: { tickSize: '0.00000001' },
+ filterMinNotional: { minNotional: '0.00010000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 0.001,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
- ],
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 0.002 },
buy: {
currentPrice: 0.00003771,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 0.00003812,
+ quantity: 26,
+ side: 'buy',
+ stopPrice: 0.00003808,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
+
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'ALPHABTC-last-buy-order',
+ JSON.stringify({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
+ });
+
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'ALPHABTC-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
+ }
+ });
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
openOrders: [
{
orderId: 456,
@@ -1463,19 +2841,108 @@ describe('place-buy-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
],
- processMessage: 'Placed new stop loss limit order for buying.',
- updatedAt: expect.any(Object)
+ buy: {
+ currentPrice: 0.00003771,
+ openOrders: [
+ {
+ orderId: 456,
+ price: 0.00003812,
+ quantity: 26,
+ side: 'buy',
+ stopPrice: 0.00003808,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
}
- }
+ });
});
});
- });
- describe('BTCBRL', () => {
- beforeEach(async () => {
- mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
- {
- orderId: 456,
+ describe('BTCBRL', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 456,
+ price: 271704,
+ quantity: 0.00004,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-buy-order');
+
+ rawData = {
+ symbol: 'BTCBRL',
+ isLocked: false,
+ featureToggle: {
+ notifyDebug: false
+ },
+ symbolInfo: {
+ baseAsset: 'BTC',
+ quoteAsset: 'BRL',
+ filterLotSize: { stepSize: '0.00000100', minQty: '0.00000100' },
+ filterPrice: { tickSize: '1.00000000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ buy: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ maxPurchaseAmount: 100,
+ stopPercentage: 1.01,
+ limitPercentage: 1.011,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'buy',
+ quoteAssetBalance: { free: 11 },
+ buy: {
+ currentPrice: 268748,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
price: 271704,
quantity: 0.00004,
side: 'buy',
@@ -1483,111 +2950,68 @@ describe('place-buy-order.js', () => {
symbol: 'BTCBRL',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
- }
- ]);
- mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
- account: 'info'
+ });
});
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
- }));
-
- const step = require('../place-buy-order');
-
- rawData = {
- symbol: 'BTCBRL',
- isLocked: false,
- symbolInfo: {
- baseAsset: 'BTC',
- quoteAsset: 'BRL',
- filterLotSize: { stepSize: '0.00000100', minQty: '0.00000100' },
- filterPrice: { tickSize: '1.00000000' },
- filterMinNotional: { minNotional: '10.00000000' }
- },
- symbolConfiguration: {
- buy: {
- enabled: true,
- maxPurchaseAmount: 100,
- stopPercentage: 1.01,
- limitPercentage: 1.011
- }
- },
- action: 'buy',
- quoteAssetBalance: { free: 11 },
- buy: {
- currentPrice: 268748,
- openOrders: []
- }
- };
-
- result = await step.execute(loggerMock, rawData);
- });
-
- it('triggers binance.client.order', () => {
- expect(binanceMock.client.order).toHaveBeenCalledWith({
- price: 271704,
- quantity: 0.00004,
- side: 'buy',
- stopPrice: 271435,
- symbol: 'BTCBRL',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ it('triggers cache.set for last buy order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCBRL-last-buy-order',
+ JSON.stringify({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 120
+ );
});
- });
- it('triggers cache.set', () => {
- expect(cacheMock.set).toHaveBeenCalledWith(
- 'BTCBRL-last-buy-order',
- 'true',
- 120
- );
- });
+ it('triggers cache.set for grid trade last buy order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCBRL-grid-trade-last-buy-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
- it('triggers mongo.upsertOne', () => {
- expect(mongoMock.upsertOne).toHaveBeenCalledWith(
- loggerMock,
- 'trailing-trade-symbols',
- {
- key: 'BTCBRL-last-buy-price'
- },
- {
- key: 'BTCBRL-last-buy-price',
- lastBuyPrice: 271704,
- quantity: 0.00004
- }
- );
- });
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
- it('triggers getAndCacheOpenOrdersForSymbol', () => {
- expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
- });
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
- it('triggers getAccountInfoFromAPI', () => {
- expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
- });
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
+ }
+ });
+ });
- it('retruns expected value', () => {
- expect(result).toStrictEqual({
- ...rawData,
- ...{
- openOrders: [
- {
- orderId: 456,
- price: 271704,
- quantity: 0.00004,
- side: 'buy',
- stopPrice: 271435,
- symbol: 'BTCBRL',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
- }
- ],
- buy: {
- currentPrice: 268748,
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
openOrders: [
{
orderId: 456,
@@ -1600,10 +3024,26 @@ describe('place-buy-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
],
- processMessage: 'Placed new stop loss limit order for buying.',
- updatedAt: expect.any(Object)
+ buy: {
+ currentPrice: 268748,
+ openOrders: [
+ {
+ orderId: 456,
+ price: 271704,
+ quantity: 0.00004,
+ side: 'buy',
+ stopPrice: 271435,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for buying of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
}
- }
+ });
});
});
});
diff --git a/app/cronjob/trailingTrade/step/__tests__/place-manual-trade.test.js b/app/cronjob/trailingTrade/step/__tests__/place-manual-trade.test.js
index f627794c..911e41ba 100644
--- a/app/cronjob/trailingTrade/step/__tests__/place-manual-trade.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/place-manual-trade.test.js
@@ -12,6 +12,7 @@ describe('place-manual-trade.js', () => {
let mockGetAndCacheOpenOrdersForSymbol;
let mockGetAccountInfoFromAPI;
let mockGetAPILimit;
+ let mockSaveOrder;
beforeEach(() => {
jest.clearAllMocks().resetModules();
@@ -38,6 +39,7 @@ describe('place-manual-trade.js', () => {
.fn()
.mockResolvedValue({ account: 'info' });
mockGetAPILimit = jest.fn().mockResolvedValue(10);
+ mockSaveOrder = jest.fn().mockResolvedValue(true);
});
describe('when symbol is locked', () => {
@@ -45,7 +47,8 @@ describe('place-manual-trade.js', () => {
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-manual-trade');
@@ -69,6 +72,10 @@ describe('place-manual-trade.js', () => {
expect(cacheMock.hset).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
@@ -89,7 +96,8 @@ describe('place-manual-trade.js', () => {
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-manual-trade');
@@ -113,6 +121,10 @@ describe('place-manual-trade.js', () => {
expect(cacheMock.hset).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('returns expected result', () => {
expect(result).toStrictEqual({
symbol: 'BTCUSDT',
@@ -752,7 +764,8 @@ describe('place-manual-trade.js', () => {
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
binanceMock.client.order = jest
@@ -799,10 +812,27 @@ describe('place-manual-trade.js', () => {
})
);
});
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ ...testData.orderResult
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-manual-trade',
+ savedMessage: 'The manual order is placed.'
+ }
+ });
+ });
} else {
it('does not trigger cache.hset', () => {
expect(cacheMock.hset).not.toHaveBeenCalled();
});
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
}
it('returns expected result', () => {
@@ -818,7 +848,8 @@ describe('place-manual-trade.js', () => {
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
binanceMock.client.order = jest.fn().mockResolvedValue(true);
diff --git a/app/cronjob/trailingTrade/step/__tests__/place-sell-order.test.js b/app/cronjob/trailingTrade/step/__tests__/place-sell-order.test.js
index bf6319cb..e2523054 100644
--- a/app/cronjob/trailingTrade/step/__tests__/place-sell-order.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/place-sell-order.test.js
@@ -13,6 +13,7 @@ describe('place-sell-order.js', () => {
let mockGetAccountInfoFromAPI;
let mockIsExceedAPILimit;
let mockGetAPILimit;
+ let mockSaveOrder;
describe('execute', () => {
beforeEach(() => {
@@ -33,6 +34,7 @@ describe('place-sell-order.js', () => {
mockIsExceedAPILimit = jest.fn().mockReturnValue(false);
mockGetAPILimit = jest.fn().mockResolvedValue(10);
+ mockSaveOrder = jest.fn().mockResolvedValue(true);
});
describe('when symbol is locked', () => {
@@ -46,7 +48,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -66,8 +69,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'not-determined',
@@ -90,6 +103,10 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual(rawData);
});
@@ -106,7 +123,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -126,8 +144,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'not-determined',
@@ -150,6 +178,10 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual(rawData);
});
@@ -166,7 +198,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -186,8 +219,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -222,6 +265,10 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -239,7 +286,89 @@ describe('place-sell-order.js', () => {
}
],
processMessage:
- 'There are open orders for BTCUPUSDT. Do not place an order.',
+ 'There are open orders for BTCUPUSDT. Do not place an order for the grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
+ });
+
+ describe('when current grid trade is null', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([]);
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-sell-order');
+
+ rawData = {
+ symbol: 'BTCUPUSDT',
+ isLocked: false,
+ symbolInfo: {
+ filterLotSize: {
+ stepSize: '0.01000000',
+ minQty: '0.01000000',
+ maxQty: '100.0000000'
+ },
+ filterPrice: { tickSize: '0.00100000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ sell: {
+ enabled: true,
+ currentGridTradeIndex: -1,
+ currentGridTrade: null
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'sell',
+ baseAssetBalance: { free: 0.5 },
+ sell: {
+ currentPrice: 200,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('does not trigger binance.client.order', () => {
+ expect(binanceMock.client.order).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ sell: {
+ currentPrice: 200,
+ openOrders: [],
+ processMessage:
+ 'Current grid trade is not defined. Do not place an order.',
updatedAt: expect.any(Object)
}
}
@@ -259,7 +388,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -279,8 +409,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -306,6 +446,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -314,7 +462,8 @@ describe('place-sell-order.js', () => {
currentPrice: 200,
openOrders: [],
processMessage:
- 'Order quantity is less or equal than the minimum quantity - 0.01000000. Do not place an order.',
+ `Order quantity is less or equal than the minimum quantity - 0.01000000. ` +
+ `Do not place an order for the grid trade #1.`,
updatedAt: expect.any(Object)
}
}
@@ -333,7 +482,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -353,8 +503,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -380,6 +540,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -388,7 +556,8 @@ describe('place-sell-order.js', () => {
currentPrice: 0.00003771,
openOrders: [],
processMessage:
- 'Order quantity is less or equal than the minimum quantity - 1.00000000. Do not place an order.',
+ `Order quantity is less or equal than the minimum quantity - 1.00000000. ` +
+ `Do not place an order for the grid trade #1.`,
updatedAt: expect.any(Object)
}
}
@@ -407,7 +576,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -427,8 +597,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -454,6 +634,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -462,7 +650,8 @@ describe('place-sell-order.js', () => {
currentPrice: 268748,
openOrders: [],
processMessage:
- 'Order quantity is less or equal than the minimum quantity - 0.00000100. Do not place an order.',
+ `Order quantity is less or equal than the minimum quantity - 0.00000100. ` +
+ `Do not place an order for the grid trade #1.`,
updatedAt: expect.any(Object)
}
}
@@ -483,7 +672,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -503,8 +693,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -530,6 +730,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -538,7 +746,8 @@ describe('place-sell-order.js', () => {
currentPrice: 200,
openOrders: [],
processMessage:
- 'Notional value is less than the minimum notional value. Do not place an order.',
+ `Notional value is less than the minimum notional value. ` +
+ `Do not place an order for the grid trade #1.`,
updatedAt: expect.any(Object)
}
}
@@ -557,7 +766,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -577,8 +787,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -604,6 +824,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -612,7 +840,8 @@ describe('place-sell-order.js', () => {
currentPrice: 0.00003771,
openOrders: [],
processMessage:
- 'Notional value is less than the minimum notional value. Do not place an order.',
+ `Notional value is less than the minimum notional value. ` +
+ `Do not place an order for the grid trade #1.`,
updatedAt: expect.any(Object)
}
}
@@ -631,7 +860,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -651,8 +881,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -678,6 +918,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -686,7 +934,8 @@ describe('place-sell-order.js', () => {
currentPrice: 268748,
openOrders: [],
processMessage:
- 'Notional value is less than the minimum notional value. Do not place an order.',
+ `Notional value is less than the minimum notional value. ` +
+ `Do not place an order for the grid trade #1.`,
updatedAt: expect.any(Object)
}
}
@@ -706,7 +955,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -726,8 +976,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: false,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -753,6 +1013,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -761,7 +1029,7 @@ describe('place-sell-order.js', () => {
currentPrice: 200,
openOrders: [],
processMessage:
- 'Trading for BTCUPUSDT is disabled. Do not place an order.',
+ 'Trading for BTCUPUSDT is disabled. Do not place an order for the grid trade #1.',
updatedAt: expect.any(Object)
}
}
@@ -782,7 +1050,8 @@ describe('place-sell-order.js', () => {
getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -802,8 +1071,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -829,6 +1108,14 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger cache.set', () => {
+ expect(cacheMock.set).not.toHaveBeenCalled();
+ });
+
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -837,7 +1124,7 @@ describe('place-sell-order.js', () => {
currentPrice: 200,
openOrders: [],
processMessage:
- 'Binance API limit has been exceeded. Do not place an order.',
+ 'Binance API limit has been exceeded. Do not place an order for the grid trade #1.',
updatedAt: expect.any(Object)
}
}
@@ -861,6 +1148,14 @@ describe('place-sell-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
account: 'info'
});
@@ -870,7 +1165,8 @@ describe('place-sell-order.js', () => {
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -890,8 +1186,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -917,14 +1223,36 @@ describe('place-sell-order.js', () => {
});
});
- it('triggers cache.set', () => {
+ it('triggers cache.set for last sell order', () => {
expect(cacheMock.set).toHaveBeenCalledWith(
'BTCUPUSDT-last-sell-order',
- 'true',
+ JSON.stringify({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
15
);
});
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCUPUSDT-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
it('triggers getAndCacheOpenOrdersForSymbol', () => {
expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
});
@@ -933,6 +1261,23 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -964,7 +1309,7 @@ describe('place-sell-order.js', () => {
}
],
processMessage:
- 'Placed new stop loss limit order for selling.',
+ 'Placed new stop loss limit order for selling of grid trade #1.',
updatedAt: expect.any(Object)
}
}
@@ -986,6 +1331,14 @@ describe('place-sell-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
account: 'info'
});
@@ -995,7 +1348,8 @@ describe('place-sell-order.js', () => {
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -1015,8 +1369,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -1042,14 +1406,36 @@ describe('place-sell-order.js', () => {
});
});
- it('triggers cache.set', () => {
+ it('triggers cache.set for last sell order', () => {
expect(cacheMock.set).toHaveBeenCalledWith(
'ALPHABTC-last-sell-order',
- 'true',
+ JSON.stringify({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
15
);
});
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'ALPHABTC-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
it('triggers getAndCacheOpenOrdersForSymbol', () => {
expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
});
@@ -1058,6 +1444,23 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1089,7 +1492,7 @@ describe('place-sell-order.js', () => {
}
],
processMessage:
- 'Placed new stop loss limit order for selling.',
+ 'Placed new stop loss limit order for selling of grid trade #1.',
updatedAt: expect.any(Object)
}
}
@@ -1111,6 +1514,14 @@ describe('place-sell-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
account: 'info'
});
@@ -1120,7 +1531,8 @@ describe('place-sell-order.js', () => {
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-order');
@@ -1140,8 +1552,18 @@ describe('place-sell-order.js', () => {
symbolConfiguration: {
sell: {
enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
},
action: 'sell',
@@ -1167,14 +1589,36 @@ describe('place-sell-order.js', () => {
});
});
- it('triggers cache.set', () => {
+ it('triggers cache.set for last sell order', () => {
expect(cacheMock.set).toHaveBeenCalledWith(
'BTCBRL-last-sell-order',
- 'true',
+ JSON.stringify({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
15
);
});
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCBRL-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
it('triggers getAndCacheOpenOrdersForSymbol', () => {
expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
});
@@ -1183,6 +1627,23 @@ describe('place-sell-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1214,7 +1675,7 @@ describe('place-sell-order.js', () => {
}
],
processMessage:
- 'Placed new stop loss limit order for selling.',
+ 'Placed new stop loss limit order for selling of grid trade #1.',
updatedAt: expect.any(Object)
}
}
@@ -1224,110 +1685,706 @@ describe('place-sell-order.js', () => {
});
describe('when the quality is less than maximum quantity', () => {
- describe('BTCUPUSDT', () => {
- beforeEach(async () => {
- mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
- {
- orderId: 123,
+ describe('when quantity percentage is less than 1', () => {
+ describe('BTCUPUSDT', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 197.8,
+ quantity: 0.49,
+ side: 'sell',
+ stopPrice: 198,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-sell-order');
+
+ rawData = {
+ symbol: 'BTCUPUSDT',
+ isLocked: false,
+ symbolInfo: {
+ filterLotSize: {
+ stepSize: '0.01000000',
+ minQty: '0.01000000',
+ maxQty: '100.0000000'
+ },
+ filterPrice: { tickSize: '0.00100000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ sell: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 0.5,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'sell',
+ baseAssetBalance: { free: 1 },
+ sell: {
+ currentPrice: 200,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
price: 197.8,
- quantity: 0.09,
+ quantity: 0.49,
side: 'sell',
stopPrice: 198,
symbol: 'BTCUPUSDT',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
- }
- ]);
- mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
- account: 'info'
+ });
});
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getAndCacheOpenOrdersForSymbol:
- mockGetAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
- }));
+ it('triggers cache.set for last sell order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCUPUSDT-last-sell-order',
+ JSON.stringify({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 15
+ );
+ });
- const step = require('../place-sell-order');
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCUPUSDT-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
- rawData = {
- symbol: 'BTCUPUSDT',
- isLocked: false,
- symbolInfo: {
- filterLotSize: {
- stepSize: '0.01000000',
- minQty: '0.01000000',
- maxQty: '100.0000000'
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
},
- filterPrice: { tickSize: '0.00100000' },
- filterMinNotional: { minNotional: '10.00000000' }
- },
- symbolConfiguration: {
- sell: {
- enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
}
- },
- action: 'sell',
- baseAssetBalance: { free: 0.1 },
- sell: {
- currentPrice: 200,
- openOrders: []
- }
- };
+ });
+ });
- result = await step.execute(loggerMock, rawData);
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 123,
+ price: 197.8,
+ quantity: 0.49,
+ side: 'sell',
+ stopPrice: 198,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ sell: {
+ currentPrice: 200,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 197.8,
+ quantity: 0.49,
+ side: 'sell',
+ stopPrice: 198,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for selling of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
- it('triggers binance.client.order', () => {
- expect(binanceMock.client.order).toHaveBeenCalledWith({
- price: 197.8,
- quantity: 0.09,
- side: 'sell',
- stopPrice: 198,
- symbol: 'BTCUPUSDT',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ describe('ALPHABTC', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 0.00003729,
+ quantity: 5,
+ side: 'sell',
+ stopPrice: 0.00003733,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-sell-order');
+
+ rawData = {
+ symbol: 'ALPHABTC',
+ isLocked: false,
+ symbolInfo: {
+ filterLotSize: {
+ minQty: '1.00000000',
+ maxQty: '90000000.00000000',
+ stepSize: '1.00000000'
+ },
+ filterPrice: { tickSize: '0.00000001' },
+ filterMinNotional: { minNotional: '0.00010000' }
+ },
+ symbolConfiguration: {
+ sell: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 0.5,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'sell',
+ baseAssetBalance: { free: 11 },
+ sell: {
+ currentPrice: 0.00003771,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
});
- });
- it('triggers cache.set', () => {
- expect(cacheMock.set).toHaveBeenCalledWith(
- 'BTCUPUSDT-last-sell-order',
- 'true',
- 15
- );
- });
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 0.00003729,
+ quantity: 5,
+ side: 'sell',
+ stopPrice: 0.00003733,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
- it('triggers getAndCacheOpenOrdersForSymbol', () => {
- expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ it('triggers cache.set for last sell order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'ALPHABTC-last-sell-order',
+ JSON.stringify({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 15
+ );
+ });
+
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'ALPHABTC-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 123,
+ price: 0.00003729,
+ quantity: 5,
+ side: 'sell',
+ stopPrice: 0.00003733,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ sell: {
+ currentPrice: 0.00003771,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 0.00003729,
+ quantity: 5,
+ side: 'sell',
+ stopPrice: 0.00003733,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for selling of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
- it('triggers getAccountInfoFromAPI', () => {
- expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ describe('BTCBRL', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 265791,
+ quantity: 0.000039,
+ side: 'sell',
+ stopPrice: 266060,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-sell-order');
+
+ rawData = {
+ symbol: 'BTCBRL',
+ isLocked: false,
+ symbolInfo: {
+ filterLotSize: {
+ minQty: '0.00000100',
+ maxQty: '9000.00000000',
+ stepSize: '0.00000100'
+ },
+ filterPrice: { tickSize: '1.00000000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ sell: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 0.5,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'sell',
+ baseAssetBalance: { free: 0.00008 },
+ sell: {
+ currentPrice: 268748,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 265791,
+ quantity: 0.000039,
+ side: 'sell',
+ stopPrice: 266060,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
+
+ it('triggers cache.set for last sell order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCBRL-last-sell-order',
+ JSON.stringify({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 15
+ );
+ });
+
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCBRL-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
+ openOrders: [
+ {
+ orderId: 123,
+ price: 265791,
+ quantity: 0.000039,
+ side: 'sell',
+ stopPrice: 266060,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ sell: {
+ currentPrice: 268748,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 265791,
+ quantity: 0.000039,
+ side: 'sell',
+ stopPrice: 266060,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for selling of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
+ }
+ });
+ });
});
+ });
- it('retruns expected value', () => {
- expect(result).toStrictEqual({
- ...rawData,
- ...{
- openOrders: [
- {
- orderId: 123,
- price: 197.8,
- quantity: 0.09,
- side: 'sell',
- stopPrice: 198,
- symbol: 'BTCUPUSDT',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ describe('when quantity percentage is equal to 1', () => {
+ describe('BTCUPUSDT', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 197.8,
+ quantity: 0.09,
+ side: 'sell',
+ stopPrice: 198,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-sell-order');
+
+ rawData = {
+ symbol: 'BTCUPUSDT',
+ isLocked: false,
+ symbolInfo: {
+ filterLotSize: {
+ stepSize: '0.01000000',
+ minQty: '0.01000000',
+ maxQty: '100.0000000'
+ },
+ filterPrice: { tickSize: '0.00100000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ sell: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
}
- ],
+ },
+ action: 'sell',
+ baseAssetBalance: { free: 0.1 },
sell: {
currentPrice: 200,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
+ price: 197.8,
+ quantity: 0.09,
+ side: 'sell',
+ stopPrice: 198,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ });
+ });
+
+ it('triggers cache.set for last sell order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCUPUSDT-last-sell-order',
+ JSON.stringify({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 15
+ );
+ });
+
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCUPUSDT-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
+ });
+
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
+
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
+
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
+
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
openOrders: [
{
orderId: 123,
@@ -1340,20 +2397,108 @@ describe('place-sell-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
],
- processMessage:
- 'Placed new stop loss limit order for selling.',
- updatedAt: expect.any(Object)
+ sell: {
+ currentPrice: 200,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 197.8,
+ quantity: 0.09,
+ side: 'sell',
+ stopPrice: 198,
+ symbol: 'BTCUPUSDT',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for selling of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
}
- }
+ });
});
});
- });
- describe('ALPHABTC', () => {
- beforeEach(async () => {
- mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
- {
- orderId: 123,
+ describe('ALPHABTC', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 0.00003729,
+ quantity: 10,
+ side: 'sell',
+ stopPrice: 0.00003733,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-sell-order');
+
+ rawData = {
+ symbol: 'ALPHABTC',
+ isLocked: false,
+ symbolInfo: {
+ filterLotSize: {
+ minQty: '1.00000000',
+ maxQty: '90000000.00000000',
+ stepSize: '1.00000000'
+ },
+ filterPrice: { tickSize: '0.00000001' },
+ filterMinNotional: { minNotional: '0.00010000' }
+ },
+ symbolConfiguration: {
+ sell: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'sell',
+ baseAssetBalance: { free: 11 },
+ sell: {
+ currentPrice: 0.00003771,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
price: 0.00003729,
quantity: 10,
side: 'sell',
@@ -1361,98 +2506,68 @@ describe('place-sell-order.js', () => {
symbol: 'ALPHABTC',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
- }
- ]);
- mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
- account: 'info'
+ });
});
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getAndCacheOpenOrdersForSymbol:
- mockGetAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
- }));
-
- const step = require('../place-sell-order');
-
- rawData = {
- symbol: 'ALPHABTC',
- isLocked: false,
- symbolInfo: {
- filterLotSize: {
- minQty: '1.00000000',
- maxQty: '90000000.00000000',
- stepSize: '1.00000000'
- },
- filterPrice: { tickSize: '0.00000001' },
- filterMinNotional: { minNotional: '0.00010000' }
- },
- symbolConfiguration: {
- sell: {
- enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
- }
- },
- action: 'sell',
- baseAssetBalance: { free: 11 },
- sell: {
- currentPrice: 0.00003771,
- openOrders: []
- }
- };
-
- result = await step.execute(loggerMock, rawData);
- });
+ it('triggers cache.set for last sell order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'ALPHABTC-last-sell-order',
+ JSON.stringify({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 15
+ );
+ });
- it('triggers binance.client.order', () => {
- expect(binanceMock.client.order).toHaveBeenCalledWith({
- price: 0.00003729,
- quantity: 10,
- side: 'sell',
- stopPrice: 0.00003733,
- symbol: 'ALPHABTC',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'ALPHABTC-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
});
- });
- it('triggers cache.set', () => {
- expect(cacheMock.set).toHaveBeenCalledWith(
- 'ALPHABTC-last-sell-order',
- 'true',
- 15
- );
- });
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
- it('triggers getAndCacheOpenOrdersForSymbol', () => {
- expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
- });
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
- it('triggers getAccountInfoFromAPI', () => {
- expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
- });
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
- it('retruns expected value', () => {
- expect(result).toStrictEqual({
- ...rawData,
- ...{
- openOrders: [
- {
- orderId: 123,
- price: 0.00003729,
- quantity: 10,
- side: 'sell',
- stopPrice: 0.00003733,
- symbol: 'ALPHABTC',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
- }
- ],
- sell: {
- currentPrice: 0.00003771,
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
openOrders: [
{
orderId: 123,
@@ -1465,20 +2580,108 @@ describe('place-sell-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
],
- processMessage:
- 'Placed new stop loss limit order for selling.',
- updatedAt: expect.any(Object)
+ sell: {
+ currentPrice: 0.00003771,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 0.00003729,
+ quantity: 10,
+ side: 'sell',
+ stopPrice: 0.00003733,
+ symbol: 'ALPHABTC',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for selling of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
}
- }
+ });
});
});
- });
- describe('BTCBRL', () => {
- beforeEach(async () => {
- mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
- {
- orderId: 123,
+ describe('BTCBRL', () => {
+ beforeEach(async () => {
+ mockGetAndCacheOpenOrdersForSymbol = jest.fn().mockResolvedValue([
+ {
+ orderId: 123,
+ price: 265791,
+ quantity: 0.0999,
+ side: 'sell',
+ stopPrice: 266060,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ]);
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
+ mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
+ account: 'info'
+ });
+
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol:
+ mockGetAndCacheOpenOrdersForSymbol,
+ getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
+ isExceedAPILimit: mockIsExceedAPILimit,
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
+ }));
+
+ const step = require('../place-sell-order');
+
+ rawData = {
+ symbol: 'BTCBRL',
+ isLocked: false,
+ symbolInfo: {
+ filterLotSize: {
+ minQty: '0.00000100',
+ maxQty: '9000.00000000',
+ stepSize: '0.00000100'
+ },
+ filterPrice: { tickSize: '1.00000000' },
+ filterMinNotional: { minNotional: '10.00000000' }
+ },
+ symbolConfiguration: {
+ sell: {
+ enabled: true,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.99,
+ limitPercentage: 0.989,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ system: {
+ checkOrderExecutePeriod: 10
+ }
+ },
+ action: 'sell',
+ baseAssetBalance: { free: 0.1 },
+ sell: {
+ currentPrice: 268748,
+ openOrders: []
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('triggers binance.client.order', () => {
+ expect(binanceMock.client.order).toHaveBeenCalledWith({
price: 265791,
quantity: 0.0999,
side: 'sell',
@@ -1486,98 +2689,68 @@ describe('place-sell-order.js', () => {
symbol: 'BTCBRL',
timeInForce: 'GTC',
type: 'STOP_LOSS_LIMIT'
- }
- ]);
- mockGetAccountInfoFromAPI = jest.fn().mockResolvedValue({
- account: 'info'
+ });
});
- jest.mock('../../../trailingTradeHelper/common', () => ({
- getAndCacheOpenOrdersForSymbol:
- mockGetAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
- isExceedAPILimit: mockIsExceedAPILimit,
- getAPILimit: mockGetAPILimit
- }));
-
- const step = require('../place-sell-order');
-
- rawData = {
- symbol: 'BTCBRL',
- isLocked: false,
- symbolInfo: {
- filterLotSize: {
- minQty: '0.00000100',
- maxQty: '9000.00000000',
- stepSize: '0.00000100'
- },
- filterPrice: { tickSize: '1.00000000' },
- filterMinNotional: { minNotional: '10.00000000' }
- },
- symbolConfiguration: {
- sell: {
- enabled: true,
- stopPercentage: 0.99,
- limitPercentage: 0.989
- }
- },
- action: 'sell',
- baseAssetBalance: { free: 0.1 },
- sell: {
- currentPrice: 268748,
- openOrders: []
- }
- };
-
- result = await step.execute(loggerMock, rawData);
- });
+ it('triggers cache.set for last sell order', () => {
+ expect(cacheMock.set).toHaveBeenCalledWith(
+ 'BTCBRL-last-sell-order',
+ JSON.stringify({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ }),
+ 15
+ );
+ });
- it('triggers binance.client.order', () => {
- expect(binanceMock.client.order).toHaveBeenCalledWith({
- price: 265791,
- quantity: 0.0999,
- side: 'sell',
- stopPrice: 266060,
- symbol: 'BTCBRL',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
+ it('triggers cache.set for grid trade last sell order', () => {
+ expect(cacheMock.set.mock.calls[1][0]).toStrictEqual(
+ 'BTCBRL-grid-trade-last-sell-order'
+ );
+ const args = JSON.parse(cacheMock.set.mock.calls[1][1]);
+ expect(args).toStrictEqual({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520,
+ currentGridTradeIndex: 0,
+ nextCheck: expect.any(String)
+ });
});
- });
- it('triggers cache.set', () => {
- expect(cacheMock.set).toHaveBeenCalledWith(
- 'BTCBRL-last-sell-order',
- 'true',
- 15
- );
- });
+ it('triggers getAndCacheOpenOrdersForSymbol', () => {
+ expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
+ });
- it('triggers getAndCacheOpenOrdersForSymbol', () => {
- expect(mockGetAndCacheOpenOrdersForSymbol).toHaveBeenCalled();
- });
+ it('triggers getAccountInfoFromAPI', () => {
+ expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
+ });
- it('triggers getAccountInfoFromAPI', () => {
- expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
- });
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+ });
- it('retruns expected value', () => {
- expect(result).toStrictEqual({
- ...rawData,
- ...{
- openOrders: [
- {
- orderId: 123,
- price: 265791,
- quantity: 0.0999,
- side: 'sell',
- stopPrice: 266060,
- symbol: 'BTCBRL',
- timeInForce: 'GTC',
- type: 'STOP_LOSS_LIMIT'
- }
- ],
- sell: {
- currentPrice: 268748,
+ it('retruns expected value', () => {
+ expect(result).toStrictEqual({
+ ...rawData,
+ ...{
openOrders: [
{
orderId: 123,
@@ -1590,11 +2763,26 @@ describe('place-sell-order.js', () => {
type: 'STOP_LOSS_LIMIT'
}
],
- processMessage:
- 'Placed new stop loss limit order for selling.',
- updatedAt: expect.any(Object)
+ sell: {
+ currentPrice: 268748,
+ openOrders: [
+ {
+ orderId: 123,
+ price: 265791,
+ quantity: 0.0999,
+ side: 'sell',
+ stopPrice: 266060,
+ symbol: 'BTCBRL',
+ timeInForce: 'GTC',
+ type: 'STOP_LOSS_LIMIT'
+ }
+ ],
+ processMessage:
+ 'Placed new stop loss limit order for selling of grid trade #1.',
+ updatedAt: expect.any(Object)
+ }
}
- }
+ });
});
});
});
diff --git a/app/cronjob/trailingTrade/step/__tests__/place-sell-stop-loss-order.test.js b/app/cronjob/trailingTrade/step/__tests__/place-sell-stop-loss-order.test.js
index 60abd658..242d59cd 100644
--- a/app/cronjob/trailingTrade/step/__tests__/place-sell-stop-loss-order.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/place-sell-stop-loss-order.test.js
@@ -13,6 +13,7 @@ describe('place-sell-stop-loss-order.js', () => {
let mockIsExceedAPILimit;
let mockDisableAction;
let mockGetAPILimit;
+ let mockSaveOrder;
describe('execute', () => {
beforeEach(() => {
@@ -31,6 +32,7 @@ describe('place-sell-stop-loss-order.js', () => {
mockIsExceedAPILimit = jest.fn().mockReturnValue(false);
mockDisableAction = jest.fn().mockResolvedValue(true);
mockGetAPILimit = jest.fn().mockReturnValueOnce(10);
+ mockSaveOrder = jest.fn().mockResolvedValue(true);
});
describe('when symbol is locked', () => {
@@ -45,7 +47,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -91,6 +94,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual(rawData);
});
@@ -108,7 +115,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -154,6 +162,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual(rawData);
});
@@ -171,7 +183,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -229,6 +242,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -267,7 +284,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -316,6 +334,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -345,7 +367,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -394,6 +417,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -423,7 +450,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -472,6 +500,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -503,7 +535,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -552,6 +585,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -580,7 +617,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -629,6 +667,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -657,7 +699,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -706,6 +749,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -735,7 +782,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -784,6 +832,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -814,7 +866,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -863,6 +916,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -891,7 +948,8 @@ describe('place-sell-stop-loss-order.js', () => {
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -940,6 +998,10 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).not.toHaveBeenCalled();
});
+ it('does not trigger saveOrder', () => {
+ expect(mockSaveOrder).not.toHaveBeenCalled();
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -973,13 +1035,22 @@ describe('place-sell-stop-loss-order.js', () => {
account: 'info'
});
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol:
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -1046,6 +1117,23 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-stop-loss-order',
+ savedMessage: 'The sell STOP-LOSS order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1093,13 +1181,22 @@ describe('place-sell-stop-loss-order.js', () => {
account: 'info'
});
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol:
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -1166,6 +1263,23 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-stop-loss-order',
+ savedMessage: 'The sell STOP-LOSS order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1213,13 +1327,22 @@ describe('place-sell-stop-loss-order.js', () => {
account: 'info'
});
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol:
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -1286,6 +1409,23 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-stop-loss-order',
+ savedMessage: 'The sell STOP-LOSS order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1335,13 +1475,22 @@ describe('place-sell-stop-loss-order.js', () => {
account: 'info'
});
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol:
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -1408,6 +1557,23 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCUPUSDT',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-stop-loss-order',
+ savedMessage: 'The sell STOP-LOSS order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1455,13 +1621,22 @@ describe('place-sell-stop-loss-order.js', () => {
account: 'info'
});
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol:
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -1528,6 +1703,23 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'ALPHABTC',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-stop-loss-order',
+ savedMessage: 'The sell STOP-LOSS order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
@@ -1575,13 +1767,22 @@ describe('place-sell-stop-loss-order.js', () => {
account: 'info'
});
+ binanceMock.client.order = jest.fn().mockResolvedValue({
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ });
+
jest.mock('../../../trailingTradeHelper/common', () => ({
getAndCacheOpenOrdersForSymbol:
mockGetAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI: mockGetAccountInfoFromAPI,
isExceedAPILimit: mockIsExceedAPILimit,
disableAction: mockDisableAction,
- getAPILimit: mockGetAPILimit
+ getAPILimit: mockGetAPILimit,
+ saveOrder: mockSaveOrder
}));
const step = require('../place-sell-stop-loss-order');
@@ -1648,6 +1849,23 @@ describe('place-sell-stop-loss-order.js', () => {
expect(mockGetAccountInfoFromAPI).toHaveBeenCalled();
});
+ it('triggers saveOrder', () => {
+ expect(mockSaveOrder).toHaveBeenCalledWith(loggerMock, {
+ order: {
+ symbol: 'BTCBRL',
+ orderId: 2701762317,
+ orderListId: -1,
+ clientOrderId: '6eGYHaJbmJrIS40eoq8ziM',
+ transactTime: 1626946722520
+ },
+ botStatus: {
+ savedAt: expect.any(String),
+ savedBy: 'place-sell-stop-loss-order',
+ savedMessage: 'The sell STOP-LOSS order is placed.'
+ }
+ });
+ });
+
it('retruns expected value', () => {
expect(result).toStrictEqual({
...rawData,
diff --git a/app/cronjob/trailingTrade/step/__tests__/remove-last-buy-price.test.js b/app/cronjob/trailingTrade/step/__tests__/remove-last-buy-price.test.js
index 7547431d..c710f219 100644
--- a/app/cronjob/trailingTrade/step/__tests__/remove-last-buy-price.test.js
+++ b/app/cronjob/trailingTrade/step/__tests__/remove-last-buy-price.test.js
@@ -191,6 +191,128 @@ describe('remove-last-buy-price.js', () => {
});
});
+ describe('when grid trade last buy order exists', () => {
+ beforeEach(async () => {
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
+ isActionDisabled: mockIsActionDisabled,
+ getAPILimit: mockGetAPILimit
+ }));
+
+ cacheMock.get = jest.fn().mockImplementation(key => {
+ if (key === 'BTCUPUSDT-grid-trade-last-buy-order') {
+ return Promise.resolve(
+ JSON.stringify({
+ orderId: 123
+ })
+ );
+ }
+
+ return Promise.resolve(null);
+ });
+
+ const step = require('../remove-last-buy-price');
+
+ rawData = {
+ action: 'not-determined',
+ isLocked: false,
+ symbol: 'BTCUPUSDT',
+ symbolConfiguration: {
+ buy: { lastBuyPriceRemoveThreshold: 10 }
+ },
+ symbolInfo: {
+ filterLotSize: {
+ stepSize: '0.01000000',
+ minQty: '0.01000000'
+ },
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ openOrders: [],
+ baseAssetBalance: {
+ free: 0,
+ locked: 0
+ },
+ sell: {
+ currentPrice: 200,
+ lastBuyPrice: null
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('does not trigger mongo.deleteOne', () => {
+ expect(mongoMock.deleteOne).not.toHaveBeenCalled();
+ });
+
+ it('returns expected data', () => {
+ expect(result).toStrictEqual(rawData);
+ });
+ });
+
+ describe('when grid trade last sell order exists', () => {
+ beforeEach(async () => {
+ jest.mock('../../../trailingTradeHelper/common', () => ({
+ getAndCacheOpenOrdersForSymbol: mockGetAndCacheOpenOrdersForSymbol,
+ isActionDisabled: mockIsActionDisabled,
+ getAPILimit: mockGetAPILimit
+ }));
+
+ cacheMock.get = jest.fn().mockImplementation(key => {
+ if (key === 'BTCUPUSDT-grid-trade-last-sell-order') {
+ return Promise.resolve(
+ JSON.stringify({
+ orderId: 123
+ })
+ );
+ }
+
+ return Promise.resolve(null);
+ });
+
+ const step = require('../remove-last-buy-price');
+
+ rawData = {
+ action: 'not-determined',
+ isLocked: false,
+ symbol: 'BTCUPUSDT',
+ symbolConfiguration: {
+ buy: { lastBuyPriceRemoveThreshold: 10 }
+ },
+ symbolInfo: {
+ filterLotSize: {
+ stepSize: '0.01000000',
+ minQty: '0.01000000'
+ },
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ },
+ openOrders: [],
+ baseAssetBalance: {
+ free: 0,
+ locked: 0
+ },
+ sell: {
+ currentPrice: 200,
+ lastBuyPrice: null
+ }
+ };
+
+ result = await step.execute(loggerMock, rawData);
+ });
+
+ it('does not trigger mongo.deleteOne', () => {
+ expect(mongoMock.deleteOne).not.toHaveBeenCalled();
+ });
+
+ it('returns expected data', () => {
+ expect(result).toStrictEqual(rawData);
+ });
+ });
+
describe('when last buy price is not set', () => {
beforeEach(async () => {
jest.mock('../../../trailingTradeHelper/common', () => ({
diff --git a/app/cronjob/trailingTrade/step/determine-action.js b/app/cronjob/trailingTrade/step/determine-action.js
index 8647d1d0..c992b725 100644
--- a/app/cronjob/trailingTrade/step/determine-action.js
+++ b/app/cronjob/trailingTrade/step/determine-action.js
@@ -1,25 +1,35 @@
+const _ = require('lodash');
const moment = require('moment');
+const { cache } = require('../../../helpers');
const { isActionDisabled } = require('../../trailingTradeHelper/common');
/**
* Check whether can buy or not
*
+ * - current price must be less than trigger price.
+ * - current grid trade must be defined.
+ *
* @param {*} data
* @returns
*/
const canBuy = data => {
const {
- buy: { currentPrice: buyCurrentPrice, triggerPrice: buyTriggerPrice },
- sell: { lastBuyPrice }
+ symbolConfiguration: {
+ buy: { currentGridTrade }
+ },
+ buy: { currentPrice: buyCurrentPrice, triggerPrice: buyTriggerPrice }
} = data;
- return lastBuyPrice <= 0 && buyCurrentPrice <= buyTriggerPrice;
+ return buyCurrentPrice <= buyTriggerPrice && currentGridTrade !== null;
};
/**
* Check whether has enough balance to sell
*
+ * - If current gird trade index is 0, and has enough balance to sell,
+ * then it should not execute
+ *
* @param {*} data
* @returns
*/
@@ -29,15 +39,25 @@ const hasBalanceToSell = data => {
filterMinNotional: { minNotional }
},
baseAssetBalance: { total: baseAssetTotalBalance },
- buy: { currentPrice: buyCurrentPrice }
+ buy: { currentPrice: buyCurrentPrice },
+ symbolConfiguration: {
+ buy: { currentGridTradeIndex: currentBuyGridTradeIndex }
+ }
} = data;
- return baseAssetTotalBalance * buyCurrentPrice >= parseFloat(minNotional);
+ return (
+ currentBuyGridTradeIndex === 0 &&
+ baseAssetTotalBalance * buyCurrentPrice >= parseFloat(minNotional)
+ );
};
/**
* Check whether trigger price within the buying restriction price or not
*
+ * - current grid trade must be first grid trade.
+ * - ATH restriction must be enabled.
+ * - buy trigger price must be higher than ATH restriction price.
+ *
* @param {*} data
* @returns
*/
@@ -45,6 +65,7 @@ const isGreaterThanTheATHRestrictionPrice = data => {
const {
symbolConfiguration: {
buy: {
+ currentGridTradeIndex,
athRestriction: { enabled: buyATHRestrictionEnabled }
}
},
@@ -55,6 +76,7 @@ const isGreaterThanTheATHRestrictionPrice = data => {
} = data;
return (
+ currentGridTradeIndex === 0 &&
buyATHRestrictionEnabled === true &&
buyTriggerPrice >= buyATHRestrictionPrice
);
@@ -82,6 +104,10 @@ const setBuyActionAndMessage = (logger, rawData, action, processMessage) => {
/**
* Check whether can sell or not
*
+ * - last buy price must be more than 0.
+ * - current balance must be more than the minimum notional value
+ * - current grid trade must not be null.
+ *
* @param {*} data
* @returns
*/
@@ -90,13 +116,17 @@ const canSell = data => {
symbolInfo: {
filterMinNotional: { minNotional }
},
+ symbolConfiguration: {
+ sell: { currentGridTrade }
+ },
baseAssetBalance: { total: baseAssetTotalBalance },
sell: { currentPrice: sellCurrentPrice, lastBuyPrice }
} = data;
return (
lastBuyPrice > 0 &&
- baseAssetTotalBalance * sellCurrentPrice > parseFloat(minNotional)
+ baseAssetTotalBalance * sellCurrentPrice > parseFloat(minNotional) &&
+ currentGridTrade !== null
);
};
@@ -157,6 +187,27 @@ const setSellActionAndMessage = (logger, rawData, action, processMessage) => {
return data;
};
+/**
+ * Retrieve last grid order from cache
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} side
+ * @returns
+ */
+const getGridTradeLastOrder = async (logger, symbol, side) => {
+ const cachedLastOrder =
+ JSON.parse(await cache.get(`${symbol}-grid-trade-last-${side}-order`)) ||
+ {};
+
+ logger.info(
+ { cachedLastOrder },
+ `Retrieved grid trade last ${side} order from cache`
+ );
+
+ return cachedLastOrder;
+};
+
/**
* Determine action for trade
*
@@ -170,9 +221,16 @@ const execute = async (logger, rawData) => {
action,
symbol,
isLocked,
- symbolInfo: { baseAsset }
+ symbolInfo: { baseAsset },
+ symbolConfiguration: {
+ buy: { currentGridTradeIndex: currentBuyGridTradeIndex },
+ sell: { currentGridTradeIndex: currentSellGridTradeIndex }
+ }
} = data;
+ const humanisedBuyGridTradeIndex = currentBuyGridTradeIndex + 1;
+ const humanisedSellGridTradeIndex = currentSellGridTradeIndex + 1;
+
if (isLocked) {
logger.info(
{ isLocked },
@@ -196,6 +254,17 @@ const execute = async (logger, rawData) => {
// and current price is lower than the restriction price
// then buy.
if (canBuy(data)) {
+ if (
+ _.isEmpty(await getGridTradeLastOrder(logger, symbol, 'buy')) === false
+ ) {
+ return setBuyActionAndMessage(
+ logger,
+ data,
+ 'buy-order-wait',
+ `There is a last gird trade buy order. Wait.`
+ );
+ }
+
if (hasBalanceToSell(data)) {
return setBuyActionAndMessage(
logger,
@@ -237,7 +306,7 @@ const execute = async (logger, rawData) => {
logger,
data,
'buy',
- "The current price reached the trigger price. Let's buy it."
+ `The current price reached the trigger price for the grid trade #${humanisedBuyGridTradeIndex}. Let's buy it.`
);
}
@@ -245,6 +314,16 @@ const execute = async (logger, rawData) => {
// last buy price has a value
// and total balance is enough to sell
if (canSell(data)) {
+ if (
+ _.isEmpty(await getGridTradeLastOrder(logger, symbol, 'sell')) === false
+ ) {
+ return setSellActionAndMessage(
+ logger,
+ data,
+ 'sell-order-wait',
+ `There is a last gird trade sell order. Wait.`
+ );
+ }
// And if current price is higher or equal than trigger price
if (isHigherThanSellTriggerPrice(data)) {
const checkDisable = await isActionDisabled(symbol);
@@ -300,7 +379,8 @@ const execute = async (logger, rawData) => {
logger,
data,
'sell-wait',
- 'The current price is lower than the selling trigger price. Wait.'
+ `The current price is lower than the selling trigger price ` +
+ `for the grid trade #${humanisedSellGridTradeIndex}. Wait.`
);
}
diff --git a/app/cronjob/trailingTrade/step/ensure-grid-trade-order-executed.js b/app/cronjob/trailingTrade/step/ensure-grid-trade-order-executed.js
new file mode 100644
index 00000000..6d9b2d68
--- /dev/null
+++ b/app/cronjob/trailingTrade/step/ensure-grid-trade-order-executed.js
@@ -0,0 +1,770 @@
+const moment = require('moment');
+const _ = require('lodash');
+
+const { cache, slack, PubSub, binance } = require('../../../helpers');
+const {
+ calculateLastBuyPrice,
+ getAPILimit,
+ isExceedAPILimit,
+ disableAction,
+ saveOrder
+} = require('../../trailingTradeHelper/common');
+
+const {
+ saveSymbolGridTrade
+} = require('../../trailingTradeHelper/configuration');
+
+/**
+ * Retrieve last grid order from cache
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} side
+ * @returns
+ */
+const getGridTradeLastOrder = async (logger, symbol, side) => {
+ const cachedLastOrder =
+ JSON.parse(await cache.get(`${symbol}-grid-trade-last-${side}-order`)) ||
+ {};
+
+ logger.info(
+ { cachedLastOrder },
+ `Retrieved grid trade last ${side} order from cache`
+ );
+
+ return cachedLastOrder;
+};
+
+/**
+ * Update grid trade order
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} side
+ * @param {*} newOrder
+ */
+const updateGridTradeLastOrder = async (logger, symbol, side, newOrder) => {
+ await cache.set(
+ `${symbol}-grid-trade-last-${side}-order`,
+ JSON.stringify(newOrder)
+ );
+ logger.info(
+ { debug: true },
+ `Updated grid trade last ${side} order to cache`
+ );
+};
+
+/**
+ * Remove last order from cache
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ */
+const removeGridTradeLastOrder = async (logger, symbol, side) => {
+ await cache.del(`${symbol}-grid-trade-last-${side}-order`);
+ logger.info(
+ { debug: true },
+ `Deleted grid trade last ${side} order from cache`
+ );
+};
+
+/**
+ * Send slack message for order filled
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} side
+ * @param {*} orderParams
+ * @param {*} orderResult
+ * @param {*} notifyOrderExecute
+ */
+const slackMessageOrderFilled = async (
+ logger,
+ symbol,
+ side,
+ orderParams,
+ orderResult,
+ notifyOrderExecute
+) => {
+ const type = orderParams.type.toUpperCase();
+
+ const humanisedGridTradeIndex = orderParams.currentGridTradeIndex + 1;
+
+ PubSub.publish('frontend-notification', {
+ type: 'success',
+ title:
+ `The ${side} order of the grid trade #${humanisedGridTradeIndex} ` +
+ `for ${symbol} has been executed successfully.`
+ });
+
+ if (notifyOrderExecute) {
+ return slack.sendMessage(
+ `${symbol} ${side.toUpperCase()} Grid Trade #${humanisedGridTradeIndex} Order Filled (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): *${type}*\n` +
+ `- Order Result: \`\`\`${JSON.stringify(
+ orderResult,
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+ }
+
+ return true;
+};
+
+/**
+ * Send slack message for order deleted
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} side
+ * @param {*} orderParams
+ * @param {*} orderResult
+ * @param {*} notifyOrderExecute
+ */
+const slackMessageOrderDeleted = async (
+ logger,
+ symbol,
+ side,
+ orderParams,
+ orderResult,
+ notifyOrderExecute
+) => {
+ const type = orderParams.type.toUpperCase();
+
+ const humanisedGridTradeIndex = orderParams.currentGridTradeIndex + 1;
+
+ PubSub.publish('frontend-notification', {
+ type: 'success',
+ title:
+ `The ${side} order of the grid trade #${humanisedGridTradeIndex} ` +
+ `for ${symbol} is ${orderResult.status}. Stop monitoring.`
+ });
+
+ if (notifyOrderExecute) {
+ return slack.sendMessage(
+ `${symbol} ${side.toUpperCase()} Grid Trade #${humanisedGridTradeIndex} Order Removed (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): *${type}*\n` +
+ `- Order Result: \`\`\`${JSON.stringify(
+ orderResult,
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+ }
+ return true;
+};
+
+/**
+ * Save grid trade to database
+ *
+ * @param {*} logger
+ * @param {*} rawData
+ * @param {*} order
+ */
+const saveGridTrade = async (logger, rawData, order) => {
+ const {
+ symbol,
+ featureToggle: { notifyDebug },
+ symbolConfiguration: {
+ buy: { gridTrade: buyGridTrade },
+ sell: { gridTrade: sellGridTrade }
+ }
+ } = rawData;
+ // Assummed grid trade in the symbol configuration is already up to date.
+ const { side, type, currentGridTradeIndex } = order;
+
+ const newGridTrade = {
+ buy: buyGridTrade,
+ sell: sellGridTrade
+ };
+ logger.info(
+ { side, currentGridTradeIndex, newGridTrade },
+ 'Grid trade before updating'
+ );
+
+ const selectedSide = side.toLowerCase();
+
+ const currentGridTrade = newGridTrade[selectedSide][currentGridTradeIndex];
+
+ currentGridTrade.executed = true;
+ currentGridTrade.executedOrder = order;
+
+ newGridTrade[selectedSide][currentGridTradeIndex] = currentGridTrade;
+ logger.info({ symbol, newGridTrade }, 'Saving grid trade');
+
+ if (notifyDebug) {
+ slack.sendMessage(
+ `${symbol} ${side.toUpperCase()} Grid Trade Updated (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): *${type}*\n` +
+ `- New Gird Trade: \`\`\`${JSON.stringify(
+ newGridTrade,
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+ }
+ return saveSymbolGridTrade(logger, symbol, newGridTrade);
+};
+
+/**
+ * Ensure order is executed
+ *
+ * @param {*} logger
+ * @param {*} rawData
+ */
+const execute = async (logger, rawData) => {
+ const data = rawData;
+
+ const {
+ symbol,
+ action,
+ featureToggle: { notifyOrderExecute, notifyDebug },
+ symbolConfiguration: {
+ system: {
+ checkOrderExecutePeriod,
+ temporaryDisableActionAfterConfirmingOrder
+ }
+ }
+ } = data;
+
+ if (action !== 'not-determined') {
+ logger.info(
+ { action },
+ 'Action is already defined, do not try to ensure grid order executed.'
+ );
+ return data;
+ }
+
+ if (isExceedAPILimit(logger)) {
+ logger.info(
+ { action },
+ 'The API limit is exceed, do not try to ensure grid order executed.'
+ );
+ return data;
+ }
+
+ const removeStatuses = ['CANCELED', 'REJECTED', 'EXPIRED', 'PENDING_CANCEL'];
+
+ // Ensure buy order executed
+ const lastBuyOrder = await getGridTradeLastOrder(logger, symbol, 'buy');
+ if (_.isEmpty(lastBuyOrder) === false) {
+ logger.info(
+ { debug: true, lastBuyOrder },
+ 'Last grid trade buy order found'
+ );
+
+ // If filled already, then calculate average price and save
+ if (lastBuyOrder.status === 'FILLED') {
+ logger.info(
+ { lastBuyOrder },
+ 'Order has already filled, calculate last buy price.'
+ );
+
+ // Calculate last buy price
+ await calculateLastBuyPrice(logger, symbol, lastBuyOrder);
+
+ // Save grid trade to the database
+ const saveGridTradeResult = await saveGridTrade(
+ logger,
+ data,
+ lastBuyOrder
+ );
+
+ if (notifyDebug) {
+ slack.sendMessage(
+ `${symbol} BUY Grid Trade Updated Result (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): \n` +
+ `- Save Grid Trade Result: \`\`\`${JSON.stringify(
+ saveGridTradeResult,
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+ }
+
+ // Remove grid trade last order
+ await removeGridTradeLastOrder(logger, symbol, 'buy');
+
+ // Save order
+ await saveOrder(logger, {
+ order: { ...lastBuyOrder },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has already filled and updated the last buy price.'
+ }
+ });
+
+ slackMessageOrderFilled(
+ logger,
+ symbol,
+ lastBuyOrder.side,
+ lastBuyOrder,
+ lastBuyOrder,
+ notifyOrderExecute
+ );
+
+ // Lock symbol action configured seconds to avoid immediate action
+ await disableAction(
+ symbol,
+ {
+ disabledBy: 'buy filled order',
+ message: 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ temporaryDisableActionAfterConfirmingOrder
+ );
+ } else {
+ // If not filled, check orders is time to check or not
+ const nextCheck = _.get(lastBuyOrder, 'nextCheck', null);
+ if (moment(nextCheck) < moment()) {
+ // Check orders whether it's filled or not
+ let orderResult;
+ try {
+ orderResult = await binance.client.getOrder({
+ symbol,
+ orderId: lastBuyOrder.orderId
+ });
+ } catch (e) {
+ logger.error(
+ { e },
+ 'The order could not be found or error occurred querying the order.'
+ );
+ const updatedNextCheck = moment().add(
+ checkOrderExecutePeriod,
+ 'seconds'
+ );
+
+ logger.info(
+ {
+ e,
+ lastBuyOrder,
+ checkOrderExecutePeriod,
+ nextCheck: updatedNextCheck
+ },
+ 'The order could not be found or error occurred querying the order.'
+ );
+
+ // Set last order to be checked later
+ await updateGridTradeLastOrder(logger, symbol, 'buy', {
+ ...lastBuyOrder,
+ nextCheck: updatedNextCheck
+ });
+
+ // Save order
+ await saveOrder(logger, {
+ order: { ...lastBuyOrder },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order could not be found or error occurred querying the order.'
+ }
+ });
+
+ return data;
+ }
+
+ // If filled, then calculate average cost and quantity and save new last buy pirce.
+ if (orderResult.status === 'FILLED') {
+ logger.info(
+ { lastBuyOrder },
+ 'The order is filled, caluclate last buy price.'
+ );
+
+ // Calculate last buy price
+ await calculateLastBuyPrice(logger, symbol, orderResult);
+
+ // Save grid trade to the database
+ const saveGridTradeResult = await saveGridTrade(logger, data, {
+ ...lastBuyOrder,
+ ...orderResult
+ });
+
+ if (notifyDebug) {
+ slack.sendMessage(
+ `${symbol} BUY Grid Trade Updated Result (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): \n` +
+ `- Save Grid Trade Result: \`\`\`${JSON.stringify(
+ saveGridTradeResult,
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+ }
+
+ // Remove grid trade last order
+ await removeGridTradeLastOrder(logger, symbol, 'buy');
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...lastBuyOrder,
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has filled and updated the last buy price.'
+ }
+ });
+
+ slackMessageOrderFilled(
+ logger,
+ symbol,
+ lastBuyOrder.side,
+ lastBuyOrder,
+ orderResult,
+ notifyOrderExecute
+ );
+
+ // Lock symbol action configured seconds to avoid immediate action
+ await disableAction(
+ symbol,
+ {
+ disabledBy: 'buy filled order',
+ message:
+ 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ temporaryDisableActionAfterConfirmingOrder
+ );
+ } else if (removeStatuses.includes(orderResult.status) === true) {
+ // If order is no longer available, then delete from cache
+ await removeGridTradeLastOrder(logger, symbol, 'buy');
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...lastBuyOrder,
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order is no longer valid. Removed from the cache.'
+ }
+ });
+
+ slackMessageOrderDeleted(
+ logger,
+ symbol,
+ lastBuyOrder.side,
+ lastBuyOrder,
+ orderResult,
+ notifyOrderExecute
+ );
+ } else {
+ // If not filled, update next check time
+ const updatedNextCheck = moment().add(
+ checkOrderExecutePeriod,
+ 'seconds'
+ );
+
+ logger.info(
+ {
+ orderResult,
+ checkOrderExecutePeriod,
+ nextCheck: updatedNextCheck
+ },
+ 'The order is not filled, update next check time.'
+ );
+
+ await updateGridTradeLastOrder(logger, symbol, 'buy', {
+ ...orderResult,
+ currentGridTradeIndex: lastBuyOrder.currentGridTradeIndex,
+ nextCheck: updatedNextCheck
+ });
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage: 'The order is not filled. Check next internal.'
+ }
+ });
+ }
+ } else {
+ logger.info(
+ { lastBuyOrder, nextCheck, currentTime: moment() },
+ 'Skip checking the grid trade last buy order'
+ );
+ }
+ }
+ }
+
+ // Ensure buy order executed
+ const lastSellOrder = await getGridTradeLastOrder(logger, symbol, 'sell');
+ if (_.isEmpty(lastSellOrder) === false) {
+ logger.info(
+ { debug: true, lastSellOrder },
+ 'Last grid trade sell order found'
+ );
+
+ // If filled already, then calculate average price and save
+ if (lastSellOrder.status === 'FILLED') {
+ logger.info({ lastSellOrder }, 'Order has already filled.');
+
+ // Save grid trade to the database
+ const saveGridTradeResult = await saveGridTrade(
+ logger,
+ data,
+ lastSellOrder
+ );
+ if (notifyDebug) {
+ slack.sendMessage(
+ `${symbol} SELL Grid Trade Updated Result (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): \n` +
+ `- Save Grid Trade Result: \`\`\`${JSON.stringify(
+ saveGridTradeResult,
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+ }
+
+ // Remove grid trade last order
+ await removeGridTradeLastOrder(logger, symbol, 'sell');
+
+ // Save order
+ await saveOrder(logger, {
+ order: { ...lastSellOrder },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has already filled and updated the last buy price.'
+ }
+ });
+
+ slackMessageOrderFilled(
+ logger,
+ symbol,
+ lastSellOrder.side,
+ lastSellOrder,
+ lastSellOrder,
+ notifyOrderExecute
+ );
+
+ // Lock symbol action configured seconds to avoid immediate action
+ await disableAction(
+ symbol,
+ {
+ disabledBy: 'sell filled order',
+ message: 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ temporaryDisableActionAfterConfirmingOrder
+ );
+ } else {
+ // If not filled, check orders is time to check or not
+ const nextCheck = _.get(lastSellOrder, 'nextCheck', null);
+
+ if (moment(nextCheck) < moment()) {
+ // Check orders whether it's filled or not
+ let orderResult;
+ try {
+ orderResult = await binance.client.getOrder({
+ symbol,
+ orderId: lastSellOrder.orderId
+ });
+ } catch (e) {
+ logger.error(
+ { e },
+ 'The order could not be found or error occurred querying the order.'
+ );
+ const updatedNextCheck = moment().add(
+ checkOrderExecutePeriod,
+ 'seconds'
+ );
+
+ logger.info(
+ {
+ e,
+ lastSellOrder,
+ checkOrderExecutePeriod,
+ nextCheck: updatedNextCheck
+ },
+ 'The order could not be found or error occurred querying the order.'
+ );
+
+ // Set last order to be checked later
+ await updateGridTradeLastOrder(logger, symbol, 'sell', {
+ ...lastSellOrder,
+ nextCheck: updatedNextCheck
+ });
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...lastSellOrder
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order could not be found or error occurred querying the order.'
+ }
+ });
+
+ return data;
+ }
+
+ // If filled, then calculate average cost and quantity and save new last buy pirce.
+ if (orderResult.status === 'FILLED') {
+ logger.info({ lastSellOrder }, 'The order is filled.');
+
+ // Save grid trade to the database
+ const saveGridTradeResult = await saveGridTrade(logger, data, {
+ ...lastSellOrder,
+ ...orderResult
+ });
+
+ if (notifyDebug) {
+ slack.sendMessage(
+ `${symbol} SELL Grid Trade Updated Result (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): \n` +
+ `- Save Grid Trade Result: \`\`\`${JSON.stringify(
+ saveGridTradeResult,
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+ }
+
+ // Remove grid trade last order
+ await removeGridTradeLastOrder(logger, symbol, 'sell');
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...lastSellOrder,
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order has filled and updated the last buy price.'
+ }
+ });
+
+ slackMessageOrderFilled(
+ logger,
+ symbol,
+ lastSellOrder.side,
+ lastSellOrder,
+ orderResult,
+ notifyOrderExecute
+ );
+
+ // Lock symbol action configured seconds to avoid immediate action
+ await disableAction(
+ symbol,
+ {
+ disabledBy: 'sell filled order',
+ message:
+ 'Disabled action after founding filled grid trade order .',
+ canResume: false,
+ canRemoveLastBuyPrice: false
+ },
+ temporaryDisableActionAfterConfirmingOrder
+ );
+ } else if (removeStatuses.includes(orderResult.status) === true) {
+ // If order is no longer available, then delete from cache
+ await removeGridTradeLastOrder(logger, symbol, 'sell');
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...lastSellOrder,
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage:
+ 'The order is no longer valid. Removed from the cache.'
+ }
+ });
+
+ slackMessageOrderDeleted(
+ logger,
+ symbol,
+ lastSellOrder.side,
+ lastSellOrder,
+ orderResult,
+ notifyOrderExecute
+ );
+ } else {
+ // If not filled, update next check time
+ const updatedNextCheck = moment().add(
+ checkOrderExecutePeriod,
+ 'seconds'
+ );
+
+ logger.info(
+ {
+ orderResult,
+ checkOrderExecutePeriod,
+ nextCheck: updatedNextCheck
+ },
+ 'The order is not filled, update next check time.'
+ );
+
+ await updateGridTradeLastOrder(logger, symbol, 'sell', {
+ ...orderResult,
+ currentGridTradeIndex: lastSellOrder.currentGridTradeIndex,
+ nextCheck: updatedNextCheck
+ });
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-grid-trade-order-executed',
+ savedMessage: 'The order is not filled. Check next internal.'
+ }
+ });
+ }
+ } else {
+ logger.info(
+ { lastSellOrder, nextCheck, currentTime: moment() },
+ 'Skip checking the grid trade last buy order'
+ );
+ }
+ }
+ }
+
+ return data;
+};
+
+module.exports = { execute };
diff --git a/app/cronjob/trailingTrade/step/ensure-manual-buy-order.js b/app/cronjob/trailingTrade/step/ensure-manual-buy-order.js
index 73da2bd9..ca5db571 100644
--- a/app/cronjob/trailingTrade/step/ensure-manual-buy-order.js
+++ b/app/cronjob/trailingTrade/step/ensure-manual-buy-order.js
@@ -3,75 +3,11 @@ const moment = require('moment');
const _ = require('lodash');
const { cache, PubSub, binance, slack } = require('../../../helpers');
const {
- getLastBuyPrice,
- saveLastBuyPrice,
- getAPILimit
+ calculateLastBuyPrice,
+ getAPILimit,
+ saveOrder
} = require('../../trailingTradeHelper/common');
-/**
- * Retrieve last buy price and recalculate new last buy price
- *
- * @param {*} logger
- * @param {*} symbol
- * @param {*} order
- */
-const calculateLastBuyPrice = async (logger, symbol, order) => {
- const { orderId, type, executedQty, cummulativeQuoteQty } = order;
- const lastBuyPriceDoc = await getLastBuyPrice(logger, symbol);
-
- const orgLastBuyPrice = _.get(lastBuyPriceDoc, 'lastBuyPrice', 0);
- const orgQuantity = _.get(lastBuyPriceDoc, 'quantity', 0);
- const orgTotalAmount = orgLastBuyPrice * orgQuantity;
-
- logger.info(
- { orgLastBuyPrice, orgQuantity, orgTotalAmount },
- 'Existing last buy price'
- );
-
- const filledQuoteQty = parseFloat(cummulativeQuoteQty);
- const filledQuantity = parseFloat(executedQty);
-
- const newQuantity = orgQuantity + filledQuantity;
- const newTotalAmount = orgTotalAmount + filledQuoteQty;
-
- const newLastBuyPrice = newTotalAmount / newQuantity;
-
- logger.info(
- { newLastBuyPrice, newTotalAmount, newQuantity },
- 'New last buy price'
- );
- await saveLastBuyPrice(logger, symbol, {
- lastBuyPrice: newLastBuyPrice,
- quantity: newQuantity
- });
-
- await cache.hdel(`trailing-trade-manual-buy-order-${symbol}`, orderId);
-
- PubSub.publish('frontend-notification', {
- type: 'success',
- title: `New last buy price for ${symbol} has been updated.`
- });
-
- slack.sendMessage(
- `${symbol} Last buy price Updated (${moment().format(
- 'HH:mm:ss.SSS'
- )}): *${type}*\n` +
- `- Order Result: \`\`\`${JSON.stringify(
- {
- orgLastBuyPrice,
- orgQuantity,
- orgTotalAmount,
- newLastBuyPrice,
- newQuantity,
- newTotalAmount
- },
- undefined,
- 2
- )}\`\`\`\n` +
- `- Current API Usage: ${getAPILimit(logger)}`
- );
-};
-
/**
* Send slack message for order filled
*
@@ -186,6 +122,21 @@ const execute = async (logger, rawData) => {
'Order has already filled, calculate last buy price.'
);
await calculateLastBuyPrice(logger, symbol, buyOrder);
+ await cache.hdel(
+ `trailing-trade-manual-buy-order-${symbol}`,
+ buyOrder.orderId
+ );
+
+ // Save order
+ await saveOrder(logger, {
+ order: { ...buyOrder },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order has already filled and updated the last buy price.'
+ }
+ });
} else {
// If not filled, check orders is time to check or not
@@ -228,6 +179,17 @@ const execute = async (logger, rawData) => {
})
);
+ // Save order
+ await saveOrder(logger, {
+ order: { ...buyOrder },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order could not be found or error occurred querying the order.'
+ }
+ });
+
return data;
}
@@ -245,6 +207,23 @@ const execute = async (logger, rawData) => {
orderResult
);
await calculateLastBuyPrice(logger, symbol, orderResult);
+
+ // Remove manual buy order
+ await cache.hdel(
+ `trailing-trade-manual-buy-order-${symbol}`,
+ orderResult.orderId
+ );
+
+ // Save order
+ await saveOrder(logger, {
+ order: { ...buyOrder, ...orderResult },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order has filled and updated the last buy price.'
+ }
+ });
} else if (removeStatuses.includes(orderResult.status) === true) {
// If order is no longer available, then delete from cache
await cache.hdel(
@@ -252,6 +231,17 @@ const execute = async (logger, rawData) => {
orderResult.orderId
);
+ // Save order
+ await saveOrder(logger, {
+ order: { ...buyOrder, ...orderResult },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage:
+ 'The order is no longer valid. Removed from the cache.'
+ }
+ });
+
slackMessageOrderDeleted(
logger,
symbol,
@@ -283,6 +273,16 @@ const execute = async (logger, rawData) => {
nextCheck: updatedNextCheck
})
);
+
+ // Save order
+ await saveOrder(logger, {
+ order: { ...orderResult },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-manual-buy-order',
+ savedMessage: 'The order is not filled. Check next internal.'
+ }
+ });
}
} else {
logger.info(
diff --git a/app/cronjob/trailingTrade/step/ensure-order-placed.js b/app/cronjob/trailingTrade/step/ensure-order-placed.js
index a3c73259..5ef11bf3 100644
--- a/app/cronjob/trailingTrade/step/ensure-order-placed.js
+++ b/app/cronjob/trailingTrade/step/ensure-order-placed.js
@@ -7,7 +7,8 @@ const {
getAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI,
disableAction,
- getAPILimit
+ getAPILimit,
+ saveOrder
} = require('../../trailingTradeHelper/common');
/**
@@ -179,6 +180,18 @@ const execute = async (logger, rawData) => {
);
}
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...lastBuyOrder
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-order-placed',
+ savedMessage: 'The order is found in the open orders.'
+ }
+ });
+
// Lock symbol action 20 seconds to avoid API limit
await disableAction(
symbol,
@@ -273,6 +286,18 @@ const execute = async (logger, rawData) => {
);
}
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...lastSellOrder
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'ensure-order-placed',
+ savedMessage: 'The order is found in the open orders.'
+ }
+ });
+
// Lock symbol action 20 seconds to avoid API limit
await disableAction(
symbol,
diff --git a/app/cronjob/trailingTrade/step/get-indicators.js b/app/cronjob/trailingTrade/step/get-indicators.js
index afcec583..0c3459a5 100644
--- a/app/cronjob/trailingTrade/step/get-indicators.js
+++ b/app/cronjob/trailingTrade/step/get-indicators.js
@@ -20,16 +20,15 @@ const execute = async (logger, rawData) => {
},
symbolConfiguration: {
buy: {
- triggerPercentage: buyTriggerPercentage,
- limitPercentage: buyLimitPercentage,
+ currentGridTradeIndex: currentBuyGridTradeIndex,
+ currentGridTrade: currentBuyGridTrade,
athRestriction: {
enabled: buyATHRestrictionEnabled,
restrictionPercentage: buyATHRestrictionPercentage
}
},
sell: {
- triggerPercentage: sellTriggerPercentage,
- limitPercentage: sellLimitPercentage,
+ currentGridTrade: currentSellGridTrade,
stopLoss: { maxLossPercentage: sellMaxLossPercentage }
}
},
@@ -67,27 +66,61 @@ const execute = async (logger, rawData) => {
...cachedIndicator
};
- // Cast string to number
const { highestPrice, lowestPrice, athPrice } = data.indicators;
- const currentPrice = parseFloat(cachedLatestCandle.close);
- const buyTriggerPrice = lowestPrice * buyTriggerPercentage;
- const buyDifference = (1 - currentPrice / buyTriggerPrice) * -100;
- const buyLimitPrice = currentPrice * buyLimitPercentage;
- let buyATHRestrictionPrice = null;
- if (buyATHRestrictionEnabled) {
- buyATHRestrictionPrice = athPrice * buyATHRestrictionPercentage;
- }
+ // Get current price
+ const currentPrice = parseFloat(cachedLatestCandle.close);
// Get last buy price
const lastBuyPriceDoc = await getLastBuyPrice(logger, symbol);
const lastBuyPrice = _.get(lastBuyPriceDoc, 'lastBuyPrice', null);
- const sellTriggerPrice =
- lastBuyPrice > 0 ? lastBuyPrice * sellTriggerPercentage : null;
- const sellDifference =
- lastBuyPrice > 0 ? (1 - sellTriggerPrice / currentPrice) * 100 : null;
- const sellLimitPrice = currentPrice * sellLimitPercentage;
+ // #### Buy related variables
+ // Set trigger price to be null which will prevent to buy.
+ let buyTriggerPrice = null;
+ let buyDifference = null;
+ let buyLimitPrice = null;
+ if (currentBuyGridTrade !== null) {
+ const {
+ triggerPercentage: buyTriggerPercentage,
+ limitPercentage: buyLimitPercentage
+ } = currentBuyGridTrade;
+
+ // If grid trade index is 0 or last buy price is null, then use lowest price as trigger price.
+ // If grid trade index is not 0 and last buy price is not null, then use last buy price
+ const triggerPrice =
+ currentBuyGridTradeIndex !== 0 && lastBuyPrice !== null
+ ? lastBuyPrice
+ : lowestPrice;
+
+ buyTriggerPrice = triggerPrice * buyTriggerPercentage;
+ buyDifference = (1 - currentPrice / buyTriggerPrice) * -100;
+ buyLimitPrice = currentPrice * buyLimitPercentage;
+ }
+
+ let buyATHRestrictionPrice = null;
+ if (buyATHRestrictionEnabled) {
+ buyATHRestrictionPrice = athPrice * buyATHRestrictionPercentage;
+ }
+ // ##############################
+
+ // #### Sell related variables
+ // Set trigger price to be null which will prevent to sell.
+ let sellTriggerPrice = null;
+ let sellDifference = null;
+ let sellLimitPrice = null;
+
+ if (lastBuyPrice > 0 && currentSellGridTrade !== null) {
+ const {
+ triggerPercentage: sellTriggerPercentage,
+ limitPercentage: sellLimitPercentage
+ } = currentSellGridTrade;
+
+ sellTriggerPrice = lastBuyPrice * sellTriggerPercentage;
+ sellDifference = (1 - sellTriggerPrice / currentPrice) * 100;
+ sellLimitPrice = currentPrice * sellLimitPercentage;
+ }
+ // ##############################
// Get stop loss trigger price
const sellStopLossTriggerPrice =
@@ -121,22 +154,22 @@ const execute = async (logger, rawData) => {
}
if (order.side.toLowerCase() === 'buy') {
- newOrder.limitPrice = buyLimitPrice;
- newOrder.limitPercentage = buyLimitPercentage;
newOrder.differenceToExecute =
(1 - parseFloat(order.stopPrice / currentPrice)) * 100;
newOrder.differenceToCancel =
- (1 - parseFloat(order.stopPrice / buyLimitPrice)) * 100;
+ buyLimitPrice > 0
+ ? (1 - parseFloat(order.stopPrice / buyLimitPrice)) * 100
+ : null;
}
if (order.side.toLowerCase() === 'sell') {
- newOrder.limitPrice = sellLimitPrice;
- newOrder.limitPercentage = sellLimitPercentage;
newOrder.differenceToExecute =
(1 - parseFloat(order.stopPrice / currentPrice)) * 100;
newOrder.differenceToCancel =
- (1 - parseFloat(order.stopPrice / sellLimitPrice)) * 100;
+ sellLimitPrice > 0
+ ? (1 - parseFloat(order.stopPrice / sellLimitPrice)) * 100
+ : null;
newOrder.minimumProfit = null;
newOrder.minimumProfitPercentage = null;
diff --git a/app/cronjob/trailingTrade/step/get-override-action.js b/app/cronjob/trailingTrade/step/get-override-action.js
index 944c2ff6..103250fd 100644
--- a/app/cronjob/trailingTrade/step/get-override-action.js
+++ b/app/cronjob/trailingTrade/step/get-override-action.js
@@ -37,12 +37,13 @@ const execute = async (logger, rawData) => {
// Override action
if (
- (_.get(overrideData, 'action') === 'manual-trade' ||
+ (_.get(overrideData, 'action') === 'buy' ||
+ _.get(overrideData, 'action') === 'manual-trade' ||
_.get(overrideData, 'action') === 'cancel-order') &&
moment(_.get(overrideData, 'actionAt', undefined)) <= moment()
) {
data.action = overrideData.action;
- data.order = overrideData.order;
+ data.order = overrideData.order || {};
// Remove override data to avoid multiple execution
await removeOverrideDataForSymbol(logger, symbol);
return data;
diff --git a/app/cronjob/trailingTrade/step/place-buy-order.js b/app/cronjob/trailingTrade/step/place-buy-order.js
index 5d6e317f..ebc7181c 100644
--- a/app/cronjob/trailingTrade/step/place-buy-order.js
+++ b/app/cronjob/trailingTrade/step/place-buy-order.js
@@ -1,12 +1,12 @@
const _ = require('lodash');
const moment = require('moment');
-const { binance, slack, mongo, cache } = require('../../../helpers');
-const { roundDown } = require('../../trailingTradeHelper/util');
+const { binance, slack, cache } = require('../../../helpers');
const {
getAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI,
isExceedAPILimit,
- getAPILimit
+ getAPILimit,
+ saveOrder
} = require('../../trailingTradeHelper/common');
/**
@@ -21,6 +21,7 @@ const execute = async (logger, rawData) => {
const {
symbol,
isLocked,
+ featureToggle: { notifyDebug },
symbolInfo: {
baseAsset,
quoteAsset,
@@ -29,18 +30,16 @@ const execute = async (logger, rawData) => {
filterMinNotional: { minNotional }
},
symbolConfiguration: {
- buy: {
- enabled: tradingEnabled,
- maxPurchaseAmount,
- stopPercentage,
- limitPercentage
- }
+ buy: { enabled: tradingEnabled, currentGridTradeIndex, currentGridTrade },
+ system: { checkOrderExecutePeriod }
},
action,
quoteAssetBalance: { free: quoteAssetFreeBalance },
buy: { currentPrice, openOrders }
} = data;
+ const humanisedGridTradeIndex = currentGridTradeIndex + 1;
+
if (isLocked) {
logger.info(
{ isLocked },
@@ -55,12 +54,23 @@ const execute = async (logger, rawData) => {
}
if (openOrders.length > 0) {
- data.buy.processMessage = `There are open orders for ${symbol}. Do not place an order.`;
+ data.buy.processMessage =
+ `There are open orders for ${symbol}. ` +
+ `Do not place an order for the grid trade #${humanisedGridTradeIndex}.`;
+ data.buy.updatedAt = moment().utc();
+
+ return data;
+ }
+
+ if (currentGridTrade === null) {
+ data.buy.processMessage = `Current grid trade is not defined. Cannot place an order.`;
data.buy.updatedAt = moment().utc();
return data;
}
+ const { maxPurchaseAmount, stopPercentage, limitPercentage } =
+ currentGridTrade;
if (maxPurchaseAmount <= 0) {
data.buy.processMessage =
'Max purchase amount must be configured. Please configure symbol settings.';
@@ -74,11 +84,15 @@ const execute = async (logger, rawData) => {
'Attempting to place buy order'
);
- const lotPrecision = parseFloat(stepSize) === 1 ? 0 : stepSize.indexOf(1) - 1;
- const pricePrecision =
+ const lotStepSizePrecision =
+ parseFloat(stepSize) === 1 ? 0 : stepSize.indexOf(1) - 1;
+ const priceTickPrecision =
parseFloat(tickSize) === 1 ? 0 : tickSize.indexOf(1) - 1;
- let freeBalance = parseFloat(_.floor(quoteAssetFreeBalance, pricePrecision));
+ const orgFreeBalance = parseFloat(
+ _.floor(quoteAssetFreeBalance, priceTickPrecision)
+ );
+ let freeBalance = orgFreeBalance;
logger.info({ freeBalance }, 'Free balance');
if (freeBalance > maxPurchaseAmount) {
@@ -87,43 +101,84 @@ const execute = async (logger, rawData) => {
}
if (freeBalance < parseFloat(minNotional)) {
- data.buy.processMessage = `Do not place a buy order as not enough ${quoteAsset} to buy ${baseAsset}.`;
+ data.buy.processMessage =
+ `Do not place a buy order for the grid trade #${humanisedGridTradeIndex} ` +
+ `as not enough ${quoteAsset} to buy ${baseAsset}.`;
data.buy.updatedAt = moment().utc();
return data;
}
- const stopPrice = roundDown(currentPrice * stopPercentage, pricePrecision);
- const limitPrice = roundDown(currentPrice * limitPercentage, pricePrecision);
+ const stopPrice = _.floor(currentPrice * stopPercentage, priceTickPrecision);
+ const limitPrice = _.floor(
+ currentPrice * limitPercentage,
+ priceTickPrecision
+ );
logger.info({ stopPrice, limitPrice }, 'Stop price and limit price');
- const orderQuantityBeforeCommission = 1 / (limitPrice / freeBalance);
+ const orderQuantityBeforeCommission = parseFloat(
+ _.ceil(freeBalance / limitPrice, lotStepSizePrecision)
+ );
logger.info(
{ orderQuantityBeforeCommission },
'Order quantity before commission'
);
- const orderQuantity = parseFloat(
+ let orderQuantity = parseFloat(
_.floor(
orderQuantityBeforeCommission -
orderQuantityBeforeCommission * (0.1 / 100),
- lotPrecision
+ lotStepSizePrecision
)
);
+ // If free balance is exactly same as minimum notional, then it will be failed to place the order
+ // because it will be always less than minimum notional after calculating commission.
+ // To avoid the minimum notional issue, add commission to free balance
+
+ if (
+ orgFreeBalance > parseFloat(minNotional) &&
+ maxPurchaseAmount === parseFloat(minNotional)
+ ) {
+ // Note: For some reason, Binance rejects the order with exact amount of minimum notional amount.
+ // For example,
+ // - Calculated limit price: 289.48 (current price) * 1.026 (limit percentage) = 297
+ // - Calcuated order quantity: 0.0337
+ // - Calculated quote amount: 297 * 0.0337 = 10.0089, which is over minimum notional value 10.
+ // Above the order is rejected by Binance with MIN_NOTIONAL error.
+ // As a result, I had to re-calculate if max purchase amount is exactly same as minimum notional value.
+ orderQuantity = parseFloat(
+ _.ceil(
+ (freeBalance + freeBalance * (0.1 / 100)) / limitPrice,
+ lotStepSizePrecision
+ )
+ );
+ }
+
logger.info({ orderQuantity }, 'Order quantity after commission');
if (orderQuantity * limitPrice < parseFloat(minNotional)) {
- data.buy.processMessage =
- `Do not place a buy order as not enough ${quoteAsset} ` +
- `to buy ${baseAsset} after calculation.`;
+ const processMessage =
+ `Do not place a buy order for the grid trade #${humanisedGridTradeIndex} ` +
+ `as not enough ${quoteAsset} ` +
+ `to buy ${baseAsset} after calculating commission - Order amount: ${_.floor(
+ orderQuantity * limitPrice,
+ priceTickPrecision
+ )} ${quoteAsset}, Minimum notional: ${minNotional}.`;
+ logger.info(
+ { calculatedAmount: orderQuantity * limitPrice, minNotional },
+ processMessage
+ );
+ data.buy.processMessage = processMessage;
data.buy.updatedAt = moment().utc();
return data;
}
if (tradingEnabled !== true) {
- data.buy.processMessage = `Trading for ${symbol} is disabled. Do not place an order.`;
+ data.buy.processMessage =
+ `Trading for ${symbol} is disabled. ` +
+ `Do not place an order for the grid trade #${humanisedGridTradeIndex}.`;
data.buy.updatedAt = moment().utc();
return data;
@@ -146,12 +201,29 @@ const execute = async (logger, rawData) => {
timeInForce: 'GTC'
};
+ const notifyMessage = { orderParams };
+ if (notifyDebug) {
+ notifyMessage.calculationParams = {
+ quoteAssetFreeBalance,
+ priceTickPrecision,
+ lotStepSizePrecision,
+ minNotional,
+ maxPurchaseAmount,
+ freeBalance,
+ orderQuantityBeforeCommission,
+ orderQuantity,
+ currentPrice,
+ stopPercentage,
+ limitPrice
+ };
+ }
+
slack.sendMessage(
- `${symbol} Buy Action (${moment().format(
+ `${symbol} Buy Action Grid Trade #${humanisedGridTradeIndex} (${moment().format(
'HH:mm:ss.SSS'
)}): *STOP_LOSS_LIMIT*\n` +
`- Order Params: \`\`\`${JSON.stringify(
- orderParams,
+ notifyMessage,
undefined,
2
)}\`\`\`\n` +
@@ -169,18 +241,27 @@ const execute = async (logger, rawData) => {
// Set last buy order to be checked over 2 minutes
await cache.set(`${symbol}-last-buy-order`, JSON.stringify(orderResult), 120);
- await mongo.upsertOne(
- logger,
- 'trailing-trade-symbols',
- {
- key: `${symbol}-last-buy-price`
+ // Set last buy grid order to be checked until it is executed
+ await cache.set(
+ `${symbol}-grid-trade-last-buy-order`,
+ JSON.stringify({
+ ...orderResult,
+ currentGridTradeIndex,
+ nextCheck: moment().add(checkOrderExecutePeriod, 'seconds')
+ })
+ );
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...orderResult
},
- {
- key: `${symbol}-last-buy-price`,
- lastBuyPrice: limitPrice,
- quantity: orderQuantity
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'place-buy-order',
+ savedMessage: 'The buy order is placed.'
}
- );
+ });
// Get open orders and update cache
data.openOrders = await getAndCacheOpenOrdersForSymbol(logger, symbol);
@@ -192,7 +273,7 @@ const execute = async (logger, rawData) => {
data.accountInfo = await getAccountInfoFromAPI(logger);
slack.sendMessage(
- `${symbol} Buy Action Result (${moment().format(
+ `${symbol} Buy Action Grid Trade #${humanisedGridTradeIndex} Result (${moment().format(
'HH:mm:ss.SSS'
)}): *STOP_LOSS_LIMIT*\n` +
`- Order Result: \`\`\`${JSON.stringify(
@@ -202,7 +283,7 @@ const execute = async (logger, rawData) => {
)}\`\`\`\n` +
`- Current API Usage: ${getAPILimit(logger)}`
);
- data.buy.processMessage = `Placed new stop loss limit order for buying.`;
+ data.buy.processMessage = `Placed new stop loss limit order for buying of grid trade #${humanisedGridTradeIndex}.`;
data.buy.updatedAt = moment().utc();
// Save last buy price
diff --git a/app/cronjob/trailingTrade/step/place-manual-trade.js b/app/cronjob/trailingTrade/step/place-manual-trade.js
index b8c2df79..caa73f3d 100644
--- a/app/cronjob/trailingTrade/step/place-manual-trade.js
+++ b/app/cronjob/trailingTrade/step/place-manual-trade.js
@@ -3,7 +3,8 @@ const { binance, slack, cache, PubSub } = require('../../../helpers');
const {
getAPILimit,
getAndCacheOpenOrdersForSymbol,
- getAccountInfoFromAPI
+ getAccountInfoFromAPI,
+ saveOrder
} = require('../../trailingTradeHelper/common');
/**
@@ -208,6 +209,18 @@ const recordOrder = async (logger, orderResult, checkManualBuyOrderPeriod) => {
nextCheck: moment().add(checkManualBuyOrderPeriod, 'seconds')
})
);
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'place-manual-trade',
+ savedMessage: 'The manual order is placed.'
+ }
+ });
} else {
logger.info({ orderResult }, 'Do not record order as it is not BUY order');
}
diff --git a/app/cronjob/trailingTrade/step/place-sell-order.js b/app/cronjob/trailingTrade/step/place-sell-order.js
index a29d60cd..2f01f13e 100644
--- a/app/cronjob/trailingTrade/step/place-sell-order.js
+++ b/app/cronjob/trailingTrade/step/place-sell-order.js
@@ -6,7 +6,8 @@ const {
getAndCacheOpenOrdersForSymbol,
getAccountInfoFromAPI,
isExceedAPILimit,
- getAPILimit
+ getAPILimit,
+ saveOrder
} = require('../../trailingTradeHelper/common');
/**
@@ -27,13 +28,20 @@ const execute = async (logger, rawData) => {
filterMinNotional: { minNotional }
},
symbolConfiguration: {
- sell: { enabled: tradingEnabled, stopPercentage, limitPercentage }
+ sell: {
+ enabled: tradingEnabled,
+ currentGridTradeIndex,
+ currentGridTrade
+ },
+ system: { checkOrderExecutePeriod }
},
action,
baseAssetBalance: { free: baseAssetFreeBalance },
sell: { currentPrice, openOrders }
} = data;
+ const humanisedGridTradeIndex = currentGridTradeIndex + 1;
+
if (isLocked) {
logger.info(
{ isLocked },
@@ -48,12 +56,24 @@ const execute = async (logger, rawData) => {
}
if (openOrders.length > 0) {
- data.sell.processMessage = `There are open orders for ${symbol}. Do not place an order.`;
+ data.sell.processMessage =
+ `There are open orders for ${symbol}. ` +
+ `Do not place an order for the grid trade #${humanisedGridTradeIndex}.`;
+ data.sell.updatedAt = moment().utc();
+
+ return data;
+ }
+
+ if (currentGridTrade === null) {
+ data.sell.processMessage = `Current grid trade is not defined. Do not place an order.`;
data.sell.updatedAt = moment().utc();
return data;
}
+ const { stopPercentage, limitPercentage, quantityPercentage } =
+ currentGridTrade;
+
const lotPrecision = parseFloat(stepSize) === 1 ? 0 : stepSize.indexOf(1) - 1;
const pricePrecision =
parseFloat(tickSize) === 1 ? 0 : tickSize.indexOf(1) - 1;
@@ -64,14 +84,38 @@ const execute = async (logger, rawData) => {
const freeBalance = parseFloat(_.floor(baseAssetFreeBalance, lotPrecision));
logger.info({ freeBalance }, 'Free balance');
+ // If after calculating quantity percentage, it is not enough minimum notional, then simply sell all balance
+
let orderQuantity = parseFloat(
_.floor(freeBalance - freeBalance * (0.1 / 100), lotPrecision)
);
+ // When order quantity multiply quantity percentage is more than minimum notional
+ const orderQuantityWithPercentage = parseFloat(
+ _.floor(
+ freeBalance * quantityPercentage -
+ freeBalance * quantityPercentage * (0.1 / 100),
+ lotPrecision
+ )
+ );
+ logger.info(
+ { orderQuantityWithPercentage: orderQuantity },
+ 'Calculated order quantity with quantity percentage.'
+ );
+
+ if (orderQuantityWithPercentage * limitPrice > parseFloat(minNotional)) {
+ // Then calculate order quantity
+ orderQuantity = orderQuantityWithPercentage;
+ logger.info(
+ { orderQuantityWithPercentage: orderQuantity },
+ 'Apply order quantity with quantity percentage.'
+ );
+ }
+
if (orderQuantity <= parseFloat(minQty)) {
data.sell.processMessage =
`Order quantity is less or equal than the minimum quantity - ${minQty}. ` +
- `Do not place an order.`;
+ `Do not place an order for the grid trade #${humanisedGridTradeIndex}.`;
data.sell.updatedAt = moment().utc();
return data;
@@ -81,21 +125,27 @@ const execute = async (logger, rawData) => {
}
if (orderQuantity * limitPrice < parseFloat(minNotional)) {
- data.sell.processMessage = `Notional value is less than the minimum notional value. Do not place an order.`;
+ data.sell.processMessage =
+ `Notional value is less than the minimum notional value. ` +
+ `Do not place an order for the grid trade #${humanisedGridTradeIndex}.`;
data.sell.updatedAt = moment().utc();
return data;
}
if (tradingEnabled !== true) {
- data.sell.processMessage = `Trading for ${symbol} is disabled. Do not place an order.`;
+ data.sell.processMessage =
+ `Trading for ${symbol} is disabled. ` +
+ `Do not place an order for the grid trade #${humanisedGridTradeIndex}.`;
data.sell.updatedAt = moment().utc();
return data;
}
if (isExceedAPILimit(logger)) {
- data.sell.processMessage = `Binance API limit has been exceeded. Do not place an order.`;
+ data.sell.processMessage =
+ `Binance API limit has been exceeded. ` +
+ `Do not place an order for the grid trade #${humanisedGridTradeIndex}.`;
data.sell.updatedAt = moment().utc();
return data;
@@ -112,7 +162,7 @@ const execute = async (logger, rawData) => {
};
slack.sendMessage(
- `${symbol} Sell Action (${moment().format(
+ `${symbol} Sell Action Grid Trade #${humanisedGridTradeIndex}(${moment().format(
'HH:mm:ss.SSS'
)}): *STOP_LOSS_LIMIT*\n` +
`- Order Params: \`\`\`${JSON.stringify(orderParams, undefined, 2)}\`\`\`
@@ -130,6 +180,28 @@ const execute = async (logger, rawData) => {
await cache.set(`${symbol}-last-sell-order`, JSON.stringify(orderResult), 15);
+ // Set last sell grid order to be checked until it is executed
+ await cache.set(
+ `${symbol}-grid-trade-last-sell-order`,
+ JSON.stringify({
+ ...orderResult,
+ currentGridTradeIndex,
+ nextCheck: moment().add(checkOrderExecutePeriod, 'seconds')
+ })
+ );
+
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'place-sell-order',
+ savedMessage: 'The sell order is placed.'
+ }
+ });
+
// Get open orders and update cache
data.openOrders = await getAndCacheOpenOrdersForSymbol(logger, symbol);
data.sell.openOrders = data.openOrders.filter(
@@ -140,7 +212,7 @@ const execute = async (logger, rawData) => {
data.accountInfo = await getAccountInfoFromAPI(logger);
slack.sendMessage(
- `${symbol} Sell Action Result (${moment().format(
+ `${symbol} Sell Action Grid Trade #${humanisedGridTradeIndex} Result (${moment().format(
'HH:mm:ss.SSS'
)}): *STOP_LOSS_LIMIT*\n` +
`- Order Result: \`\`\`${JSON.stringify(
@@ -150,7 +222,7 @@ const execute = async (logger, rawData) => {
)}\`\`\`\n` +
`- Current API Usage: ${getAPILimit(logger)}`
);
- data.sell.processMessage = `Placed new stop loss limit order for selling.`;
+ data.sell.processMessage = `Placed new stop loss limit order for selling of grid trade #${humanisedGridTradeIndex}.`;
data.sell.updatedAt = moment().utc();
return data;
diff --git a/app/cronjob/trailingTrade/step/place-sell-stop-loss-order.js b/app/cronjob/trailingTrade/step/place-sell-stop-loss-order.js
index 8e15010b..2d52b4f1 100644
--- a/app/cronjob/trailingTrade/step/place-sell-stop-loss-order.js
+++ b/app/cronjob/trailingTrade/step/place-sell-stop-loss-order.js
@@ -6,7 +6,8 @@ const {
getAccountInfoFromAPI,
isExceedAPILimit,
disableAction,
- getAPILimit
+ getAPILimit,
+ saveOrder
} = require('../../trailingTradeHelper/common');
/**
@@ -142,6 +143,18 @@ const execute = async (logger, rawData) => {
logger.info({ orderResult }, 'Market order result');
+ // Save order
+ await saveOrder(logger, {
+ order: {
+ ...orderResult
+ },
+ botStatus: {
+ savedAt: moment().format(),
+ savedBy: 'place-sell-stop-loss-order',
+ savedMessage: 'The sell STOP-LOSS order is placed.'
+ }
+ });
+
// Temporary disable action
await disableAction(
symbol,
diff --git a/app/cronjob/trailingTrade/step/remove-last-buy-price.js b/app/cronjob/trailingTrade/step/remove-last-buy-price.js
index 297cb922..cfd70b2e 100644
--- a/app/cronjob/trailingTrade/step/remove-last-buy-price.js
+++ b/app/cronjob/trailingTrade/step/remove-last-buy-price.js
@@ -6,6 +6,11 @@ const {
getAPILimit,
isActionDisabled
} = require('../../trailingTradeHelper/common');
+
+const {
+ deleteSymbolGridTrade
+} = require('../../trailingTradeHelper/configuration');
+
/**
* Retrieve last buy order from cache
*
@@ -23,6 +28,27 @@ const getLastBuyOrder = async (logger, symbol) => {
return cachedLastBuyOrder;
};
+/**
+ * Retrieve last grid order from cache
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} side
+ * @returns
+ */
+const getGridTradeLastOrder = async (logger, symbol, side) => {
+ const cachedLastOrder =
+ JSON.parse(await cache.get(`${symbol}-grid-trade-last-${side}-order`)) ||
+ {};
+
+ logger.info(
+ { cachedLastOrder },
+ `Retrieved grid trade last ${side} order from cache`
+ );
+
+ return cachedLastOrder;
+};
+
/**
* Remove last buy price
*
@@ -37,10 +63,14 @@ const removeLastBuyPrice = async (
processMessage,
extraMessages
) => {
+ // Delete the last buy price from the database
await mongo.deleteOne(logger, 'trailing-trade-symbols', {
key: `${symbol}-last-buy-price`
});
+ // Delete symbol grid trade
+ await deleteSymbolGridTrade(logger, symbol);
+
slack.sendMessage(
`${symbol} Action (${moment().format(
'HH:mm:ss.SSS'
@@ -103,6 +133,30 @@ const execute = async (logger, rawData) => {
return data;
}
+ const gridTradeLastBuyOrder = await getGridTradeLastOrder(
+ logger,
+ symbol,
+ 'buy'
+ );
+ if (_.isEmpty(gridTradeLastBuyOrder) === false) {
+ logger.info(
+ 'Do not process to remove last buy price because there is a grid trade last buy order to be confirmed.'
+ );
+ return data;
+ }
+
+ const gridTradeLastSellOrder = await getGridTradeLastOrder(
+ logger,
+ symbol,
+ 'sell'
+ );
+ if (_.isEmpty(gridTradeLastSellOrder) === false) {
+ logger.info(
+ 'Do not process to remove last buy price because there is a grid trade last sell order to be confirmed.'
+ );
+ return data;
+ }
+
// If last buy price is null, undefined, 0, NaN or less than 0
if (!lastBuyPrice || lastBuyPrice <= 0) {
logger.info('Do not process because last buy price does not exist.');
diff --git a/app/cronjob/trailingTrade/steps.js b/app/cronjob/trailingTrade/steps.js
index ab4c7318..2f949dd8 100644
--- a/app/cronjob/trailingTrade/steps.js
+++ b/app/cronjob/trailingTrade/steps.js
@@ -8,6 +8,9 @@ const {
execute: ensureManualBuyOrder
} = require('./step/ensure-manual-buy-order');
const { execute: ensureOrderPlaced } = require('./step/ensure-order-placed');
+const {
+ execute: ensureGridTradeOrderExecuted
+} = require('./step/ensure-grid-trade-order-executed');
const { execute: getOpenOrders } = require('./step/get-open-orders');
const { execute: getIndicators } = require('./step/get-indicators');
const { execute: handleOpenOrders } = require('./step/handle-open-orders');
@@ -29,6 +32,7 @@ module.exports = {
getOverrideAction,
ensureManualBuyOrder,
ensureOrderPlaced,
+ ensureGridTradeOrderExecuted,
getOpenOrders,
getIndicators,
handleOpenOrders,
diff --git a/app/cronjob/trailingTradeHelper/__tests__/common.test.js b/app/cronjob/trailingTradeHelper/__tests__/common.test.js
index 3092287d..e44dc59f 100644
--- a/app/cronjob/trailingTradeHelper/__tests__/common.test.js
+++ b/app/cronjob/trailingTradeHelper/__tests__/common.test.js
@@ -6,6 +6,8 @@ describe('common.js', () => {
let cacheMock;
let binanceMock;
let mongoMock;
+ let PubSubMock;
+ let slackMock;
let loggerMock;
let result;
@@ -1218,4 +1220,189 @@ describe('common.js', () => {
);
});
});
+
+ describe('calculateLastBuyPrice', () => {
+ describe('when last buy price is not recorded', () => {
+ beforeEach(async () => {
+ const { logger, mongo, PubSub, slack } = require('../../../helpers');
+
+ loggerMock = logger;
+ mongoMock = mongo;
+ PubSubMock = PubSub;
+ slackMock = slack;
+
+ mongoMock.findOne = jest.fn().mockResolvedValue({});
+ mongoMock.upsertOne = jest.fn().mockResolvedValue(true);
+ PubSubMock.publish = jest.fn().mockResolvedValue(true);
+ slackMock.sendMessage = jest.fn().mockResolvedValue(true);
+
+ commonHelper = require('../common');
+ await commonHelper.calculateLastBuyPrice(loggerMock, 'BTCUSDT', {
+ type: 'buy',
+ executedQty: '0.07840000',
+ cummulativeQuoteQty: '19.94260800'
+ });
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mongoMock.findOne).toHaveBeenCalledWith(
+ loggerMock,
+ 'trailing-trade-symbols',
+ { key: 'BTCUSDT-last-buy-price' }
+ );
+ });
+
+ it('triggers saveLastBuyPrice', () => {
+ expect(mongoMock.upsertOne).toHaveBeenCalledWith(
+ loggerMock,
+ 'trailing-trade-symbols',
+ {
+ key: 'BTCUSDT-last-buy-price'
+ },
+ {
+ key: 'BTCUSDT-last-buy-price',
+ lastBuyPrice: 254.37,
+ quantity: 0.0784
+ }
+ );
+ });
+
+ it('triggers PubSub.publish', () => {
+ expect(PubSubMock.publish).toHaveBeenCalled();
+ });
+
+ it('triggers slack.sendMessage', () => {
+ expect(slackMock.sendMessage).toHaveBeenCalledWith(
+ expect.stringContaining(
+ JSON.stringify(
+ {
+ orgLastBuyPrice: 0,
+ orgQuantity: 0,
+ orgTotalAmount: 0,
+ newLastBuyPrice: 254.37,
+ newQuantity: 0.0784,
+ newTotalAmount: 19.942608
+ },
+ undefined,
+ 2
+ )
+ )
+ );
+ });
+ });
+
+ describe('when last buy price is recorded', () => {
+ beforeEach(async () => {
+ const { logger, mongo, PubSub, slack } = require('../../../helpers');
+
+ loggerMock = logger;
+ mongoMock = mongo;
+ PubSubMock = PubSub;
+ slackMock = slack;
+
+ mongoMock.findOne = jest.fn().mockResolvedValue({
+ lastBuyPrice: 254.37,
+ quantity: 0.0784
+ });
+ mongoMock.upsertOne = jest.fn().mockResolvedValue(true);
+ PubSubMock.publish = jest.fn().mockResolvedValue(true);
+ slackMock.sendMessage = jest.fn().mockResolvedValue(true);
+
+ commonHelper = require('../common');
+ await commonHelper.calculateLastBuyPrice(loggerMock, 'BTCUSDT', {
+ type: 'buy',
+ executedQty: '0.05',
+ cummulativeQuoteQty: '30'
+ });
+ });
+
+ it('triggers getLastBuyPrice', () => {
+ expect(mongoMock.findOne).toHaveBeenCalledWith(
+ loggerMock,
+ 'trailing-trade-symbols',
+ { key: 'BTCUSDT-last-buy-price' }
+ );
+ });
+
+ it('triggers saveLastBuyPrice', () => {
+ expect(mongoMock.upsertOne).toHaveBeenCalledWith(
+ loggerMock,
+ 'trailing-trade-symbols',
+ {
+ key: 'BTCUSDT-last-buy-price'
+ },
+ {
+ key: 'BTCUSDT-last-buy-price',
+ lastBuyPrice: 388.96112149532706,
+ quantity: 0.12840000000000001
+ }
+ );
+ });
+
+ it('triggers PubSub.publish', () => {
+ expect(PubSubMock.publish).toHaveBeenCalled();
+ });
+
+ it('triggers slack.sendMessage', () => {
+ expect(slackMock.sendMessage).toHaveBeenCalledWith(
+ expect.stringContaining(
+ JSON.stringify(
+ {
+ orgLastBuyPrice: 254.37,
+ orgQuantity: 0.0784,
+ orgTotalAmount: 19.942608,
+ newLastBuyPrice: 388.96112149532706,
+ newQuantity: 0.12840000000000001,
+ newTotalAmount: 49.942608
+ },
+ undefined,
+ 2
+ )
+ )
+ );
+ });
+ });
+ });
+
+ describe('saveOrder', () => {
+ beforeEach(async () => {
+ const { mongo, logger } = require('../../../helpers');
+
+ mongoMock = mongo;
+ loggerMock = logger;
+
+ mongoMock.upsertOne = jest.fn().mockResolvedValue(true);
+
+ commonHelper = require('../common');
+ result = await commonHelper.saveOrder(loggerMock, {
+ order: {
+ orderId: 123456
+ },
+ botStatus: {
+ some: 'value'
+ }
+ });
+ });
+
+ it('triggers mongo.upsertOne', () => {
+ expect(mongoMock.upsertOne).toHaveBeenCalledWith(
+ loggerMock,
+ 'trailing-trade-orders',
+ { key: 123456 },
+ {
+ key: 123456,
+ order: {
+ orderId: 123456
+ },
+ botStatus: {
+ some: 'value'
+ }
+ }
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toBeTruthy();
+ });
+ });
});
diff --git a/app/cronjob/trailingTradeHelper/__tests__/configuration.test.js b/app/cronjob/trailingTradeHelper/__tests__/configuration.test.js
index 4d19e854..e97a7dae 100644
--- a/app/cronjob/trailingTradeHelper/__tests__/configuration.test.js
+++ b/app/cronjob/trailingTradeHelper/__tests__/configuration.test.js
@@ -267,76 +267,1812 @@ describe('configuration.js', () => {
});
});
+ describe('getSymbolGridTrade', () => {
+ describe('when symbol is not provided', () => {
+ beforeEach(async () => {
+ result = await configuration.getSymbolGridTrade(logger);
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({});
+ });
+ });
+
+ describe('when cannot find from mongodb', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn((_logger, _collection, _filter) => null);
+
+ result = await configuration.getSymbolGridTrade(logger, 'BTCUSDT');
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({});
+ });
+ });
+
+ describe('when found from mongodb', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn((_logger, collection, filter) => {
+ if (
+ collection === 'trailing-trade-grid-trade' &&
+ _.isEqual(filter, { key: 'BTCUSDT' })
+ ) {
+ return {
+ buy: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.025,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 1,
+ quantityPercentages: {
+ USDT: 1
+ },
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ };
+ }
+ return null;
+ });
+
+ result = await configuration.getSymbolGridTrade(logger, 'BTCUSDT');
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual({
+ buy: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.025,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 1,
+ quantityPercentages: {
+ USDT: 1
+ },
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ });
+ });
+ });
+ });
+
describe('saveSymbolConfiguration', () => {
describe('when symbol is not provided', () => {
beforeEach(async () => {
mongo.upsertOne = jest.fn().mockResolvedValue(true);
- result = await configuration.saveSymbolConfiguration(logger);
- });
+ result = await configuration.saveSymbolConfiguration(logger);
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({});
+ });
+ });
+
+ describe('when symbol is provided', () => {
+ beforeEach(async () => {
+ mongo.upsertOne = jest.fn().mockResolvedValue(true);
+
+ result = await configuration.saveSymbolConfiguration(
+ logger,
+ 'BTCUSDT',
+ {
+ myKey: 'value'
+ }
+ );
+ });
+
+ it('triggers mongo.upsertOne', () => {
+ expect(mongo.upsertOne).toHaveBeenCalledWith(
+ logger,
+ 'trailing-trade-symbols',
+ { key: 'BTCUSDT-configuration' },
+ { key: 'BTCUSDT-configuration', myKey: 'value' }
+ );
+ });
+ });
+ });
+
+ describe('saveSymbolGridTrade', () => {
+ describe('when symbol is not provided', () => {
+ beforeEach(async () => {
+ mongo.upsertOne = jest.fn().mockResolvedValue(true);
+
+ result = await configuration.saveSymbolGridTrade(logger);
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({});
+ });
+ });
+
+ describe('when symbol is provided', () => {
+ beforeEach(async () => {
+ mongo.upsertOne = jest.fn().mockResolvedValue(true);
+
+ result = await configuration.saveSymbolGridTrade(logger, 'BTCUSDT', {
+ myKey: 'value'
+ });
+ });
+
+ it('triggers mongo.upsertOne', () => {
+ expect(mongo.upsertOne).toHaveBeenCalledWith(
+ logger,
+ 'trailing-trade-grid-trade',
+ { key: 'BTCUSDT' },
+ { key: 'BTCUSDT', myKey: 'value' }
+ );
+ });
+ });
+ });
+
+ describe('deleteAllSymbolConfiguration', () => {
+ beforeEach(async () => {
+ mongo.deleteAll = jest.fn().mockResolvedValue(true);
+
+ result = await configuration.deleteAllSymbolConfiguration(logger);
+ });
+
+ it('trigger mongo.deleteAll', () => {
+ expect(mongo.deleteAll).toHaveBeenCalledWith(
+ logger,
+ 'trailing-trade-symbols',
+ {
+ key: { $regex: /^(.+)-configuration/ }
+ }
+ );
+ });
+ });
+
+ describe('deleteSymbolConfiguration', () => {
+ beforeEach(async () => {
+ mongo.deleteOne = jest.fn().mockResolvedValue(true);
+
+ result = await configuration.deleteSymbolConfiguration(logger, 'BTCUSDT');
+ });
+
+ it('trigger mongo.deleteOne', () => {
+ expect(mongo.deleteOne).toHaveBeenCalledWith(
+ logger,
+ 'trailing-trade-symbols',
+ {
+ key: `BTCUSDT-configuration`
+ }
+ );
+ });
+ });
+
+ describe('deleteAllSymbolGridTrade', () => {
+ beforeEach(async () => {
+ mongo.deleteAll = jest.fn().mockResolvedValue(true);
+
+ result = await configuration.deleteAllSymbolGridTrade(logger);
+ });
+
+ it('trigger mongo.deleteAll', () => {
+ expect(mongo.deleteAll).toHaveBeenCalledWith(
+ logger,
+ 'trailing-trade-grid-trade',
+ {}
+ );
+ });
+ });
+
+ describe('deleteSymbolGridTrade', () => {
+ beforeEach(async () => {
+ mongo.deleteOne = jest.fn().mockResolvedValue(true);
+
+ result = await configuration.deleteSymbolGridTrade(logger, 'BTCUSDT');
+ });
+
+ it('trigger mongo.deleteOne', () => {
+ expect(mongo.deleteOne).toHaveBeenCalledWith(
+ logger,
+ 'trailing-trade-grid-trade',
+ {
+ key: 'BTCUSDT'
+ }
+ );
+ });
+ });
+
+ describe('getGridTradeBuy', () => {
+ let cachedSymbolInfo;
+ let globalConfiguration;
+ let symbolConfiguration;
+
+ describe('when grid trade is empty', () => {
+ beforeEach(async () => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT',
+ filterMinNotional: { minNotional: 10 }
+ };
+
+ globalConfiguration = {
+ buy: { gridTrade: [{ maxPurchaseAmounts: { USDT: 10 } }] }
+ };
+
+ symbolConfiguration = {
+ buy: { gridTrade: [] }
+ };
+
+ result = configuration.getGridTradeBuy(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual([{ maxPurchaseAmount: 10 }]);
+ });
+ });
+
+ describe('when max purchase amount is already defined', () => {
+ beforeEach(async () => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT',
+ filterMinNotional: { minNotional: 10 }
+ };
+
+ globalConfiguration = {
+ buy: {
+ gridTrade: [
+ { maxPurchaseAmounts: { USDT: 10 } },
+ { maxPurchaseAmounts: { USDT: 10 } }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ gridTrade: [
+ {
+ maxPurchaseAmount: 15,
+ maxPurchaseAmounts: { USDT: 10 }
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeBuy(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual([
+ {
+ maxPurchaseAmount: 15
+ }
+ ]);
+ });
+ });
+
+ describe('when max purchase amount is not defined', () => {
+ describe('when cached symbol info is not provided', () => {
+ beforeEach(async () => {
+ cachedSymbolInfo = {};
+
+ globalConfiguration = {
+ buy: {
+ gridTrade: [
+ { maxPurchaseAmounts: {} },
+ { maxPurchaseAmounts: {} }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ gridTrade: [
+ {
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {}
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeBuy(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual([
+ {
+ maxPurchaseAmount: -1
+ }
+ ]);
+ });
+ });
+
+ describe('when cached symbol info is provided', () => {
+ describe('when global configuration has max purchase amount defined', () => {
+ beforeEach(async () => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT',
+ filterMinNotional: { minNotional: 10 }
+ };
+
+ globalConfiguration = {
+ buy: {
+ gridTrade: [
+ { maxPurchaseAmounts: { USDT: 10 } },
+ { maxPurchaseAmounts: { USDT: 10 } }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ gridTrade: [
+ {
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: { USDT: 10 }
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeBuy(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual([
+ {
+ maxPurchaseAmount: 10
+ }
+ ]);
+ });
+ });
+
+ describe('when global configuration does not have max purchase amount', () => {
+ beforeEach(async () => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT',
+ filterMinNotional: { minNotional: 10 }
+ };
+
+ globalConfiguration = {
+ buy: {
+ gridTrade: [
+ { maxPurchaseAmounts: {} },
+ { maxPurchaseAmounts: {} },
+ { maxPurchaseAmounts: {} }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ gridTrade: [
+ {
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {}
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeBuy(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual([
+ {
+ maxPurchaseAmount: 100
+ }
+ ]);
+ });
+ });
+ });
+ });
+ });
+
+ describe('getGridTradeSell', () => {
+ let cachedSymbolInfo;
+ let globalConfiguration;
+ let symbolConfiguration;
+
+ describe('when grid trade is empty', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT'
+ };
+
+ globalConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentages: {
+ USDT: 0.5
+ }
+ },
+ {
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ sell: {
+ gridTrade: []
+ }
+ };
+
+ result = configuration.getGridTradeSell(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual([
+ {
+ quantityPercentage: 0.5
+ },
+ {
+ quantityPercentage: 1
+ }
+ ]);
+ });
+ });
+
+ describe('when quantity percentage is already defined', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT'
+ };
+
+ globalConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentages: {
+ USDT: 0.5
+ }
+ },
+ {
+ quantityPercentages: {
+ USDT: 1
+ }
+ },
+ {
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentage: 0.8,
+ quantityPercentages: {
+ USDT: 0.5
+ }
+ },
+ {
+ quantityPercentage: 1,
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeSell(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual([
+ {
+ quantityPercentage: 0.8
+ },
+ {
+ quantityPercentage: 1
+ }
+ ]);
+ });
+ });
+
+ describe('when quantity percentage is not defined', () => {
+ describe('when cached symbol info is not provided', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {};
+
+ globalConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentages: {
+ USDT: 0.5
+ }
+ }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 0.5
+ }
+ },
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeSell(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual([
+ {
+ quantityPercentage: -1
+ },
+ {
+ quantityPercentage: -1
+ }
+ ]);
+ });
+ });
+
+ describe('when cached symbol info is provided', () => {
+ describe('when global configuration has quantity percentage defined', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT'
+ };
+ globalConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentages: {
+ USDT: 0.5
+ }
+ }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 0.5
+ }
+ },
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeSell(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual([
+ {
+ quantityPercentage: 0.5
+ },
+ {
+ quantityPercentage: 1
+ }
+ ]);
+ });
+ });
+
+ describe('when global configuration does not thave quantity percentage', () => {
+ describe('when there was only one grid trade', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT'
+ };
+
+ globalConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentages: {}
+ }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ },
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeSell(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual([
+ {
+ quantityPercentage: 0.5
+ },
+ {
+ quantityPercentage: 1
+ }
+ ]);
+ });
+ });
+
+ describe('when there are 3 grid trades', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT'
+ };
+
+ globalConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentages: {}
+ },
+ {
+ quantityPercentages: {}
+ }
+ ]
+ }
+ };
+
+ symbolConfiguration = {
+ sell: {
+ gridTrade: [
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ },
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ },
+ {
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ }
+ ]
+ }
+ };
+
+ result = configuration.getGridTradeSell(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual([
+ {
+ quantityPercentage: 0.33
+ },
+ {
+ quantityPercentage: 0.33
+ },
+ {
+ quantityPercentage: 1
+ }
+ ]);
+ });
+ });
+ });
+ });
+ });
+ });
+
+ describe('getLastBuyPriceRemoveThreshold', () => {
+ let cachedSymbolInfo;
+ let globalConfiguration;
+ let symbolConfiguration;
+
+ describe('when last buy price remove threshold is already defined', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT',
+ filterMinNotional: { minNotional: 10 }
+ };
+
+ globalConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThresholds: {
+ USDT: 5
+ }
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThreshold: 7
+ }
+ };
+
+ result = configuration.getLastBuyPriceRemoveThreshold(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual(7);
+ });
+ });
+
+ describe('when last buy price remove threshold is not defined', () => {
+ describe('when symbol info is not provided', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {};
+
+ globalConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThresholds: {
+ USDT: 5
+ }
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThreshold: -1
+ }
+ };
+
+ result = configuration.getLastBuyPriceRemoveThreshold(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual(-1);
+ });
+ });
+
+ describe('when symbol info is provided', () => {
+ describe('when global configuration has last buy price remove threshold', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT',
+ filterMinNotional: { minNotional: 10 }
+ };
+
+ globalConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThresholds: {
+ USDT: 5
+ }
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThreshold: -1
+ }
+ };
+
+ result = configuration.getLastBuyPriceRemoveThreshold(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual(5);
+ });
+ });
+
+ describe('when global configuration does not have last buy price remove threshold', () => {
+ beforeEach(() => {
+ cachedSymbolInfo = {
+ quoteAsset: 'USDT',
+ filterMinNotional: { minNotional: 10 }
+ };
+
+ globalConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThresholds: {}
+ }
+ };
+
+ symbolConfiguration = {
+ buy: {
+ lastBuyPriceRemoveThreshold: -1
+ }
+ };
+
+ result = configuration.getLastBuyPriceRemoveThreshold(
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual(10);
+ });
+ });
+ });
+ });
+ });
+
+ describe('postProcessConfiguration', () => {
+ let configurationParam;
+ let symbolGridTrade;
+ const symbol = 'BTCUSDT';
+
+ describe('when symbol grid trades contain executed orders', () => {
+ describe('when first grid order is executed', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn().mockResolvedValue({
+ lastBuyPrice: 3000,
+ quantity: 0.1
+ });
+
+ configurationParam = {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1
+ },
+ {
+ triggerPercentage: 0.9
+ },
+ {
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.02
+ },
+ {
+ triggerPercentage: 1.03
+ },
+ {
+ triggerPercentage: 1.04
+ }
+ ]
+ }
+ };
+
+ symbolGridTrade = {
+ buy: [
+ {
+ triggerPercentage: 1.01,
+ executed: true,
+ executedOrder: { orderId: 1 }
+ },
+ {
+ triggerPercentage: 0.95,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.05,
+ executed: true,
+ executedOrder: { orderId: 1 }
+ },
+ {
+ triggerPercentage: 1.06,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.07,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ };
+
+ result = await configuration.postProcessConfiguration(
+ logger,
+ configurationParam,
+ { symbolGridTrade, symbol }
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ buy: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.9
+ },
+ currentGridTradeIndex: 1,
+ gridTrade: [
+ {
+ executed: true,
+ executedOrder: { orderId: 1 },
+ triggerPercentage: 1.01
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.9
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.03
+ },
+ currentGridTradeIndex: 1,
+ gridTrade: [
+ {
+ executed: true,
+ executedOrder: { orderId: 1 },
+ triggerPercentage: 1.05
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.04
+ }
+ ]
+ }
+ });
+ });
+ });
+
+ describe('when second grid order is executed', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn().mockResolvedValue({
+ lastBuyPrice: 3000,
+ quantity: 0.1
+ });
+
+ configurationParam = {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.02
+ },
+ {
+ triggerPercentage: 0.95
+ },
+ {
+ triggerPercentage: 0.85
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.051
+ },
+ {
+ triggerPercentage: 1.062
+ },
+ {
+ triggerPercentage: 1.073
+ }
+ ]
+ }
+ };
+
+ symbolGridTrade = {
+ buy: [
+ {
+ triggerPercentage: 1,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ executed: true,
+ executedOrder: { orderId: 1 }
+ },
+ {
+ triggerPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.03,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.04,
+ executed: true,
+ executedOrder: { orderId: 2 }
+ },
+ {
+ triggerPercentage: 1.05,
+ executed: false,
+ executedOrder: null
+ }
+ ]
+ };
+
+ result = await configuration.postProcessConfiguration(
+ logger,
+ configurationParam,
+ { symbolGridTrade, symbol }
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ buy: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.85
+ },
+ currentGridTradeIndex: 2,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.02
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 1 },
+ triggerPercentage: 0.9
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.85
+ }
+ ]
+ },
+ sell: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.073
+ },
+ currentGridTradeIndex: 2,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.051
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 2 },
+ triggerPercentage: 1.04
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.073
+ }
+ ]
+ }
+ });
+ });
+ });
+
+ describe('when second/last grid orders are executed', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn().mockResolvedValue({
+ lastBuyPrice: 3000,
+ quantity: 0.1
+ });
+
+ configurationParam = {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.03
+ },
+ {
+ triggerPercentage: 0.8
+ },
+ {
+ triggerPercentage: 0.7
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.055
+ },
+ {
+ triggerPercentage: 1.066
+ },
+ {
+ triggerPercentage: 1.077
+ }
+ ]
+ }
+ };
+
+ symbolGridTrade = {
+ buy: [
+ {
+ triggerPercentage: 1,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ executed: true,
+ executedOrder: { orderId: 1 }
+ },
+ {
+ triggerPercentage: 0.8,
+ executed: true,
+ executedOrder: { orderId: 2 }
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.03,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.04,
+ executed: true,
+ executedOrder: { orderId: 2 }
+ },
+ {
+ triggerPercentage: 1.05,
+ executed: true,
+ executedOrder: { orderId: 3 }
+ }
+ ]
+ };
+
+ result = await configuration.postProcessConfiguration(
+ logger,
+ configurationParam,
+ { symbolGridTrade, symbol }
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ buy: {
+ currentGridTrade: null,
+ currentGridTradeIndex: -1,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 1 },
+ triggerPercentage: 0.9
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 2 },
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ currentGridTrade: null,
+ currentGridTradeIndex: -1,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.055
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 2 },
+ triggerPercentage: 1.04
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 3 },
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ });
+ });
+ });
+
+ describe('when all grid orders are executed', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn().mockResolvedValue({
+ lastBuyPrice: 3000,
+ quantity: 0.1
+ });
+
+ configurationParam = {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.03
+ },
+ {
+ triggerPercentage: 0.8
+ },
+ {
+ triggerPercentage: 0.7
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.055
+ },
+ {
+ triggerPercentage: 1.066
+ },
+ {
+ triggerPercentage: 1.077
+ }
+ ]
+ }
+ };
+
+ symbolGridTrade = {
+ buy: [
+ {
+ triggerPercentage: 1,
+ executed: true,
+ executedOrder: { orderId: 4 }
+ },
+ {
+ triggerPercentage: 0.9,
+ executed: true,
+ executedOrder: { orderId: 1 }
+ },
+ {
+ triggerPercentage: 0.8,
+ executed: true,
+ executedOrder: { orderId: 2 }
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.03,
+ executed: true,
+ executedOrder: { orderId: 4 }
+ },
+ {
+ triggerPercentage: 1.04,
+ executed: true,
+ executedOrder: { orderId: 2 }
+ },
+ {
+ triggerPercentage: 1.05,
+ executed: true,
+ executedOrder: { orderId: 3 }
+ }
+ ]
+ };
- it('returns expected value', () => {
- expect(result).toStrictEqual({});
+ result = await configuration.postProcessConfiguration(
+ logger,
+ configurationParam,
+ { symbolGridTrade, symbol }
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ buy: {
+ currentGridTrade: null,
+ currentGridTradeIndex: -1,
+ gridTrade: [
+ {
+ executed: true,
+ executedOrder: { orderId: 4 },
+ triggerPercentage: 1
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 1 },
+ triggerPercentage: 0.9
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 2 },
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ currentGridTrade: null,
+ currentGridTradeIndex: -1,
+ gridTrade: [
+ {
+ executed: true,
+ executedOrder: { orderId: 4 },
+ triggerPercentage: 1.03
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 2 },
+ triggerPercentage: 1.04
+ },
+ {
+ executed: true,
+ executedOrder: { orderId: 3 },
+ triggerPercentage: 1.05
+ }
+ ]
+ }
+ });
+ });
});
});
- describe('when symbol is provided', () => {
- beforeEach(async () => {
- mongo.upsertOne = jest.fn().mockResolvedValue(true);
+ describe('when grid trades have no executed orders', () => {
+ describe('when side is buy, has last buy price, and 2nd grid trade is defined', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn().mockResolvedValue({
+ lastBuyPrice: 3000,
+ quantity: 0.1
+ });
- result = await configuration.saveSymbolConfiguration(
- logger,
- 'BTCUSDT',
- {
- myKey: 'value'
- }
- );
- });
+ configurationParam = {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1
+ },
+ {
+ triggerPercentage: 0.9
+ },
+ {
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.02
+ },
+ {
+ triggerPercentage: 1.03
+ },
+ {
+ triggerPercentage: 1.04
+ }
+ ]
+ }
+ };
- it('triggers mongo.upsertOne', () => {
- expect(mongo.upsertOne).toHaveBeenCalledWith(
- logger,
- 'trailing-trade-symbols',
- { key: 'BTCUSDT-configuration' },
- { key: 'BTCUSDT-configuration', myKey: 'value' }
- );
+ symbolGridTrade = {
+ buy: [
+ {
+ triggerPercentage: 1,
+ executed: false
+ },
+ {
+ triggerPercentage: 0.9,
+ executed: false
+ },
+ {
+ triggerPercentage: 0.8,
+ executed: false
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.03,
+ executed: false
+ },
+ {
+ triggerPercentage: 1.04,
+ executed: false
+ },
+ {
+ triggerPercentage: 1.05,
+ executed: false
+ }
+ ]
+ };
+
+ result = await configuration.postProcessConfiguration(
+ logger,
+ configurationParam,
+ { symbolGridTrade, symbol }
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ buy: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.9
+ },
+ currentGridTradeIndex: 1,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.9
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.02
+ },
+ currentGridTradeIndex: 0,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.02
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.04
+ }
+ ]
+ }
+ });
+ });
});
- });
- });
- describe('deleteAllSymbolConfiguration', () => {
- beforeEach(async () => {
- mongo.deleteAll = jest.fn().mockResolvedValue(true);
+ describe('when side is buy, has last buy price, but 2nd grid trade is not defined', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn().mockResolvedValue({
+ lastBuyPrice: 3000,
+ quantity: 0.1
+ });
- result = await configuration.deleteAllSymbolConfiguration(logger);
- });
+ configurationParam = {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.02
+ }
+ ]
+ }
+ };
- it('trigger mongo.deleteAll', () => {
- expect(mongo.deleteAll).toHaveBeenCalledWith(
- logger,
- 'trailing-trade-symbols',
- {
- key: { $regex: /^(.+)-configuration/ }
- }
- );
- });
- });
+ symbolGridTrade = {
+ buy: [
+ {
+ triggerPercentage: 1,
+ executed: false
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.03,
+ executed: false
+ }
+ ]
+ };
- describe('deleteSymbolConfiguration', () => {
- beforeEach(async () => {
- mongo.deleteOne = jest.fn().mockResolvedValue(true);
+ result = await configuration.postProcessConfiguration(
+ logger,
+ configurationParam,
+ { symbolGridTrade, symbol }
+ );
+ });
- result = await configuration.deleteSymbolConfiguration(logger, 'BTCUSDT');
- });
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ buy: {
+ currentGridTrade: null,
+ currentGridTradeIndex: -1,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1
+ }
+ ]
+ },
+ sell: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.02
+ },
+ currentGridTradeIndex: 0,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.02
+ }
+ ]
+ }
+ });
+ });
+ });
- it('trigger mongo.deleteOne', () => {
- expect(mongo.deleteOne).toHaveBeenCalledWith(
- logger,
- 'trailing-trade-symbols',
- {
- key: `BTCUSDT-configuration`
- }
- );
+ describe('when none of conditions are matching', () => {
+ beforeEach(async () => {
+ mongo.findOne = jest.fn().mockResolvedValue(null);
+
+ configurationParam = {
+ buy: {
+ gridTrade: [
+ {
+ triggerPercentage: 1
+ },
+ {
+ triggerPercentage: 0.9
+ },
+ {
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ gridTrade: [
+ {
+ triggerPercentage: 1.02
+ },
+ {
+ triggerPercentage: 1.03
+ },
+ {
+ triggerPercentage: 1.04
+ }
+ ]
+ }
+ };
+
+ symbolGridTrade = {
+ buy: [
+ {
+ triggerPercentage: 1,
+ executed: false
+ },
+ {
+ triggerPercentage: 0.9,
+ executed: false
+ },
+ {
+ triggerPercentage: 0.8,
+ executed: false
+ }
+ ],
+ sell: [
+ {
+ triggerPercentage: 1.03,
+ executed: false
+ },
+ {
+ triggerPercentage: 1.04,
+ executed: false
+ },
+ {
+ triggerPercentage: 1.05,
+ executed: false
+ }
+ ]
+ };
+
+ result = await configuration.postProcessConfiguration(
+ logger,
+ configurationParam,
+ { symbolGridTrade, symbol }
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ buy: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1
+ },
+ currentGridTradeIndex: 0,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.9
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 0.8
+ }
+ ]
+ },
+ sell: {
+ currentGridTrade: {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.02
+ },
+ currentGridTradeIndex: 0,
+ gridTrade: [
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.02
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.03
+ },
+ {
+ executed: false,
+ executedOrder: null,
+ triggerPercentage: 1.04
+ }
+ ]
+ }
+ });
+ });
+ });
});
});
@@ -365,17 +2101,19 @@ describe('configuration.js', () => {
},
buy: {
enabled: true,
- maxPurchaseAmount: -1,
- maxPurchaseAmounts: {
- USDT: 100
- },
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {}
+ }
+ ],
lastBuyPriceRemoveThreshold: -1,
lastBuyPriceRemoveThresholds: {
USDT: 10
},
- triggerPercentage: 1.0,
- stopPercentage: 1.02,
- limitPercentage: 1.021,
athRestriction: {
enabled: true,
candles: {
@@ -387,9 +2125,15 @@ describe('configuration.js', () => {
},
sell: {
enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.98,
- limitPercentage: 0.979,
+ gridTrade: [
+ {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ }
+ ],
stopLoss: {
enabled: false,
maxLossPercentage: 0.8,
@@ -401,7 +2145,8 @@ describe('configuration.js', () => {
temporaryDisableActionAfterConfirmingOrder: 20,
checkManualBuyOrderPeriod: 5,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 1
+ refreshAccountInfoPeriod: 1,
+ checkOrderExecutePeriod: 10
}
};
}
@@ -426,21 +2171,36 @@ describe('configuration.js', () => {
},
buy: {
enabled: false,
- maxPurchaseAmount: -1,
- maxPurchaseAmounts: {
- USDT: 100,
- BTC: 0.001,
- BUSD: 100
- },
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ }
+ ],
lastBuyPriceRemoveThreshold: -1,
lastBuyPriceRemoveThresholds: {
USDT: 5,
BTC: 0.00005,
BUSD: 5
},
- triggerPercentage: 1.05,
- stopPercentage: 1.05,
- limitPercentage: 1.051,
athRestriction: {
enabled: true,
candles: {
@@ -452,9 +2212,19 @@ describe('configuration.js', () => {
},
sell: {
enabled: false,
- triggerPercentage: 1.08,
- stopPercentage: 0.95,
- limitPercentage: 0.949,
+ gridTrade: [
+ {
+ triggerPercentage: 1.08,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 1,
+ BTC: 1,
+ BUSD: 1
+ }
+ }
+ ],
stopLoss: {
enabled: true,
maxLossPercentage: 0.95,
@@ -466,7 +2236,8 @@ describe('configuration.js', () => {
temporaryDisableActionAfterConfirmingOrder: 10,
checkManualBuyOrderPeriod: 10,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
}
};
}
@@ -482,17 +2253,41 @@ describe('configuration.js', () => {
},
buy: {
enabled: true,
- maxPurchaseAmount: 150,
- lastBuyPriceRemoveThreshold: 4,
- triggerPercentage: 1.04,
- stopPercentage: 1.04,
- limitPercentage: 1.041
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 20
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.056,
+ maxPurchaseAmount: 30
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 4
},
sell: {
enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.96,
- limitPercentage: 0.979,
+ gridTrade: [
+ {
+ triggerPercentage: 1.025,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 1,
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ],
stopLoss: {
enabled: true,
maxLossPercentage: 0.81,
@@ -524,31 +2319,41 @@ describe('configuration.js', () => {
candles: { interval: '1d', limit: 10 },
buy: {
enabled: false,
- maxPurchaseAmount: -1,
- maxPurchaseAmounts: { USDT: 100, BTC: 0.001, BUSD: 100 },
- lastBuyPriceRemoveThreshold: -1,
- lastBuyPriceRemoveThresholds: {
- USDT: 5,
- BTC: 0.00005,
- BUSD: 5
- },
- triggerPercentage: 1.05,
- stopPercentage: 1.05,
- limitPercentage: 1.051,
- athRestriction: {
- enabled: true,
- candles: {
- interval: '1d',
- limit: 30
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: { USDT: 100, BTC: 0.001, BUSD: 100 }
},
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: { USDT: 100, BTC: 0.001, BUSD: 100 }
+ }
+ ],
+ lastBuyPriceRemoveThreshold: -1,
+ lastBuyPriceRemoveThresholds: { USDT: 5, BTC: 0.00005, BUSD: 5 },
+ athRestriction: {
+ enabled: true,
+ candles: { interval: '1d', limit: 30 },
restrictionPercentage: 0.9
}
},
sell: {
enabled: false,
- triggerPercentage: 1.08,
- stopPercentage: 0.95,
- limitPercentage: 0.949,
+ gridTrade: [
+ {
+ triggerPercentage: 1.08,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: { USDT: 1, BTC: 1, BUSD: 1 }
+ }
+ ],
stopLoss: {
enabled: true,
maxLossPercentage: 0.95,
@@ -560,7 +2365,8 @@ describe('configuration.js', () => {
temporaryDisableActionAfterConfirmingOrder: 10,
checkManualBuyOrderPeriod: 10,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
}
});
});
@@ -604,20 +2410,25 @@ describe('configuration.js', () => {
enabled: true,
cronTime: '* * * * * *',
symbols: ['BTCUSDT', 'ETHUSDT', 'ETHBTC', 'XRPBTC'],
- candles: { interval: '1h', limit: 100 },
+ candles: {
+ interval: '1h',
+ limit: 100
+ },
buy: {
enabled: true,
- maxPurchaseAmount: -1,
- maxPurchaseAmounts: {
- USDT: 100
- },
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {}
+ }
+ ],
lastBuyPriceRemoveThreshold: -1,
lastBuyPriceRemoveThresholds: {
USDT: 10
},
- triggerPercentage: 1,
- stopPercentage: 1.02,
- limitPercentage: 1.021,
athRestriction: {
enabled: true,
candles: {
@@ -629,9 +2440,15 @@ describe('configuration.js', () => {
},
sell: {
enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.98,
- limitPercentage: 0.979,
+ gridTrade: [
+ {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ }
+ ],
stopLoss: {
enabled: false,
maxLossPercentage: 0.8,
@@ -643,7 +2460,8 @@ describe('configuration.js', () => {
temporaryDisableActionAfterConfirmingOrder: 20,
checkManualBuyOrderPeriod: 5,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 1
+ refreshAccountInfoPeriod: 1,
+ checkOrderExecutePeriod: 10
}
}
);
@@ -657,163 +2475,73 @@ describe('configuration.js', () => {
candles: { interval: '1h', limit: 100 },
buy: {
enabled: true,
- maxPurchaseAmount: 100,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: 100,
+ executed: false,
+ executedOrder: null
+ }
+ ],
lastBuyPriceRemoveThreshold: 10,
- triggerPercentage: 1,
- stopPercentage: 1.02,
- limitPercentage: 1.021,
athRestriction: {
enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
+ candles: { interval: '1d', limit: 30 },
restrictionPercentage: 0.9
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: 100,
+ executed: false,
+ executedOrder: null
}
},
sell: {
enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.98,
- limitPercentage: 0.979,
+ gridTrade: [
+ {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
stopLoss: {
enabled: false,
maxLossPercentage: 0.8,
disableBuyMinutes: 360,
orderType: 'market'
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
}
},
system: {
temporaryDisableActionAfterConfirmingOrder: 20,
checkManualBuyOrderPeriod: 5,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 1
+ refreshAccountInfoPeriod: 1,
+ checkOrderExecutePeriod: 10
}
});
});
});
describe('when found global configuration, but not symbol configuration', () => {
- beforeEach(async () => {
- mongo.findOne = jest.fn((_logger, collection, filter) => {
- if (
- collection === 'trailing-trade-common' &&
- _.isEqual(filter, { key: 'configuration' })
- ) {
- return {
- enabled: true,
- cronTime: '* * * * * *',
- symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
- candles: {
- interval: '1d',
- limit: 10
- },
- buy: {
- enabled: false,
- maxPurchaseAmount: -1,
- maxPurchaseAmounts: {
- USDT: 100,
- BTC: 0.001,
- BUSD: 100
- },
- lastBuyPriceRemoveThreshold: -1,
- lastBuyPriceRemoveThresholds: {
- USDT: 5,
- BTC: 0.0004,
- BUSD: 3
- },
- triggerPercentage: 1.05,
- stopPercentage: 1.05,
- limitPercentage: 1.051,
- athRestriction: {
- enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
- restrictionPercentage: 0.9
- }
- },
- sell: {
- enabled: false,
- triggerPercentage: 1.08,
- stopPercentage: 0.95,
- limitPercentage: 0.949,
- stopLoss: {
- enabled: true,
- maxLossPercentage: 0.95,
- disableBuyMinutes: 60,
- orderType: 'market'
- }
- },
- system: {
- temporaryDisableActionAfterConfirmingOrder: 10,
- checkManualBuyOrderPeriod: 10,
- placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
- }
- };
- }
- return null;
- });
-
- result = await configuration.getConfiguration(logger, 'BTCUSDT');
- });
-
- it('triggers config.get', () => {
- expect(config.get).toHaveBeenCalled();
- });
-
- it('does not triggers mongo.upsertOne', () => {
- expect(mongo.upsertOne).not.toHaveBeenCalled();
- });
-
- it('returns expected value', () => {
- expect(result).toStrictEqual({
- enabled: true,
- cronTime: '* * * * * *',
- symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
- candles: { interval: '1d', limit: 10 },
- buy: {
- enabled: false,
- maxPurchaseAmount: 100,
- lastBuyPriceRemoveThreshold: 5,
- triggerPercentage: 1.05,
- stopPercentage: 1.05,
- limitPercentage: 1.051,
- athRestriction: {
- enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
- restrictionPercentage: 0.9
- }
- },
- sell: {
- enabled: false,
- triggerPercentage: 1.08,
- stopPercentage: 0.95,
- limitPercentage: 0.949,
- stopLoss: {
- enabled: true,
- maxLossPercentage: 0.95,
- disableBuyMinutes: 60,
- orderType: 'market'
- }
- },
- system: {
- temporaryDisableActionAfterConfirmingOrder: 10,
- checkManualBuyOrderPeriod: 10,
- placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
- }
- });
- });
- });
-
- describe('when found global/symbol configuration', () => {
- describe('when symbol configuration buy max purchase amount/last buy price remove threshold are not -1', () => {
+ describe('case 1', () => {
beforeEach(async () => {
mongo.findOne = jest.fn((_logger, collection, filter) => {
if (
@@ -830,21 +2558,36 @@ describe('configuration.js', () => {
},
buy: {
enabled: false,
- maxPurchaseAmount: -1,
- maxPurchaseAmounts: {
- USDT: 100,
- BTC: 0.001,
- BUSD: 100
- },
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ }
+ ],
lastBuyPriceRemoveThreshold: -1,
lastBuyPriceRemoveThresholds: {
- USDT: 4,
- BTC: 0.0008,
+ USDT: 5,
+ BTC: 0.00005,
BUSD: 5
},
- triggerPercentage: 1.05,
- stopPercentage: 1.05,
- limitPercentage: 1.051,
athRestriction: {
enabled: true,
candles: {
@@ -856,9 +2599,30 @@ describe('configuration.js', () => {
},
sell: {
enabled: false,
- triggerPercentage: 1.08,
- stopPercentage: 0.95,
- limitPercentage: 0.949,
+ gridTrade: [
+ {
+ triggerPercentage: 1.08,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 0.5,
+ BTC: 0.5,
+ BUSD: 0.5
+ }
+ },
+ {
+ triggerPercentage: 1.1,
+ stopPercentage: 0.94,
+ limitPercentage: 0.939,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 1,
+ BTC: 1,
+ BUSD: 1
+ }
+ }
+ ],
stopLoss: {
enabled: true,
maxLossPercentage: 0.95,
@@ -870,48 +2634,8 @@ describe('configuration.js', () => {
temporaryDisableActionAfterConfirmingOrder: 10,
checkManualBuyOrderPeriod: 10,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
- }
- };
- }
-
- if (
- collection === 'trailing-trade-symbols' &&
- _.isEqual(filter, { key: 'BTCUSDT-configuration' })
- ) {
- return {
- key: 'BTCUSDT-configuration',
- candles: {
- interval: '1h',
- limit: 50
- },
- buy: {
- enabled: true,
- maxPurchaseAmount: 150,
- lastBuyPriceRemoveThreshold: 8,
- triggerPercentage: 1.04,
- stopPercentage: 1.04,
- limitPercentage: 1.041,
- athRestriction: {
- enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
- restrictionPercentage: 0.9
- }
- },
- sell: {
- enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.96,
- limitPercentage: 0.979,
- stopLoss: {
- enabled: true,
- maxLossPercentage: 0.81,
- disableBuyMinutes: 65,
- orderType: 'market'
- }
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
}
};
}
@@ -925,152 +2649,198 @@ describe('configuration.js', () => {
expect(config.get).toHaveBeenCalled();
});
- it('does not trigger mongo.upsertOne', () => {
+ it('does not triggers mongo.upsertOne', () => {
expect(mongo.upsertOne).not.toHaveBeenCalled();
});
it('returns expected value', () => {
expect(result).toStrictEqual({
- key: 'BTCUSDT-configuration',
enabled: true,
cronTime: '* * * * * *',
symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
- candles: { interval: '1h', limit: 50 },
+ candles: { interval: '1d', limit: 10 },
buy: {
- enabled: true,
- maxPurchaseAmount: 150,
- lastBuyPriceRemoveThreshold: 8,
- triggerPercentage: 1.04,
- stopPercentage: 1.04,
- limitPercentage: 1.041,
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: 100,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: 100,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 5,
athRestriction: {
enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
+ candles: { interval: '1d', limit: 30 },
restrictionPercentage: 0.9
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: 100,
+ executed: false,
+ executedOrder: null
}
},
sell: {
- enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.96,
- limitPercentage: 0.979,
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1.08,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: 0.5,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.1,
+ limitPercentage: 0.939,
+ stopPercentage: 0.94,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
stopLoss: {
enabled: true,
- maxLossPercentage: 0.81,
- disableBuyMinutes: 65,
+ maxLossPercentage: 0.95,
+ disableBuyMinutes: 60,
orderType: 'market'
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.08,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: 0.5,
+ executed: false,
+ executedOrder: null
}
},
system: {
temporaryDisableActionAfterConfirmingOrder: 10,
checkManualBuyOrderPeriod: 10,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
}
});
});
});
- describe('when global configuration buy max purchase amount/last buy price moreve threshold are not -1', () => {
+ describe('case 2', () => {
beforeEach(async () => {
- cache.hget = jest.fn().mockResolvedValue(
- JSON.stringify({
- quoteAsset: 'USDT',
- filterMinNotional: {
- minNotional: '10.00000000'
- }
- })
- );
mongo.findOne = jest.fn((_logger, collection, filter) => {
if (
collection === 'trailing-trade-common' &&
_.isEqual(filter, { key: 'configuration' })
) {
return {
+ key: 'configuration',
enabled: true,
cronTime: '* * * * * *',
- symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
- candles: {
- interval: '1d',
- limit: 10
- },
+ symbols: [
+ 'ETHUSDT',
+ 'CAKEUSDT',
+ 'BNBUSDT',
+ 'LTCUSDT',
+ 'BTCUSDT'
+ ],
+ candles: { interval: '15m', limit: 50 },
buy: {
- enabled: false,
- maxPurchaseAmount: 50,
- maxPurchaseAmounts: {
- USDT: 100,
- BTC: 0.001,
- BUSD: 100
- },
- lastBuyPriceRemoveThreshold: 7,
- lastBuyPriceRemoveThresholds: {
- USDT: 5,
- BTC: 0.0004,
- BUSD: 4
- },
- triggerPercentage: 1.05,
- stopPercentage: 1.05,
- limitPercentage: 1.051,
+ enabled: true,
athRestriction: {
- enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
+ enabled: false,
+ candles: { interval: '30m', limit: 50 },
restrictionPercentage: 0.9
- }
- },
- sell: {
- enabled: false,
- triggerPercentage: 1.08,
- stopPercentage: 0.95,
- limitPercentage: 0.949,
- stopLoss: {
- enabled: true,
- maxLossPercentage: 0.95,
- disableBuyMinutes: 60,
- orderType: 'market'
- }
- },
- system: {
- temporaryDisableActionAfterConfirmingOrder: 10,
- checkManualBuyOrderPeriod: 10,
- placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
- }
- };
- }
-
- if (
- collection === 'trailing-trade-symbols' &&
- _.isEqual(filter, { key: 'BTCUSDT-configuration' })
- ) {
- return {
- key: 'BTCUSDT-configuration',
- candles: {
- interval: '1h',
- limit: 50
- },
- buy: {
- enabled: true,
- triggerPercentage: 1.04,
- stopPercentage: 1.04,
- limitPercentage: 1.041
+ },
+ lastBuyPriceRemoveThreshold: -1,
+ lastBuyPriceRemoveThresholds: { USDT: 5 },
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 10,
+ BTC: 0.001,
+ BUSD: 100,
+ ETH: 0.05
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 10,
+ BTC: 0.001,
+ BUSD: 100,
+ ETH: 0.05
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 10,
+ BTC: 0.001,
+ BUSD: 100,
+ ETH: 0.05
+ }
+ }
+ ],
+ maxPurchaseAmount: -1
},
sell: {
enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.96,
- limitPercentage: 0.979,
stopLoss: {
- enabled: true,
- maxLossPercentage: 0.81,
- disableBuyMinutes: 65,
+ enabled: false,
+ maxLossPercentage: 0.8,
+ disableBuyMinutes: 360,
orderType: 'market'
- }
+ },
+ gridTrade: [
+ {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: -1,
+ quantityPercentages: { USDT: 0.8 }
+ },
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: -1,
+ quantityPercentages: { USDT: 1 }
+ }
+ ]
+ },
+ system: {
+ temporaryDisableActionAfterConfirmingOrder: 20,
+ checkManualBuyOrderPeriod: 10,
+ refreshAccountInfoPeriod: 1,
+ placeManualOrderInterval: 5,
+ checkOrderExecutePeriod: 10
}
};
}
@@ -1080,51 +2850,121 @@ describe('configuration.js', () => {
result = await configuration.getConfiguration(logger, 'BTCUSDT');
});
+ it('triggers config.get', () => {
+ expect(config.get).toHaveBeenCalled();
+ });
+
+ it('does not triggers mongo.upsertOne', () => {
+ expect(mongo.upsertOne).not.toHaveBeenCalled();
+ });
+
it('returns expected value', () => {
expect(result).toStrictEqual({
- key: 'BTCUSDT-configuration',
+ key: 'configuration',
enabled: true,
cronTime: '* * * * * *',
- symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
- candles: { interval: '1h', limit: 50 },
+ symbols: ['ETHUSDT', 'CAKEUSDT', 'BNBUSDT', 'LTCUSDT', 'BTCUSDT'],
+ candles: {
+ interval: '15m',
+ limit: 50
+ },
buy: {
enabled: true,
- maxPurchaseAmount: 50,
- lastBuyPriceRemoveThreshold: 7,
- triggerPercentage: 1.04,
- stopPercentage: 1.04,
- limitPercentage: 1.041,
athRestriction: {
- enabled: true,
+ enabled: false,
candles: {
- interval: '1d',
- limit: 30
+ interval: '30m',
+ limit: 50
},
restrictionPercentage: 0.9
+ },
+ lastBuyPriceRemoveThreshold: 5,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ maxPurchaseAmount: -1,
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.025,
+ limitPercentage: 1.026,
+ maxPurchaseAmount: 10,
+ executed: false,
+ executedOrder: null
}
},
sell: {
enabled: true,
- triggerPercentage: 1.06,
- stopPercentage: 0.96,
- limitPercentage: 0.979,
stopLoss: {
- enabled: true,
- maxLossPercentage: 0.81,
- disableBuyMinutes: 65,
+ enabled: false,
+ maxLossPercentage: 0.8,
+ disableBuyMinutes: 360,
orderType: 'market'
+ },
+ gridTrade: [
+ {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.03,
+ stopPercentage: 0.985,
+ limitPercentage: 0.984,
+ quantityPercentage: 0.8,
+ executed: false,
+ executedOrder: null
}
},
system: {
- temporaryDisableActionAfterConfirmingOrder: 10,
+ temporaryDisableActionAfterConfirmingOrder: 20,
checkManualBuyOrderPeriod: 10,
+ refreshAccountInfoPeriod: 1,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 3
+ checkOrderExecutePeriod: 10
}
});
});
});
+ });
+ describe('when found global/symbol configuration', () => {
describe('when configuration is not valid format', () => {
beforeEach(async () => {
cache.hget = jest.fn().mockResolvedValue(
@@ -1144,8 +2984,7 @@ describe('configuration.js', () => {
enabled: true,
some: 'value',
buy: {
- enabled: true,
- maxPurchaseAmounts: { USDT: 80, BNB: 80 }
+ enabled: true
},
sell: { enabled: true }
};
@@ -1158,7 +2997,7 @@ describe('configuration.js', () => {
return {
enabled: true,
some: 'symbol-value',
- buy: { enabled: false, maxPurchaseAmount: -1 },
+ buy: { enabled: false },
sell: { enabled: false }
};
}
@@ -1171,49 +3010,78 @@ describe('configuration.js', () => {
it('returns expected value', () => {
expect(result).toStrictEqual({
enabled: true,
+ cronTime: '* * * * * *',
+ symbols: ['BTCUSDT', 'ETHUSDT', 'ETHBTC', 'XRPBTC'],
+ candles: { interval: '1h', limit: 100 },
some: 'symbol-value',
buy: {
enabled: false,
- maxPurchaseAmount: 80,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: 100,
+ executed: false,
+ executedOrder: null
+ }
+ ],
lastBuyPriceRemoveThreshold: 10,
- triggerPercentage: 1,
- stopPercentage: 1.02,
- limitPercentage: 1.021,
athRestriction: {
enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
+ candles: { interval: '1d', limit: 30 },
restrictionPercentage: 0.9
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: 100,
+ executed: false,
+ executedOrder: null
}
},
sell: {
enabled: false,
- triggerPercentage: 1.06,
- stopPercentage: 0.98,
- limitPercentage: 0.979,
+ gridTrade: [
+ {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
stopLoss: {
enabled: false,
maxLossPercentage: 0.8,
disableBuyMinutes: 360,
orderType: 'market'
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
}
},
- cronTime: '* * * * * *',
- symbols: ['BTCUSDT', 'ETHUSDT', 'ETHBTC', 'XRPBTC'],
- candles: { interval: '1h', limit: 100 },
system: {
temporaryDisableActionAfterConfirmingOrder: 20,
checkManualBuyOrderPeriod: 5,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 1
+ refreshAccountInfoPeriod: 1,
+ checkOrderExecutePeriod: 10
}
});
});
});
- describe('when symbol info is not cached', () => {
+ describe('when cached symbol info is not valid', () => {
beforeEach(async () => {
cache.hget = jest.fn().mockResolvedValue(null);
mongo.findOne = jest.fn((_logger, collection, filter) => {
@@ -1224,7 +3092,9 @@ describe('configuration.js', () => {
return {
enabled: true,
some: 'value',
- buy: { enabled: true, maxPurchaseAmounts: { BNB: 80 } },
+ buy: {
+ enabled: true
+ },
sell: { enabled: true }
};
}
@@ -1236,7 +3106,7 @@ describe('configuration.js', () => {
return {
enabled: true,
some: 'symbol-value',
- buy: { enabled: false, maxPurchaseAmount: -1 },
+ buy: { enabled: false },
sell: { enabled: false }
};
}
@@ -1250,46 +3120,887 @@ describe('configuration.js', () => {
expect(result).toStrictEqual({
enabled: true,
some: 'symbol-value',
- cronTime: '* * * * * *',
- symbols: ['BTCUSDT', 'ETHUSDT', 'ETHBTC', 'XRPBTC'],
- candles: { interval: '1h', limit: 100 },
buy: {
enabled: false,
- maxPurchaseAmount: -1,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
lastBuyPriceRemoveThreshold: -1,
- triggerPercentage: 1,
- stopPercentage: 1.02,
- limitPercentage: 1.021,
athRestriction: {
enabled: true,
- candles: {
- interval: '1d',
- limit: 30
- },
+ candles: { interval: '1d', limit: 30 },
restrictionPercentage: 0.9
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ executed: false,
+ executedOrder: null
}
},
sell: {
enabled: false,
- triggerPercentage: 1.06,
- stopPercentage: 0.98,
- limitPercentage: 0.979,
+ gridTrade: [
+ {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: -1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
stopLoss: {
enabled: false,
maxLossPercentage: 0.8,
disableBuyMinutes: 360,
orderType: 'market'
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.06,
+ stopPercentage: 0.98,
+ limitPercentage: 0.979,
+ quantityPercentage: -1,
+ executed: false,
+ executedOrder: null
}
},
+ cronTime: '* * * * * *',
+ symbols: ['BTCUSDT', 'ETHUSDT', 'ETHBTC', 'XRPBTC'],
+ candles: { interval: '1h', limit: 100 },
system: {
temporaryDisableActionAfterConfirmingOrder: 20,
checkManualBuyOrderPeriod: 5,
placeManualOrderInterval: 5,
- refreshAccountInfoPeriod: 1
+ refreshAccountInfoPeriod: 1,
+ checkOrderExecutePeriod: 10
}
});
});
});
+
+ describe('when configuration are valid format', () => {
+ describe('global configuration has different grid trade lengths', () => {
+ describe('global configuration has more grid trade definitions', () => {
+ beforeEach(async () => {
+ cache.hget = jest.fn().mockResolvedValue(
+ JSON.stringify({
+ quoteAsset: 'USDT',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ })
+ );
+ mongo.findOne = jest.fn((_logger, collection, filter) => {
+ if (
+ collection === 'trailing-trade-common' &&
+ _.isEqual(filter, { key: 'configuration' })
+ ) {
+ return {
+ enabled: true,
+ cronTime: '* * * * * *',
+ symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
+ candles: {
+ interval: '1d',
+ limit: 10
+ },
+ buy: {
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ }
+ ],
+ lastBuyPriceRemoveThreshold: -1,
+ lastBuyPriceRemoveThresholds: {
+ USDT: 5,
+ BTC: 0.00005,
+ BUSD: 5
+ },
+ athRestriction: {
+ enabled: true,
+ candles: {
+ interval: '1d',
+ limit: 30
+ },
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1.05,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 0.3,
+ BTC: 0.3,
+ BUSD: 0.3
+ }
+ },
+ {
+ triggerPercentage: 1.08,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 0.8,
+ BTC: 0.8,
+ BUSD: 0.8
+ }
+ },
+ {
+ triggerPercentage: 1.09,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 1,
+ BTC: 1,
+ BUSD: 1
+ }
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.95,
+ disableBuyMinutes: 60,
+ orderType: 'market'
+ }
+ },
+ system: {
+ temporaryDisableActionAfterConfirmingOrder: 10,
+ checkManualBuyOrderPeriod: 10,
+ placeManualOrderInterval: 5,
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
+ }
+ };
+ }
+
+ if (
+ collection === 'trailing-trade-symbols' &&
+ _.isEqual(filter, { key: 'BTCUSDT-configuration' })
+ ) {
+ return {
+ key: 'BTCUSDT-configuration',
+ candles: {
+ interval: '1h',
+ limit: 50
+ },
+ buy: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.045,
+ limitPercentage: 1.046,
+ maxPurchaseAmount: 22
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 5
+ },
+ sell: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.81,
+ disableBuyMinutes: 65,
+ orderType: 'market'
+ }
+ }
+ };
+ }
+ return null;
+ });
+
+ result = await configuration.getConfiguration(
+ logger,
+ 'BTCUSDT'
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ key: 'BTCUSDT-configuration',
+ candles: { interval: '1h', limit: 50 },
+ buy: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.045,
+ limitPercentage: 1.046,
+ maxPurchaseAmount: 22,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 5,
+ athRestriction: {
+ enabled: true,
+ candles: { interval: '1d', limit: 30 },
+ restrictionPercentage: 0.9
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.81,
+ disableBuyMinutes: 65,
+ orderType: 'market'
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ enabled: true,
+ cronTime: '* * * * * *',
+ symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
+ system: {
+ temporaryDisableActionAfterConfirmingOrder: 10,
+ checkManualBuyOrderPeriod: 10,
+ placeManualOrderInterval: 5,
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
+ }
+ });
+ });
+ });
+
+ describe('symbol configuration has more grid trade definitions', () => {
+ beforeEach(async () => {
+ cache.hget = jest.fn().mockResolvedValue(
+ JSON.stringify({
+ quoteAsset: 'USDT',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ })
+ );
+ mongo.findOne = jest.fn((_logger, collection, filter) => {
+ if (
+ collection === 'trailing-trade-common' &&
+ _.isEqual(filter, { key: 'configuration' })
+ ) {
+ return {
+ enabled: true,
+ cronTime: '* * * * * *',
+ symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
+ candles: {
+ interval: '1d',
+ limit: 10
+ },
+ buy: {
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ }
+ ],
+ lastBuyPriceRemoveThreshold: -1,
+ lastBuyPriceRemoveThresholds: {
+ USDT: 5,
+ BTC: 0.00005,
+ BUSD: 5
+ },
+ athRestriction: {
+ enabled: true,
+ candles: {
+ interval: '1d',
+ limit: 30
+ },
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1.05,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 0.3,
+ BTC: 0.3,
+ BUSD: 0.3
+ }
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.95,
+ disableBuyMinutes: 60,
+ orderType: 'market'
+ }
+ },
+ system: {
+ temporaryDisableActionAfterConfirmingOrder: 10,
+ checkManualBuyOrderPeriod: 10,
+ placeManualOrderInterval: 5,
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
+ }
+ };
+ }
+
+ if (
+ collection === 'trailing-trade-symbols' &&
+ _.isEqual(filter, { key: 'BTCUSDT-configuration' })
+ ) {
+ return {
+ key: 'BTCUSDT-configuration',
+ candles: {
+ interval: '1h',
+ limit: 50
+ },
+ buy: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.045,
+ limitPercentage: 1.046,
+ maxPurchaseAmount: 22
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.055,
+ limitPercentage: 1.056,
+ maxPurchaseAmount: 22
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.065,
+ limitPercentage: 1.066,
+ maxPurchaseAmount: 22
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 8
+ },
+ sell: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 0.5
+ },
+ {
+ triggerPercentage: 1.055,
+ stopPercentage: 0.965,
+ limitPercentage: 0.964,
+ quantityPercentage: 0.6
+ },
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.955,
+ limitPercentage: 0.954,
+ quantityPercentage: 1
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.81,
+ disableBuyMinutes: 65,
+ orderType: 'market'
+ }
+ }
+ };
+ }
+ return null;
+ });
+
+ result = await configuration.getConfiguration(
+ logger,
+ 'BTCUSDT'
+ );
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ key: 'BTCUSDT-configuration',
+ candles: { interval: '1h', limit: 50 },
+ buy: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.045,
+ limitPercentage: 1.046,
+ maxPurchaseAmount: 22,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.055,
+ limitPercentage: 1.056,
+ maxPurchaseAmount: 22,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.065,
+ limitPercentage: 1.066,
+ maxPurchaseAmount: 22,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 8,
+ athRestriction: {
+ enabled: true,
+ candles: { interval: '1d', limit: 30 },
+ restrictionPercentage: 0.9
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 0.5,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.055,
+ stopPercentage: 0.965,
+ limitPercentage: 0.964,
+ quantityPercentage: 0.6,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.955,
+ limitPercentage: 0.954,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.81,
+ disableBuyMinutes: 65,
+ orderType: 'market'
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 0.5,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ enabled: true,
+ cronTime: '* * * * * *',
+ symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
+ system: {
+ temporaryDisableActionAfterConfirmingOrder: 10,
+ checkManualBuyOrderPeriod: 10,
+ placeManualOrderInterval: 5,
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
+ }
+ });
+ });
+ });
+ });
+
+ describe('global configuration has same grid trade lengths', () => {
+ beforeEach(async () => {
+ cache.hget = jest.fn().mockResolvedValue(
+ JSON.stringify({
+ quoteAsset: 'USDT',
+ filterMinNotional: {
+ minNotional: '10.00000000'
+ }
+ })
+ );
+ mongo.findOne = jest.fn((_logger, collection, filter) => {
+ if (
+ collection === 'trailing-trade-common' &&
+ _.isEqual(filter, { key: 'configuration' })
+ ) {
+ return {
+ enabled: true,
+ cronTime: '* * * * * *',
+ symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
+ candles: {
+ interval: '1d',
+ limit: 10
+ },
+ buy: {
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.02,
+ limitPercentage: 1.021,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts: {
+ USDT: 100,
+ BTC: 0.001,
+ BUSD: 100
+ }
+ }
+ ],
+ lastBuyPriceRemoveThreshold: -1,
+ lastBuyPriceRemoveThresholds: {
+ USDT: 5,
+ BTC: 0.00005,
+ BUSD: 5
+ },
+ athRestriction: {
+ enabled: true,
+ candles: {
+ interval: '1d',
+ limit: 30
+ },
+ restrictionPercentage: 0.9
+ }
+ },
+ sell: {
+ enabled: false,
+ gridTrade: [
+ {
+ triggerPercentage: 1.08,
+ stopPercentage: 0.95,
+ limitPercentage: 0.949,
+ quantityPercentage: -1,
+ quantityPercentages: {
+ USDT: 1,
+ BTC: 1,
+ BUSD: 1
+ }
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.95,
+ disableBuyMinutes: 60,
+ orderType: 'market'
+ }
+ },
+ system: {
+ temporaryDisableActionAfterConfirmingOrder: 10,
+ checkManualBuyOrderPeriod: 10,
+ placeManualOrderInterval: 5,
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
+ }
+ };
+ }
+
+ if (
+ collection === 'trailing-trade-symbols' &&
+ _.isEqual(filter, { key: 'BTCUSDT-configuration' })
+ ) {
+ return {
+ key: 'BTCUSDT-configuration',
+ candles: {
+ interval: '1h',
+ limit: 50
+ },
+ buy: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.045,
+ limitPercentage: 1.046,
+ maxPurchaseAmount: 22
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.055,
+ limitPercentage: 1.056,
+ maxPurchaseAmount: 33
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 5
+ },
+ sell: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ quantityPercentages: {
+ USDT: 1
+ }
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.81,
+ disableBuyMinutes: 65,
+ orderType: 'market'
+ }
+ }
+ };
+ }
+ return null;
+ });
+
+ result = await configuration.getConfiguration(logger, 'BTCUSDT');
+ });
+
+ it('returns expected value', () => {
+ expect(result).toStrictEqual({
+ key: 'BTCUSDT-configuration',
+ candles: { interval: '1h', limit: 50 },
+ buy: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.045,
+ limitPercentage: 1.046,
+ maxPurchaseAmount: 22,
+ executed: false,
+ executedOrder: null
+ },
+ {
+ triggerPercentage: 0.9,
+ stopPercentage: 1.055,
+ limitPercentage: 1.056,
+ maxPurchaseAmount: 33,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ lastBuyPriceRemoveThreshold: 5,
+ athRestriction: {
+ enabled: true,
+ candles: { interval: '1d', limit: 30 },
+ restrictionPercentage: 0.9
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1,
+ stopPercentage: 1.035,
+ limitPercentage: 1.036,
+ maxPurchaseAmount: 11,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ sell: {
+ enabled: true,
+ gridTrade: [
+ {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ ],
+ stopLoss: {
+ enabled: true,
+ maxLossPercentage: 0.81,
+ disableBuyMinutes: 65,
+ orderType: 'market'
+ },
+ currentGridTradeIndex: 0,
+ currentGridTrade: {
+ triggerPercentage: 1.045,
+ stopPercentage: 0.975,
+ limitPercentage: 0.974,
+ quantityPercentage: 1,
+ executed: false,
+ executedOrder: null
+ }
+ },
+ enabled: true,
+ cronTime: '* * * * * *',
+ symbols: ['BNBUSDT', 'TRXBUSD', 'LTCUSDT', 'XRPBTC'],
+ system: {
+ temporaryDisableActionAfterConfirmingOrder: 10,
+ checkManualBuyOrderPeriod: 10,
+ placeManualOrderInterval: 5,
+ refreshAccountInfoPeriod: 3,
+ checkOrderExecutePeriod: 10
+ }
+ });
+ });
+ });
+ });
});
});
});
diff --git a/app/cronjob/trailingTradeHelper/common.js b/app/cronjob/trailingTradeHelper/common.js
index 8a95ddc0..48f1769b 100644
--- a/app/cronjob/trailingTradeHelper/common.js
+++ b/app/cronjob/trailingTradeHelper/common.js
@@ -1,5 +1,6 @@
const _ = require('lodash');
-const { cache, binance, mongo } = require('../../helpers');
+const moment = require('moment');
+const { cache, binance, mongo, PubSub, slack } = require('../../helpers');
const isValidCachedExchangeSymbols = exchangeSymbols =>
_.get(
@@ -461,6 +462,92 @@ const getOverrideDataForIndicator = async (_logger, key) => {
const removeOverrideDataForIndicator = async (_logger, key) =>
cache.hdel('trailing-trade-indicator-override', key);
+/**
+ * Retrieve last buy price and recalculate new last buy price
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} order
+ */
+const calculateLastBuyPrice = async (logger, symbol, order) => {
+ const { type, executedQty, cummulativeQuoteQty } = order;
+ const lastBuyPriceDoc = await getLastBuyPrice(logger, symbol);
+
+ const orgLastBuyPrice = _.get(lastBuyPriceDoc, 'lastBuyPrice', 0);
+ const orgQuantity = _.get(lastBuyPriceDoc, 'quantity', 0);
+ const orgTotalAmount = orgLastBuyPrice * orgQuantity;
+
+ logger.info(
+ { orgLastBuyPrice, orgQuantity, orgTotalAmount },
+ 'Existing last buy price'
+ );
+
+ const filledQuoteQty = parseFloat(cummulativeQuoteQty);
+ const filledQuantity = parseFloat(executedQty);
+
+ const newQuantity = orgQuantity + filledQuantity;
+ const newTotalAmount = orgTotalAmount + filledQuoteQty;
+
+ const newLastBuyPrice = newTotalAmount / newQuantity;
+
+ logger.info(
+ { newLastBuyPrice, newTotalAmount, newQuantity },
+ 'New last buy price'
+ );
+ await saveLastBuyPrice(logger, symbol, {
+ lastBuyPrice: newLastBuyPrice,
+ quantity: newQuantity
+ });
+
+ PubSub.publish('frontend-notification', {
+ type: 'success',
+ title: `New last buy price for ${symbol} has been updated.`
+ });
+
+ slack.sendMessage(
+ `${symbol} Last buy price Updated (${moment().format(
+ 'HH:mm:ss.SSS'
+ )}): *${type}*\n` +
+ `- Order Result: \`\`\`${JSON.stringify(
+ {
+ orgLastBuyPrice,
+ orgQuantity,
+ orgTotalAmount,
+ newLastBuyPrice,
+ newQuantity,
+ newTotalAmount
+ },
+ undefined,
+ 2
+ )}\`\`\`\n` +
+ `- Current API Usage: ${getAPILimit(logger)}`
+ );
+};
+
+/**
+ * Save order to mongodb
+ *
+ * @param {*} logger
+ * @param {*} data
+ */
+const saveOrder = async (logger, data) => {
+ logger.info({ tag: 'save-order', data }, 'Save order');
+
+ // Order ID must be included.
+ const {
+ order: { orderId }
+ } = data;
+ return mongo.upsertOne(
+ logger,
+ 'trailing-trade-orders',
+ { key: orderId },
+ {
+ key: orderId,
+ ...data
+ }
+ );
+};
+
module.exports = {
cacheExchangeSymbols,
getAccountInfoFromAPI,
@@ -482,5 +569,7 @@ module.exports = {
getOverrideDataForSymbol,
removeOverrideDataForSymbol,
getOverrideDataForIndicator,
- removeOverrideDataForIndicator
+ removeOverrideDataForIndicator,
+ calculateLastBuyPrice,
+ saveOrder
};
diff --git a/app/cronjob/trailingTradeHelper/configuration.js b/app/cronjob/trailingTradeHelper/configuration.js
index 4fddb8a7..bbb0c8c1 100644
--- a/app/cronjob/trailingTradeHelper/configuration.js
+++ b/app/cronjob/trailingTradeHelper/configuration.js
@@ -2,6 +2,8 @@ const _ = require('lodash');
const config = require('config');
const { mongo, cache, PubSub } = require('../../helpers');
+const { getLastBuyPrice } = require('./common');
+
/**
* Save global configuration to mongodb
*
@@ -87,6 +89,31 @@ const getSymbolConfiguration = async (logger, symbol = null) => {
return configValue;
};
+/**
+ * Get symbol's grid trade configuration from mongodb
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ */
+const getSymbolGridTrade = async (logger, symbol = null) => {
+ if (symbol === null) {
+ // If symbol is not provided, then return empty.
+ return {};
+ }
+
+ const configValue =
+ (await mongo.findOne(logger, 'trailing-trade-grid-trade', {
+ key: `${symbol}`
+ })) || {};
+
+ if (_.isEmpty(configValue)) {
+ logger.info('Could not find saved symbol grid trade.');
+ return {};
+ }
+
+ return configValue;
+};
+
/**
* Save symbol configuration to mongodb
*
@@ -117,87 +144,232 @@ const saveSymbolConfiguration = async (
);
};
+/**
+ * Save symbol grid trade to mongodb
+ *
+ * @param {*} logger
+ * @param {*} symbol
+ * @param {*} gridTrade
+ */
+const saveSymbolGridTrade = async (logger, symbol = null, gridTrade = {}) => {
+ if (symbol === null) {
+ // If symbol is not provided, then return empty.
+ return {};
+ }
+
+ return mongo.upsertOne(
+ logger,
+ 'trailing-trade-grid-trade',
+ {
+ key: `${symbol}`
+ },
+ {
+ key: `${symbol}`,
+ ...gridTrade
+ }
+ );
+};
+
+/**
+ * Delete all symbol configurations
+ *
+ * @param {*} logger
+ * @returns
+ */
const deleteAllSymbolConfiguration = async logger =>
mongo.deleteAll(logger, 'trailing-trade-symbols', {
key: { $regex: /^(.+)-configuration/ }
});
+/**
+ * Delete specific symbol configuration
+ * @param {*} logger
+ * @param {*} symbol
+ * @returns
+ */
const deleteSymbolConfiguration = async (logger, symbol) =>
mongo.deleteOne(logger, 'trailing-trade-symbols', {
key: `${symbol}-configuration`
});
-const getMaxPurchaseAmount = async (
+/**
+ * Delete all symbol grid trade information
+ *
+ * @param {*} logger
+ * @returns
+ */
+const deleteAllSymbolGridTrade = async logger =>
+ mongo.deleteAll(logger, 'trailing-trade-grid-trade', {});
+
+/**
+ * Delete specific symbol grid trade information
+ * @param {*} logger
+ * @param {*} symbol
+ * @returns
+ */
+const deleteSymbolGridTrade = async (logger, symbol) =>
+ mongo.deleteOne(logger, 'trailing-trade-grid-trade', {
+ key: `${symbol}`
+ });
+
+/**
+ * Get buy max purchase amount of grid trade for buying
+ *
+ * @param {*} logger
+ * @param {*} cachedSymbolInfo
+ * @param {*} globalConfiguration
+ * @param {*} symbolConfiguration
+ * @returns
+ */
+const getGridTradeBuy = (
logger,
- symbol,
+ cachedSymbolInfo,
globalConfiguration,
symbolConfiguration
) => {
- const symbolBuyMaxPurchaseAmount = _.get(
- symbolConfiguration,
- 'buy.maxPurchaseAmount',
- -1
- );
+ const {
+ buy: { gridTrade: srcGridTrade }
+ } = symbolConfiguration;
- if (symbolBuyMaxPurchaseAmount !== -1) {
- logger.info(
- { symbolBuyMaxPurchaseAmount },
- 'Max purchase amount is found from symbol configuration.'
- );
- return symbolBuyMaxPurchaseAmount;
+ let orgGridTrade = srcGridTrade;
+ if (_.isEmpty(srcGridTrade)) {
+ orgGridTrade = globalConfiguration.buy.gridTrade;
}
- logger.info(
- { symbolBuyMaxPurchaseAmount },
- 'Max purchase amount is set as -1. Need to calculate and override it'
- );
+ // Loop symbol's buy.gridTrade
+ const gridTrade = orgGridTrade.map((orgGrid, index) => {
+ const grid = orgGrid;
- let newBuyMaxPurchaseAmount = -1;
+ // Retrieve configured max purchase amount.
+ const symbolMaxPurchaseAmount = _.get(grid, 'maxPurchaseAmount', -1);
- // If old max purchase amount is -1, then should calculate last buy remove threshold based on the notional amount.
- const cachedSymbolInfo =
- JSON.parse(
- await cache.hget('trailing-trade-symbols', `${symbol}-symbol-info`)
- ) || {};
-
- if (_.isEmpty(cachedSymbolInfo) === false) {
- const {
- quoteAsset,
- filterMinNotional: { minNotional }
- } = cachedSymbolInfo;
+ // If max purchase amount is not -1, then it is already configrued. Return grid.
+ if (symbolMaxPurchaseAmount !== -1) {
+ _.unset(grid, 'maxPurchaseAmounts');
+ return grid;
+ }
- newBuyMaxPurchaseAmount = _.get(
- globalConfiguration,
- `buy.maxPurchaseAmounts.${quoteAsset}`,
- -1
- );
+ let newMaxPurchaseAmount = -1;
- logger.info(
- { quoteAsset, newBuyMaxPurchaseAmount },
- 'Retrieved max purchase amount from global configuration'
- );
+ if (_.isEmpty(cachedSymbolInfo) === false) {
+ const {
+ quoteAsset,
+ filterMinNotional: { minNotional }
+ } = cachedSymbolInfo;
- if (newBuyMaxPurchaseAmount === -1) {
- newBuyMaxPurchaseAmount = parseFloat(minNotional) * 10;
+ // Retrieve configured max purchase amount for the quote asset from the global configuration.
+ newMaxPurchaseAmount = _.get(
+ globalConfiguration,
+ `buy.gridTrade[${index}].maxPurchaseAmounts[${quoteAsset}]`,
+ -1
+ );
+ // If max purchase amount for the quote asset in the global configuration is not defined,
+ // then use the minimum notional value * 10.
+ if (newMaxPurchaseAmount === -1) {
+ newMaxPurchaseAmount = parseFloat(minNotional) * 10;
+ }
+ } else {
logger.info(
- { newBuyMaxPurchaseAmount, minNotional },
- 'Could not get max purchase amount from global configuration. Use minimum notional from symbol info'
+ { cachedSymbolInfo },
+ 'Could not find symbol info for buy max purchase amount, wait to be cached.'
);
}
- } else {
- logger.info(
- { cachedSymbolInfo },
- 'Could not find symbol info, wait to be cached.'
- );
+
+ _.set(grid, 'maxPurchaseAmount', newMaxPurchaseAmount);
+ _.unset(grid, 'maxPurchaseAmounts');
+
+ return grid;
+ });
+
+ return gridTrade;
+};
+
+/**
+ * Get quantity percentage of grid trade for selling
+ *
+ * @param {*} logger
+ * @param {*} cachedSymbolInfo
+ * @param {*} globalConfiguration
+ * @param {*} symbolConfiguration
+ * @returns
+ */
+const getGridTradeSell = (
+ logger,
+ cachedSymbolInfo,
+ globalConfiguration,
+ symbolConfiguration
+) => {
+ const {
+ sell: { gridTrade: srcGridTrade }
+ } = symbolConfiguration;
+
+ let orgGridTrade = srcGridTrade;
+ if (_.isEmpty(srcGridTrade)) {
+ orgGridTrade = globalConfiguration.sell.gridTrade;
}
+ const gridTradeLength = orgGridTrade.length;
+
+ // Loop symbol's sell.gridTrade
+ const gridTrade = orgGridTrade.map((orgGrid, index) => {
+ const grid = orgGrid;
+
+ // Retrieve configrued quantity percentage
+ const symbolQuantityPercentage = _.get(grid, 'quantityPercentage', -1);
+
+ if (symbolQuantityPercentage !== -1) {
+ _.unset(grid, 'quantityPercentages');
+ return grid;
+ }
+
+ let newQuantityPercentage = -1;
+
+ // Retrieve symbol information cache
+ if (_.isEmpty(cachedSymbolInfo) === false) {
+ const { quoteAsset } = cachedSymbolInfo;
+
+ // Retrieve configured quantity percentage for the quote asset from the global configuration.
+ newQuantityPercentage = _.get(
+ globalConfiguration,
+ `sell.gridTrade[${index}].quantityPercentages[${quoteAsset}]`,
+ -1
+ );
+
+ // If quantity percentage for the quote asset in the global configuration is not defined,
+ // then set custom quantity.
+ if (newQuantityPercentage === -1) {
+ newQuantityPercentage =
+ gridTradeLength !== index + 1
+ ? parseFloat((1 / gridTradeLength).toFixed(2))
+ : 1;
+ }
+ } else {
+ logger.info(
+ { cachedSymbolInfo },
+ 'Could not find symbol info for sell quantity percentage, wait to be cached.'
+ );
+ }
+
+ _.set(grid, 'quantityPercentage', newQuantityPercentage);
+ _.unset(grid, 'quantityPercentages');
- return newBuyMaxPurchaseAmount;
+ return grid;
+ });
+
+ return gridTrade;
};
-const getLastBuyPriceRemoveThreshold = async (
+/**
+ * Get last buy price remove threshold
+ * @param {*} logger
+ * @param {*} cachedSymbolInfo
+ * @param {*} globalConfiguration
+ * @param {*} symbolConfiguration
+ * @returns
+ */
+const getLastBuyPriceRemoveThreshold = (
logger,
- symbol,
+ cachedSymbolInfo,
globalConfiguration,
symbolConfiguration
) => {
@@ -224,11 +396,6 @@ const getLastBuyPriceRemoveThreshold = async (
// If old last buy price remove threshold is -1,
// then should calculate last buy price remove threshold based on the notional amount.
- const cachedSymbolInfo =
- JSON.parse(
- await cache.hget('trailing-trade-symbols', `${symbol}-symbol-info`)
- ) || {};
-
if (_.isEmpty(cachedSymbolInfo) === false) {
const {
quoteAsset,
@@ -263,6 +430,106 @@ const getLastBuyPriceRemoveThreshold = async (
return newBuyLastBuyPriceRemoveThreshold;
};
+
+/**
+ * Post process configuration
+ * - Retrieve grid trade and determine current grid trade
+ * - If symbol grid trade is stored and has executed value, then use stored grid trade.
+ *
+ * @param {*} logger
+ * @param {*} configuration
+ * @param {*} extraParams
+ * @returns
+ */
+const postProcessConfiguration = async (
+ logger,
+ configuration,
+ { symbolGridTrade, symbol }
+) => {
+ const newConfiguration = configuration;
+
+ const lastBuyPriceDoc = await getLastBuyPrice(logger, symbol);
+ const lastBuyPrice = _.get(lastBuyPriceDoc, 'lastBuyPrice', null);
+
+ // Retrieve grid trade and determine current grid trade
+ ['buy', 'sell'].forEach(side => {
+ let currentGridTradeIndex = -1;
+ let currentGridTrade = null;
+ let overridenGridTrade = configuration[side].gridTrade;
+
+ // If symbol grid trade is stored and has executed value at least one time
+ if (
+ symbolGridTrade[side] &&
+ symbolGridTrade[side].some(g => g?.executed === true)
+ ) {
+ // Find executed grid trade
+ symbolGridTrade[side].forEach((gridTrade, index) => {
+ // If grid trade is executed, then override grid trade
+ if (gridTrade?.executed) {
+ overridenGridTrade[index] = gridTrade;
+ }
+ });
+
+ // Calculate current grid trade
+ overridenGridTrade.forEach((gridTrade, index) => {
+ // If current grid trade is executed,
+ if (gridTrade?.executed) {
+ // If next gird trade exists, then get next grid trade as current buy grid trade
+ if (overridenGridTrade[index + 1]) {
+ currentGridTradeIndex = index + 1;
+ currentGridTrade = overridenGridTrade[index + 1];
+ } else {
+ // If next gird trade does not exist, then do not set current grid trade
+ currentGridTradeIndex = -1;
+ currentGridTrade = null;
+ }
+ }
+ });
+ } else if (
+ side === 'buy' &&
+ lastBuyPrice > 0 &&
+ overridenGridTrade[1] !== undefined
+ ) {
+ // If none of grid trade is executed, side is buy, last buy is recorded, 2nd grid trade is defined
+
+ currentGridTradeIndex = 1;
+ [, currentGridTrade] = overridenGridTrade;
+ } else if (
+ side === 'buy' &&
+ lastBuyPrice > 0 &&
+ overridenGridTrade[1] === undefined
+ ) {
+ // If none of grid trade is executed, side is buy, last buy is recorded, 2nd grid trade is not defined
+
+ currentGridTradeIndex = -1;
+ currentGridTrade = null;
+ } else {
+ // Otherwise, get first grid trade as current grid trade
+
+ currentGridTradeIndex = 0;
+ [currentGridTrade] = overridenGridTrade;
+ }
+
+ // Set extra parameters for grid trade if not defined
+ overridenGridTrade = overridenGridTrade.map(orgGridTrade => {
+ const gridTrade = orgGridTrade;
+ if (gridTrade.executed === undefined) {
+ gridTrade.executed = false;
+ gridTrade.executedOrder = null;
+ }
+
+ return gridTrade;
+ });
+
+ // If current grid trade index is -1, then it means grid is all executed.
+ newConfiguration[side].currentGridTradeIndex = currentGridTradeIndex;
+ newConfiguration[side].currentGridTrade = currentGridTrade;
+ newConfiguration[side].gridTrade = overridenGridTrade;
+ });
+
+ return newConfiguration;
+};
+
/**
* Get global/symbol configuration
*
@@ -273,38 +540,53 @@ const getConfiguration = async (logger, symbol = null) => {
// If symbol is not provided, then it only looks up global configuration
const globalConfigValue = await getGlobalConfiguration(logger);
const symbolConfigValue = await getSymbolConfiguration(logger, symbol);
+ const symbolGridTrade = await getSymbolGridTrade(logger, symbol);
- // Merge global and symbol configuration
- const mergedConfigValue = _.defaultsDeep(
+ // Merge global and symbol configuration without grid trade if symbol is provided.
+ let mergedConfigValue = _.defaultsDeep(
symbolConfigValue,
- globalConfigValue
+ symbol !== null
+ ? _.omit(globalConfigValue, 'buy.gridTrade', 'sell.gridTrade')
+ : globalConfigValue
);
if (symbol !== null) {
- _.set(
- mergedConfigValue,
- 'buy.maxPurchaseAmount',
- await getMaxPurchaseAmount(
- logger,
- symbol,
- globalConfigValue,
- symbolConfigValue
- )
- );
+ const cachedSymbolInfo =
+ JSON.parse(
+ await cache.hget('trailing-trade-symbols', `${symbol}-symbol-info`)
+ ) || {};
+
+ // Post process configuration value to prefill some default values
+ [
+ {
+ key: 'buy.gridTrade',
+ keyFunc: getGridTradeBuy
+ },
+ {
+ key: 'buy.lastBuyPriceRemoveThreshold',
+ keyFunc: getLastBuyPriceRemoveThreshold
+ },
+ {
+ key: 'sell.gridTrade',
+ keyFunc: getGridTradeSell
+ }
+ ].forEach(d => {
+ const { key, keyFunc } = d;
+ _.set(
+ mergedConfigValue,
+ key,
+ keyFunc(logger, cachedSymbolInfo, globalConfigValue, symbolConfigValue)
+ );
+ });
- _.set(
+ // For symbol configuration, remove lastBuyPriceRemoveThresholds
+ _.unset(mergedConfigValue, 'buy.lastBuyPriceRemoveThresholds');
+
+ // Post process configuration to get current grid trade
+ mergedConfigValue = await postProcessConfiguration(
+ logger,
mergedConfigValue,
- 'buy.lastBuyPriceRemoveThreshold',
- await getLastBuyPriceRemoveThreshold(
- logger,
- symbol,
- globalConfigValue,
- symbolConfigValue
- )
+ { symbolGridTrade, symbol }
);
-
- // For symbol configuration, remove maxPurchaseAmounts
- _.unset(mergedConfigValue, 'buy.maxPurchaseAmounts');
- _.unset(mergedConfigValue, 'buy.lastBuyPriceRemoveThresholds');
}
// Merge global and symbol configuration
@@ -312,11 +594,25 @@ const getConfiguration = async (logger, symbol = null) => {
};
module.exports = {
+ saveGlobalConfiguration,
+
getGlobalConfiguration,
getSymbolConfiguration,
- saveGlobalConfiguration,
+ getSymbolGridTrade,
+
saveSymbolConfiguration,
+ saveSymbolGridTrade,
+
deleteAllSymbolConfiguration,
deleteSymbolConfiguration,
+ deleteAllSymbolGridTrade,
+ deleteSymbolGridTrade,
+
+ getGridTradeBuy,
+ getGridTradeSell,
+ getLastBuyPriceRemoveThreshold,
+
+ postProcessConfiguration,
+
getConfiguration
};
diff --git a/app/frontend/websocket/__tests__/configure.test.js b/app/frontend/websocket/__tests__/configure.test.js
index 7dd88cc9..97edd9da 100644
--- a/app/frontend/websocket/__tests__/configure.test.js
+++ b/app/frontend/websocket/__tests__/configure.test.js
@@ -18,7 +18,9 @@ describe('websocket/configure.js', () => {
let mockHandleSymbolDelete;
let mockHandleSymbolSettingUpdate;
let mockHandleSymbolSettingDelete;
+ let mockHandleSymbolGridTradeDelete;
let mockHandleSymbolEnableAction;
+ let mockHandleSymbolTriggerBuy;
let mockHandleManualTrade;
let mockHandleManualTradeAllSymbols;
let mockHandleCancelOrder;
@@ -90,7 +92,9 @@ describe('websocket/configure.js', () => {
mockHandleSymbolDelete = jest.fn().mockResolvedValue(true);
mockHandleSymbolSettingUpdate = jest.fn().mockResolvedValue(true);
mockHandleSymbolSettingDelete = jest.fn().mockResolvedValue(true);
+ mockHandleSymbolGridTradeDelete = jest.fn().mockResolvedValue(true);
mockHandleSymbolEnableAction = jest.fn().mockResolvedValue(true);
+ mockHandleSymbolTriggerBuy = jest.fn().mockResolvedValue(true);
mockHandleManualTrade = jest.fn().mockResolvedValue(true);
mockHandleManualTradeAllSymbols = jest.fn().mockResolvedValue(true);
mockHandleCancelOrder = jest.fn().mockResolvedValue(true);
@@ -104,7 +108,9 @@ describe('websocket/configure.js', () => {
handleSymbolDelete: mockHandleSymbolDelete,
handleSymbolSettingUpdate: mockHandleSymbolSettingUpdate,
handleSymbolSettingDelete: mockHandleSymbolSettingDelete,
+ handleSymbolGridTradeDelete: mockHandleSymbolGridTradeDelete,
handleSymbolEnableAction: mockHandleSymbolEnableAction,
+ handleSymbolTriggerBuy: mockHandleSymbolTriggerBuy,
handleManualTrade: mockHandleManualTrade,
handleManualTradeAllSymbols: mockHandleManualTradeAllSymbols,
handleCancelOrder: mockHandleCancelOrder,
@@ -590,6 +596,54 @@ describe('websocket/configure.js', () => {
});
});
+ describe('when message command is symbol-grid-trade-delete', () => {
+ beforeEach(() => {
+ mockWebSocketServerWebSocketOn = jest
+ .fn()
+ .mockImplementation((_event, cb) => {
+ cb(
+ JSON.stringify({
+ command: 'symbol-grid-trade-delete'
+ })
+ );
+ });
+
+ mockWebSocketServerWebSocketSend = jest.fn().mockReturnValue(true);
+
+ mockWebSocketServerOn = jest.fn().mockImplementation((_event, cb) => {
+ cb({
+ on: mockWebSocketServerWebSocketOn,
+ send: mockWebSocketServerWebSocketSend
+ });
+ });
+
+ WebSocket.Server.mockImplementation(() => ({
+ on: mockWebSocketServerOn,
+ handleUpgrade: mockWebSocketServerHandleUpgrade,
+ emit: mockWebSocketServerEmit
+ }));
+
+ const { logger } = require('../../../helpers');
+
+ const { configureWebSocket } = require('../configure');
+ configureWebSocket(mockExpressServer, logger);
+ });
+
+ it('triggers handleSymbolGridTradeDelete', () => {
+ expect(mockHandleSymbolGridTradeDelete).toHaveBeenCalledWith(
+ expect.any(Object),
+ expect.any(Object),
+ {
+ command: 'symbol-grid-trade-delete'
+ }
+ );
+ });
+
+ it('returns wss', () => {
+ expect(wss).not.toBeNull();
+ });
+ });
+
describe('when message command is symbol-enable-action', () => {
beforeEach(() => {
mockWebSocketServerWebSocketOn = jest
@@ -638,6 +692,54 @@ describe('websocket/configure.js', () => {
});
});
+ describe('when message command is symbol-trigger-buy', () => {
+ beforeEach(() => {
+ mockWebSocketServerWebSocketOn = jest
+ .fn()
+ .mockImplementation((_event, cb) => {
+ cb(
+ JSON.stringify({
+ command: 'symbol-trigger-buy'
+ })
+ );
+ });
+
+ mockWebSocketServerWebSocketSend = jest.fn().mockReturnValue(true);
+
+ mockWebSocketServerOn = jest.fn().mockImplementation((_event, cb) => {
+ cb({
+ on: mockWebSocketServerWebSocketOn,
+ send: mockWebSocketServerWebSocketSend
+ });
+ });
+
+ WebSocket.Server.mockImplementation(() => ({
+ on: mockWebSocketServerOn,
+ handleUpgrade: mockWebSocketServerHandleUpgrade,
+ emit: mockWebSocketServerEmit
+ }));
+
+ const { logger } = require('../../../helpers');
+
+ const { configureWebSocket } = require('../configure');
+ configureWebSocket(mockExpressServer, logger);
+ });
+
+ it('triggers handleSymbolTriggerBuy', () => {
+ expect(mockHandleSymbolTriggerBuy).toHaveBeenCalledWith(
+ expect.any(Object),
+ expect.any(Object),
+ {
+ command: 'symbol-trigger-buy'
+ }
+ );
+ });
+
+ it('returns wss', () => {
+ expect(wss).not.toBeNull();
+ });
+ });
+
describe('when message command is manual-trade', () => {
beforeEach(() => {
mockWebSocketServerWebSocketOn = jest
diff --git a/app/frontend/websocket/configure.js b/app/frontend/websocket/configure.js
index 5fc48a82..b0b26891 100644
--- a/app/frontend/websocket/configure.js
+++ b/app/frontend/websocket/configure.js
@@ -8,7 +8,9 @@ const {
handleSymbolDelete,
handleSymbolSettingUpdate,
handleSymbolSettingDelete,
+ handleSymbolGridTradeDelete,
handleSymbolEnableAction,
+ handleSymbolTriggerBuy,
handleManualTrade,
handleManualTradeAllSymbols,
handleCancelOrder,
@@ -44,51 +46,33 @@ const configureWebSocket = async (server, funcLogger) => {
payload = null;
}
if (payload === null || payload.command === undefined) {
- ws.send(handleWarning(logger, ws, 'Command is not provided.'));
+ handleWarning(logger, ws, 'Command is not provided.');
return;
}
const commandLogger = logger.child({ payload });
- switch (payload.command) {
- case 'latest':
- await handleLatest(commandLogger, ws, payload);
- break;
- case 'setting-update':
- await handleSettingUpdate(commandLogger, ws, payload);
- break;
- case 'symbol-update-last-buy-price':
- await handleSymbolUpdateLastBuyPrice(commandLogger, ws, payload);
- break;
- case 'symbol-delete':
- await handleSymbolDelete(commandLogger, ws, payload);
- break;
- case 'symbol-setting-update':
- await handleSymbolSettingUpdate(commandLogger, ws, payload);
- break;
- case 'symbol-setting-delete':
- await handleSymbolSettingDelete(commandLogger, ws, payload);
- break;
- case 'symbol-enable-action':
- await handleSymbolEnableAction(commandLogger, ws, payload);
- break;
- case 'manual-trade':
- await handleManualTrade(commandLogger, ws, payload);
- break;
- case 'manual-trade-all-symbols':
- await handleManualTradeAllSymbols(commandLogger, ws, payload);
- break;
- case 'cancel-order':
- await handleCancelOrder(commandLogger, ws, payload);
- break;
- case 'dust-transfer-get':
- await handleDustTransferGet(commandLogger, ws, payload);
- break;
- case 'dust-transfer-execute':
- await handleDustTransferExecute(commandLogger, ws, payload);
- break;
- default:
- handleWarning(logger, ws, 'Command is not recognised.');
+ const commandMaps = {
+ latest: handleLatest,
+ 'setting-update': handleSettingUpdate,
+ 'symbol-update-last-buy-price': handleSymbolUpdateLastBuyPrice,
+ 'symbol-delete': handleSymbolDelete,
+ 'symbol-setting-update': handleSymbolSettingUpdate,
+ 'symbol-setting-delete': handleSymbolSettingDelete,
+ 'symbol-grid-trade-delete': handleSymbolGridTradeDelete,
+ 'symbol-enable-action': handleSymbolEnableAction,
+ 'symbol-trigger-buy': handleSymbolTriggerBuy,
+ 'manual-trade': handleManualTrade,
+ 'manual-trade-all-symbols': handleManualTradeAllSymbols,
+ 'cancel-order': handleCancelOrder,
+ 'dust-transfer-get': handleDustTransferGet,
+ 'dust-transfer-execute': handleDustTransferExecute
+ };
+
+ if (commandMaps[payload.command]) {
+ await commandMaps[payload.command](commandLogger, ws, payload);
+ } else {
+ handleWarning(logger, ws, 'Command is not recognised.');
}
});
diff --git a/app/frontend/websocket/handlers/__tests__/fixtures/latest-stats.json b/app/frontend/websocket/handlers/__tests__/fixtures/latest-stats.json
index a10489c3..b8bc6a93 100644
--- a/app/frontend/websocket/handlers/__tests__/fixtures/latest-stats.json
+++ b/app/frontend/websocket/handlers/__tests__/fixtures/latest-stats.json
@@ -7,9 +7,15 @@
"candles": { "interval": "15m", "limit": 100 },
"sell": {
"enabled": true,
- "triggerPercentage": 1.06,
- "stopPercentage": 0.98,
- "limitPercentage": 0.979,
+ "gridTrade": [
+ {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": -1,
+ "quantityPercentages": {}
+ }
+ ],
"stopLoss": {
"enabled": false,
"maxLossPercentage": 0.8,
@@ -21,13 +27,17 @@
"symbols": ["BTCUSDT", "ETHUSDT", "ETHBTC", "XRPBTC"],
"buy": {
"enabled": true,
- "maxPurchaseAmount": -1,
- "maxPurchaseAmounts": {},
+ "gridTrade": [
+ {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": -1,
+ "maxPurchaseAmounts": {}
+ }
+ ],
"lastBuyPriceRemoveThreshold": -1,
"lastBuyPriceRemoveThresholds": {},
- "triggerPercentage": 1,
- "stopPercentage": 1.02,
- "limitPercentage": 1.021,
"athRestriction": {
"enabled": true,
"candles": { "interval": "1d", "limit": 30 },
@@ -38,11 +48,12 @@
"temporaryDisableActionAfterConfirmingOrder": 20,
"checkManualBuyOrderPeriod": 5,
"placeManualOrderInterval": 5,
- "refreshAccountInfoPeriod": 1
+ "refreshAccountInfoPeriod": 1,
+ "checkOrderExecutePeriod": 10
}
},
"common": {
- "version": "0.0.71",
+ "version": "0.0.72",
"gitHash": "some-hash",
"configuration": {
"enabled": true,
@@ -50,9 +61,15 @@
"candles": { "interval": "15m", "limit": 100 },
"sell": {
"enabled": true,
- "triggerPercentage": 1.06,
- "stopPercentage": 0.98,
- "limitPercentage": 0.979,
+ "gridTrade": [
+ {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": -1,
+ "quantityPercentages": {}
+ }
+ ],
"stopLoss": {
"enabled": false,
"maxLossPercentage": 0.8,
@@ -64,13 +81,17 @@
"symbols": ["BTCUSDT", "ETHUSDT", "ETHBTC", "XRPBTC"],
"buy": {
"enabled": true,
- "maxPurchaseAmount": -1,
- "maxPurchaseAmounts": {},
+ "gridTrade": [
+ {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": -1,
+ "maxPurchaseAmounts": {}
+ }
+ ],
"lastBuyPriceRemoveThreshold": -1,
"lastBuyPriceRemoveThresholds": {},
- "triggerPercentage": 1,
- "stopPercentage": 1.02,
- "limitPercentage": 1.021,
"athRestriction": {
"enabled": true,
"candles": { "interval": "1d", "limit": 30 },
@@ -81,7 +102,8 @@
"temporaryDisableActionAfterConfirmingOrder": 20,
"checkManualBuyOrderPeriod": 5,
"placeManualOrderInterval": 5,
- "refreshAccountInfoPeriod": 1
+ "refreshAccountInfoPeriod": 1,
+ "checkOrderExecutePeriod": 10
}
},
"accountInfo": {
@@ -125,9 +147,15 @@
"candles": { "interval": "15m", "limit": 100 },
"sell": {
"enabled": true,
- "triggerPercentage": 1.06,
- "stopPercentage": 0.98,
- "limitPercentage": 0.979,
+ "gridTrade": [
+ {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": -1,
+ "quantityPercentages": {}
+ }
+ ],
"stopLoss": {
"enabled": false,
"maxLossPercentage": 0.8,
@@ -139,13 +167,17 @@
"symbols": ["BTCUSDT", "ETHUSDT", "ETHBTC", "XRPBTC"],
"buy": {
"enabled": true,
- "maxPurchaseAmount": -1,
- "maxPurchaseAmounts": {},
+ "gridTrade": [
+ {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": -1,
+ "maxPurchaseAmounts": {}
+ }
+ ],
"lastBuyPriceRemoveThreshold": -1,
"lastBuyPriceRemoveThresholds": {},
- "triggerPercentage": 1,
- "stopPercentage": 1.02,
- "limitPercentage": 1.021,
"athRestriction": {
"enabled": true,
"candles": { "interval": "1d", "limit": 30 },
@@ -156,7 +188,8 @@
"temporaryDisableActionAfterConfirmingOrder": 20,
"checkManualBuyOrderPeriod": 5,
"placeManualOrderInterval": 5,
- "refreshAccountInfoPeriod": 1
+ "refreshAccountInfoPeriod": 1,
+ "checkOrderExecutePeriod": 10
}
},
"symbol": "BNBUSDT",
@@ -167,36 +200,61 @@
"candles": { "interval": "15m", "limit": 100 },
"sell": {
"enabled": true,
- "triggerPercentage": 1.06,
- "stopPercentage": 0.98,
- "limitPercentage": 0.979,
"stopLoss": {
"enabled": false,
"maxLossPercentage": 0.8,
"disableBuyMinutes": 360,
"orderType": "market"
+ },
+ "gridTrade": [
+ {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": 1,
+ "executed": false,
+ "executedOrder": null
+ }
+ ],
+ "currentGridTradeIndex": 0,
+ "currentGridTrade": {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": 1,
+ "executed": false,
+ "executedOrder": null
}
},
"cronTime": "* * * * * *",
"symbols": ["BTCUSDT", "ETHUSDT", "ETHBTC", "XRPBTC"],
"buy": {
"enabled": true,
- "maxPurchaseAmount": 100,
"lastBuyPriceRemoveThreshold": 10,
- "triggerPercentage": 1,
- "stopPercentage": 1.02,
- "limitPercentage": 1.021,
"athRestriction": {
"enabled": true,
"candles": { "interval": "1d", "limit": 30 },
"restrictionPercentage": 0.9
- }
+ },
+ "gridTrade": [
+ {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": 100,
+ "executed": false,
+ "executedOrder": null
+ }
+ ],
+ "currentGridTradeIndex": -1,
+ "currentGridTrade": null
},
"system": {
"temporaryDisableActionAfterConfirmingOrder": 20,
"checkManualBuyOrderPeriod": 5,
"placeManualOrderInterval": 5,
- "refreshAccountInfoPeriod": 1
+ "refreshAccountInfoPeriod": 1,
+ "checkOrderExecutePeriod": 10
}
},
"accountInfo": {
@@ -338,9 +396,15 @@
"candles": { "interval": "15m", "limit": 100 },
"sell": {
"enabled": true,
- "triggerPercentage": 1.06,
- "stopPercentage": 0.98,
- "limitPercentage": 0.979,
+ "gridTrade": [
+ {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": -1,
+ "quantityPercentages": {}
+ }
+ ],
"stopLoss": {
"enabled": false,
"maxLossPercentage": 0.8,
@@ -352,13 +416,17 @@
"symbols": ["BTCUSDT", "ETHUSDT", "ETHBTC", "XRPBTC"],
"buy": {
"enabled": true,
- "maxPurchaseAmount": -1,
- "maxPurchaseAmounts": {},
+ "gridTrade": [
+ {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": -1,
+ "maxPurchaseAmounts": {}
+ }
+ ],
"lastBuyPriceRemoveThreshold": -1,
"lastBuyPriceRemoveThresholds": {},
- "triggerPercentage": 1,
- "stopPercentage": 1.02,
- "limitPercentage": 1.021,
"athRestriction": {
"enabled": true,
"candles": { "interval": "1d", "limit": 30 },
@@ -369,7 +437,8 @@
"temporaryDisableActionAfterConfirmingOrder": 20,
"checkManualBuyOrderPeriod": 5,
"placeManualOrderInterval": 5,
- "refreshAccountInfoPeriod": 1
+ "refreshAccountInfoPeriod": 1,
+ "checkOrderExecutePeriod": 10
}
},
"symbol": "ETHUSDT",
@@ -380,36 +449,68 @@
"candles": { "interval": "15m", "limit": 100 },
"sell": {
"enabled": true,
- "triggerPercentage": 1.06,
- "stopPercentage": 0.98,
- "limitPercentage": 0.979,
"stopLoss": {
"enabled": false,
"maxLossPercentage": 0.8,
"disableBuyMinutes": 360,
"orderType": "market"
+ },
+ "gridTrade": [
+ {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": 1,
+ "executed": false,
+ "executedOrder": null
+ }
+ ],
+ "currentGridTradeIndex": 0,
+ "currentGridTrade": {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": 1,
+ "executed": false,
+ "executedOrder": null
}
},
"cronTime": "* * * * * *",
"symbols": ["BTCUSDT", "ETHUSDT", "ETHBTC", "XRPBTC"],
"buy": {
"enabled": true,
- "maxPurchaseAmount": 100,
"lastBuyPriceRemoveThreshold": 10,
- "triggerPercentage": 1,
- "stopPercentage": 1.02,
- "limitPercentage": 1.021,
"athRestriction": {
"enabled": true,
"candles": { "interval": "1d", "limit": 30 },
"restrictionPercentage": 0.9
+ },
+ "gridTrade": [
+ {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": 100,
+ "executed": false,
+ "executedOrder": null
+ }
+ ],
+ "currentGridTradeIndex": 0,
+ "currentGridTrade": {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": 100,
+ "executed": false,
+ "executedOrder": null
}
},
"system": {
"temporaryDisableActionAfterConfirmingOrder": 20,
"checkManualBuyOrderPeriod": 5,
"placeManualOrderInterval": 5,
- "refreshAccountInfoPeriod": 1
+ "refreshAccountInfoPeriod": 1,
+ "checkOrderExecutePeriod": 10
}
},
"accountInfo": {
diff --git a/app/frontend/websocket/handlers/__tests__/index.test.js b/app/frontend/websocket/handlers/__tests__/index.test.js
index 11c5a0f4..ca1f75ef 100644
--- a/app/frontend/websocket/handlers/__tests__/index.test.js
+++ b/app/frontend/websocket/handlers/__tests__/index.test.js
@@ -9,7 +9,9 @@ describe('index', () => {
handleSymbolDelete: expect.any(Function),
handleSymbolSettingUpdate: expect.any(Function),
handleSymbolSettingDelete: expect.any(Function),
+ handleSymbolGridTradeDelete: expect.any(Function),
handleSymbolEnableAction: expect.any(Function),
+ handleSymbolTriggerBuy: expect.any(Function),
handleManualTradeAllSymbols: expect.any(Function),
handleManualTrade: expect.any(Function),
handleCancelOrder: expect.any(Function),
diff --git a/app/frontend/websocket/handlers/__tests__/symbol-grid-trade-delete.test.js b/app/frontend/websocket/handlers/__tests__/symbol-grid-trade-delete.test.js
new file mode 100644
index 00000000..4d93dc82
--- /dev/null
+++ b/app/frontend/websocket/handlers/__tests__/symbol-grid-trade-delete.test.js
@@ -0,0 +1,61 @@
+/* eslint-disable global-require */
+
+describe('symbol-grid-trade-delete.test.js', () => {
+ let mockWebSocketServer;
+ let mockWebSocketServerWebSocketSend;
+
+ let mockLogger;
+
+ let mockDeleteSymbolGridTrade;
+
+ beforeEach(() => {
+ jest.clearAllMocks().resetModules();
+
+ mockWebSocketServerWebSocketSend = jest.fn().mockResolvedValue(true);
+
+ mockWebSocketServer = {
+ send: mockWebSocketServerWebSocketSend
+ };
+ });
+
+ describe('when symbol is provided', () => {
+ beforeEach(async () => {
+ const { logger } = require('../../../../helpers');
+ mockLogger = logger;
+
+ mockDeleteSymbolGridTrade = jest.fn().mockResolvedValue(true);
+
+ jest.mock(
+ '../../../../cronjob/trailingTradeHelper/configuration',
+ () => ({
+ deleteSymbolGridTrade: mockDeleteSymbolGridTrade
+ })
+ );
+
+ const {
+ handleSymbolGridTradeDelete
+ } = require('../symbol-grid-trade-delete');
+ await handleSymbolGridTradeDelete(logger, mockWebSocketServer, {
+ data: {
+ symbol: 'BTCUSDT'
+ }
+ });
+ });
+
+ it('triggers deleteSymbolGridTrade', () => {
+ expect(mockDeleteSymbolGridTrade).toHaveBeenCalledWith(
+ mockLogger,
+ 'BTCUSDT'
+ );
+ });
+
+ it('triggers ws.send', () => {
+ expect(mockWebSocketServerWebSocketSend).toHaveBeenCalledWith(
+ JSON.stringify({
+ result: true,
+ type: 'symbol-grid-trade-delete-result'
+ })
+ );
+ });
+ });
+});
diff --git a/app/frontend/websocket/handlers/__tests__/symbol-setting-trigger-buy.test.js b/app/frontend/websocket/handlers/__tests__/symbol-setting-trigger-buy.test.js
new file mode 100644
index 00000000..1e7be2c2
--- /dev/null
+++ b/app/frontend/websocket/handlers/__tests__/symbol-setting-trigger-buy.test.js
@@ -0,0 +1,59 @@
+/* eslint-disable global-require */
+
+describe('symbol-trigger-buy.test.js', () => {
+ let mockWebSocketServer;
+ let mockWebSocketServerWebSocketSend;
+
+ let mockCache;
+ let mockLogger;
+
+ beforeEach(() => {
+ jest.clearAllMocks().resetModules();
+
+ mockWebSocketServerWebSocketSend = jest.fn().mockResolvedValue(true);
+
+ mockWebSocketServer = {
+ send: mockWebSocketServerWebSocketSend
+ };
+ });
+
+ describe('when symbol is provided', () => {
+ beforeEach(async () => {
+ const { cache, logger } = require('../../../../helpers');
+ mockCache = cache;
+ mockLogger = logger;
+
+ mockCache.hset = jest.fn().mockResolvedValue(true);
+
+ const { handleSymbolTriggerBuy } = require('../symbol-trigger-buy');
+ await handleSymbolTriggerBuy(mockLogger, mockWebSocketServer, {
+ data: {
+ symbol: 'BTCUSDT'
+ }
+ });
+ });
+
+ it('triggers cache.hset', () => {
+ expect(mockCache.hset.mock.calls[0][0]).toStrictEqual(
+ 'trailing-trade-override'
+ );
+
+ expect(mockCache.hset.mock.calls[0][1]).toStrictEqual('BTCUSDT');
+
+ const args = JSON.parse(mockCache.hset.mock.calls[0][2]);
+ expect(args).toStrictEqual({
+ action: 'buy',
+ actionAt: expect.any(String)
+ });
+ });
+
+ it('triggers ws.send', () => {
+ expect(mockWebSocketServerWebSocketSend).toHaveBeenCalledWith(
+ JSON.stringify({
+ result: true,
+ type: 'symbol-trigger-buy-result'
+ })
+ );
+ });
+ });
+});
diff --git a/app/frontend/websocket/handlers/index.js b/app/frontend/websocket/handlers/index.js
index 863efdc2..e2584198 100644
--- a/app/frontend/websocket/handlers/index.js
+++ b/app/frontend/websocket/handlers/index.js
@@ -6,7 +6,9 @@ const {
const { handleSymbolDelete } = require('./symbol-delete');
const { handleSymbolSettingUpdate } = require('./symbol-setting-update');
const { handleSymbolSettingDelete } = require('./symbol-setting-delete');
+const { handleSymbolGridTradeDelete } = require('./symbol-grid-trade-delete');
const { handleSymbolEnableAction } = require('./symbol-enable-action');
+const { handleSymbolTriggerBuy } = require('./symbol-trigger-buy');
const { handleManualTrade } = require('./manual-trade');
const { handleManualTradeAllSymbols } = require('./manual-trade-all-symbols');
const { handleCancelOrder } = require('./cancel-order');
@@ -20,7 +22,9 @@ module.exports = {
handleSymbolDelete,
handleSymbolSettingUpdate,
handleSymbolSettingDelete,
+ handleSymbolGridTradeDelete,
handleSymbolEnableAction,
+ handleSymbolTriggerBuy,
handleManualTrade,
handleManualTradeAllSymbols,
handleCancelOrder,
diff --git a/app/frontend/websocket/handlers/symbol-grid-trade-delete.js b/app/frontend/websocket/handlers/symbol-grid-trade-delete.js
new file mode 100644
index 00000000..fdcc245d
--- /dev/null
+++ b/app/frontend/websocket/handlers/symbol-grid-trade-delete.js
@@ -0,0 +1,19 @@
+const {
+ deleteSymbolGridTrade
+} = require('../../../cronjob/trailingTradeHelper/configuration');
+
+const handleSymbolGridTradeDelete = async (logger, ws, payload) => {
+ logger.info({ payload }, 'Start grid trade delete');
+
+ const { data: symbolInfo } = payload;
+
+ const { symbol } = symbolInfo;
+
+ await deleteSymbolGridTrade(logger, symbol);
+
+ ws.send(
+ JSON.stringify({ result: true, type: 'symbol-grid-trade-delete-result' })
+ );
+};
+
+module.exports = { handleSymbolGridTradeDelete };
diff --git a/app/frontend/websocket/handlers/symbol-trigger-buy.js b/app/frontend/websocket/handlers/symbol-trigger-buy.js
new file mode 100644
index 00000000..c19b896f
--- /dev/null
+++ b/app/frontend/websocket/handlers/symbol-trigger-buy.js
@@ -0,0 +1,28 @@
+const moment = require('moment');
+const { cache, PubSub } = require('../../../helpers');
+
+const handleSymbolTriggerBuy = async (logger, ws, payload) => {
+ logger.info({ payload }, 'Start symbol trigger buy');
+
+ const { data: symbolInfo } = payload;
+
+ const { symbol } = symbolInfo;
+
+ await cache.hset(
+ 'trailing-trade-override',
+ `${symbol}`,
+ JSON.stringify({
+ action: 'buy',
+ actionAt: moment()
+ })
+ );
+
+ PubSub.publish('frontend-notification', {
+ type: 'info',
+ title: 'The order received by the bot. Wait for placing the order.'
+ });
+
+ ws.send(JSON.stringify({ result: true, type: 'symbol-trigger-buy-result' }));
+};
+
+module.exports = { handleSymbolTriggerBuy };
diff --git a/app/helpers/__tests__/mongo.test.js b/app/helpers/__tests__/mongo.test.js
index 8e7c7e51..e47655c2 100644
--- a/app/helpers/__tests__/mongo.test.js
+++ b/app/helpers/__tests__/mongo.test.js
@@ -10,6 +10,7 @@ describe('mongo.js', () => {
let result;
let mockCollection;
+ let mockFind;
let mockFindOne;
let mockInsertOne;
let mockUpdateOne;
@@ -93,6 +94,62 @@ describe('mongo.js', () => {
});
});
+ describe('findAll', () => {
+ beforeEach(async () => {
+ mockFind = jest.fn().mockResolvedValue({
+ toArray: jest.fn().mockResolvedValue([
+ { key: 'my-key1', some: 'value' },
+ { key: 'my-key2', some: 'value' }
+ ])
+ });
+ mockCollection = jest.fn(() => ({
+ find: mockFind
+ }));
+
+ mockDBCommand = jest.fn().mockResolvedValue(true);
+ mockDB = jest.fn(() => ({
+ command: mockDBCommand,
+ collection: mockCollection
+ }));
+
+ mockMongoClient = jest.fn(() => ({
+ connect: jest.fn().mockResolvedValue(true),
+ db: mockDB
+ }));
+
+ jest.mock('mongodb', () => ({
+ MongoClient: mockMongoClient
+ }));
+
+ require('mongodb');
+
+ mongo = require('../mongo');
+
+ await mongo.connect(logger);
+
+ result = await mongo.findAll(logger, 'trailing-trade-grid-trade', {
+ key: 'BTCUSDT'
+ });
+ });
+
+ it('triggers database.collection', () => {
+ expect(mockCollection).toHaveBeenCalledWith('trailing-trade-grid-trade');
+ });
+
+ it('triggers collection.find', () => {
+ expect(mockFind).toHaveBeenCalledWith({
+ key: 'BTCUSDT'
+ });
+ });
+
+ it('returns expected result', () => {
+ expect(result).toStrictEqual([
+ { key: 'my-key1', some: 'value' },
+ { key: 'my-key2', some: 'value' }
+ ]);
+ });
+ });
+
describe('findOne', () => {
beforeEach(async () => {
mockFindOne = jest
diff --git a/app/helpers/mongo.js b/app/helpers/mongo.js
index 8fa91bf4..17a07a5e 100644
--- a/app/helpers/mongo.js
+++ b/app/helpers/mongo.js
@@ -28,6 +28,18 @@ const connect = async funcLogger => {
}
};
+const findAll = async (funcLogger, collectionName, query) => {
+ const logger = funcLogger.child({ helper: 'mongo', funcName: 'findAll' });
+
+ const collection = database.collection(collectionName);
+
+ logger.info({ collectionName, query }, 'Finding document from MongoDB');
+ const result = await collection.find(query);
+ logger.info({ result }, 'Found documents from MongoDB');
+
+ return result.toArray();
+};
+
const findOne = async (funcLogger, collectionName, query) => {
const logger = funcLogger.child({ helper: 'mongo', funcName: 'findOne' });
@@ -94,7 +106,9 @@ const deleteOne = async (funcLogger, collectionName, filter) => {
};
module.exports = {
+ client,
connect,
+ findAll,
findOne,
insertOne,
upsertOne,
diff --git a/config/custom-environment-variables.json b/config/custom-environment-variables.json
index bf4de5c6..26715a12 100644
--- a/config/custom-environment-variables.json
+++ b/config/custom-environment-variables.json
@@ -53,6 +53,11 @@
"__name": "BINANCE_FEATURE_TOGGLE_NOTIFY_DEBUG",
"__description": "Set a boolean to notify the debug message. Note that enabling this feature toggle can flood the messages.",
"__format": "boolean"
+ },
+ "notifyOrderExecute": {
+ "__name": "BINANCE_FEATURE_TOGGLE_NOTIFY_ORDER_EXECUTE",
+ "__description": "Set a boolean to notify the order executed messages. Note that enabling this feature toggle can flood the messages.",
+ "__format": "boolean"
}
},
"jobs": {
@@ -170,6 +175,11 @@
"__name": "BINANCE_JOBS_TRAILING_TRADE_SYSTEM_REFRESH_ACCOUNT_INFO_PERIOD",
"__description": "Set the seconds for the period of checking the account info.",
"__format": "number"
+ },
+ "checkOrderExecutePeriod": {
+ "__name": "BINANCE_JOBS_TRAILING_TRADE_SYSTEM_CHECK_ORDER_EXECUTE_PERIOD",
+ "__description": "Set the seconds for the period of checking the grid trade order executed. Note that reducing the seconds can cause issues with the bot exceeding the API usage.",
+ "__format": "number"
}
}
},
diff --git a/config/default.json b/config/default.json
index 41b86567..ea8ad96d 100644
--- a/config/default.json
+++ b/config/default.json
@@ -33,7 +33,8 @@
},
"featureToggle": {
"notifyOrderConfirm": true,
- "notifyDebug": false
+ "notifyDebug": false,
+ "notifyOrderExecute": true
},
"jobs": {
"alive": {
@@ -50,13 +51,17 @@
},
"buy": {
"enabled": true,
- "maxPurchaseAmount": -1,
- "maxPurchaseAmounts": {},
+ "gridTrade": [
+ {
+ "triggerPercentage": 1,
+ "stopPercentage": 1.02,
+ "limitPercentage": 1.021,
+ "maxPurchaseAmount": -1,
+ "maxPurchaseAmounts": {}
+ }
+ ],
"lastBuyPriceRemoveThreshold": -1,
"lastBuyPriceRemoveThresholds": {},
- "triggerPercentage": 1.0,
- "stopPercentage": 1.02,
- "limitPercentage": 1.021,
"athRestriction": {
"enabled": true,
"candles": {
@@ -68,9 +73,15 @@
},
"sell": {
"enabled": true,
- "triggerPercentage": 1.06,
- "stopPercentage": 0.98,
- "limitPercentage": 0.979,
+ "gridTrade": [
+ {
+ "triggerPercentage": 1.06,
+ "stopPercentage": 0.98,
+ "limitPercentage": 0.979,
+ "quantityPercentage": -1,
+ "quantityPercentages": {}
+ }
+ ],
"stopLoss": {
"enabled": false,
"maxLossPercentage": 0.8,
@@ -82,7 +93,8 @@
"temporaryDisableActionAfterConfirmingOrder": 20,
"checkManualBuyOrderPeriod": 5,
"placeManualOrderInterval": 5,
- "refreshAccountInfoPeriod": 1
+ "refreshAccountInfoPeriod": 1,
+ "checkOrderExecutePeriod": 10
}
},
"trailingTradeIndicator": {
diff --git a/docker-compose.yml b/docker-compose.yml
index 66476fa2..ebebf696 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -13,6 +13,7 @@ services:
- ./config:/srv/config
- ./app:/srv/app
- ./public:/srv/public
+ - ./migrations:/srv/migrations
env_file:
- .env
restart: unless-stopped
diff --git a/image-files/usr/local/bin/docker-entrypoint.sh b/image-files/usr/local/bin/docker-entrypoint.sh
new file mode 100755
index 00000000..0a48c1fa
--- /dev/null
+++ b/image-files/usr/local/bin/docker-entrypoint.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+echo "__________.__ __________ __"
+echo "\______ \__| ____ _____ ____ ____ ____ \______ \ _____/ |_"
+echo " | | _/ |/ \\__ \ / \_/ ___\/ __ \ | | _// _ \ __"
+echo " | | \ | | \/ __ \| | \ \__\ ___/ | | ( <_> ) |"
+echo " |______ /__|___| (____ /___| /\___ >___ > |______ /\____/|__|"
+echo " \/ \/ \/ \/ \/ \/ \/"
+
+set -e
+
+# Execute migration
+npm run migrate:up
+
+exec "$@"
diff --git a/migrations/1626509477518-migrate-grid-trade.js b/migrations/1626509477518-migrate-grid-trade.js
new file mode 100644
index 00000000..4c272162
--- /dev/null
+++ b/migrations/1626509477518-migrate-grid-trade.js
@@ -0,0 +1,181 @@
+const path = require('path');
+const { logger: rootLogger, mongo } = require('../app/helpers');
+
+const migrateGlobalConfiguration = (logger, oldConfiguration) => {
+ const newConfiguration = oldConfiguration;
+ if (!newConfiguration) {
+ return newConfiguration;
+ }
+
+ if (newConfiguration.buy.gridTrade === undefined) {
+ const {
+ buy: {
+ triggerPercentage,
+ stopPercentage,
+ limitPercentage,
+ maxPurchaseAmounts
+ }
+ } = oldConfiguration;
+
+ newConfiguration.buy.gridTrade = [
+ {
+ triggerPercentage,
+ stopPercentage,
+ limitPercentage,
+ maxPurchaseAmount: -1,
+ maxPurchaseAmounts
+ }
+ ];
+
+ delete newConfiguration.buy.triggerPercentage;
+ delete newConfiguration.buy.stopPercentage;
+ delete newConfiguration.buy.limitPercentage;
+ delete newConfiguration.buy.maxPurchaseAmount;
+ delete newConfiguration.buy.maxPurchaseAmounts;
+ }
+
+ if (newConfiguration.sell.gridTrade === undefined) {
+ const {
+ sell: { triggerPercentage, stopPercentage, limitPercentage }
+ } = oldConfiguration;
+
+ newConfiguration.sell.gridTrade = [
+ {
+ triggerPercentage,
+ stopPercentage,
+ limitPercentage,
+ quantityPercentage: -1,
+ quantityPercentages: {}
+ }
+ ];
+
+ delete newConfiguration.sell.triggerPercentage;
+ delete newConfiguration.sell.stopPercentage;
+ delete newConfiguration.sell.limitPercentage;
+ }
+
+ logger.info({ newConfiguration }, 'New migrated configuration');
+
+ return newConfiguration;
+};
+
+const migrateSymbolConfiguration = (logger, oldConfiguration) => {
+ const newConfiguration = oldConfiguration;
+
+ if (newConfiguration.buy.gridTrade === undefined) {
+ const {
+ buy: {
+ triggerPercentage,
+ stopPercentage,
+ limitPercentage,
+ maxPurchaseAmount
+ }
+ } = oldConfiguration;
+
+ newConfiguration.buy.gridTrade = [
+ {
+ triggerPercentage,
+ stopPercentage,
+ limitPercentage,
+ maxPurchaseAmount
+ }
+ ];
+
+ delete newConfiguration.buy.triggerPercentage;
+ delete newConfiguration.buy.stopPercentage;
+ delete newConfiguration.buy.limitPercentage;
+ delete newConfiguration.buy.maxPurchaseAmount;
+ }
+
+ if (newConfiguration.sell.gridTrade === undefined) {
+ const {
+ sell: { triggerPercentage, stopPercentage, limitPercentage }
+ } = oldConfiguration;
+
+ newConfiguration.sell.gridTrade = [
+ {
+ triggerPercentage,
+ stopPercentage,
+ limitPercentage,
+ quantityPercentage: 1
+ }
+ ];
+
+ delete newConfiguration.sell.triggerPercentage;
+ delete newConfiguration.sell.stopPercentage;
+ delete newConfiguration.sell.limitPercentage;
+ }
+
+ logger.info({ newConfiguration }, 'New migrated configuration');
+
+ return newConfiguration;
+};
+
+module.exports.up = async next => {
+ const logger = rootLogger.child({
+ gitHash: process.env.GIT_HASH || 'unspecified',
+ migration: path.basename(__filename)
+ });
+
+ await mongo.connect(logger);
+
+ logger.info('Start migration');
+
+ // Get symbol configuration
+ const symbolConfigurations = await mongo.findAll(
+ logger,
+ 'trailing-trade-symbols',
+ {
+ key: { $regex: /^(.+)-configuration/ }
+ }
+ );
+
+ // Migrate symbol configuration
+ const newSymbolConfigurations = symbolConfigurations.map(configuration =>
+ migrateSymbolConfiguration(logger, configuration)
+ );
+
+ // Update symbol configuration
+ await Promise.all(
+ newSymbolConfigurations.map(configuration => {
+ const { key } = configuration;
+ return mongo.upsertOne(
+ logger,
+ 'trailing-trade-symbols',
+ { key },
+ { key, ...configuration }
+ );
+ })
+ );
+
+ // Get global configuration
+ const globalConfiguration = await mongo.findOne(
+ logger,
+ 'trailing-trade-common',
+ {
+ key: 'configuration'
+ }
+ );
+
+ // Migrate global configuration
+ const newGlobalConfiguration = migrateGlobalConfiguration(
+ logger,
+ globalConfiguration
+ );
+
+ // Update global configuration
+ await mongo.upsertOne(
+ logger,
+ 'trailing-trade-common',
+ { key: 'configuration' },
+ { key: 'configuration', ...newGlobalConfiguration }
+ );
+
+ logger.info('Finish migration');
+
+ next();
+};
+
+module.exports.down = next => {
+ next();
+};
diff --git a/mongo-state-storage.js b/mongo-state-storage.js
new file mode 100644
index 00000000..d25b65c9
--- /dev/null
+++ b/mongo-state-storage.js
@@ -0,0 +1,66 @@
+/* eslint-disable no-useless-catch */
+/* eslint-disable no-console */
+/* eslint-disable class-methods-use-this */
+const config = require('config');
+const { MongoClient } = require('mongodb');
+
+const clusterUrl = `${config.get('mongo.host')}:${config.get('mongo.port')}`;
+const url = `mongodb://${clusterUrl}/`;
+
+class MongoDbStore {
+ async load(fn) {
+ let client = null;
+ let data = null;
+ try {
+ client = await MongoClient.connect(url, {
+ useNewUrlParser: true,
+ useUnifiedTopology: true
+ });
+ const db = client.db(config.get('mongo.database'));
+ data = await db.collection('trailing-trade-migrations').find().toArray();
+ if (data.length !== 1) {
+ console.log(
+ 'Cannot read migrations from database. If this is the first time you run migrations, then this is normal.'
+ );
+ return fn(null, {});
+ }
+ } catch (err) {
+ throw err;
+ } finally {
+ client.close();
+ }
+ return fn(null, data[0]);
+ }
+
+ async save(set, fn) {
+ let client = null;
+ let result = null;
+ try {
+ client = await MongoClient.connect(url, {
+ useNewUrlParser: true,
+ useUnifiedTopology: true
+ });
+ const db = client.db(config.get('mongo.database'));
+ result = await db.collection('trailing-trade-migrations').updateMany(
+ {},
+ {
+ $set: {
+ lastRun: set.lastRun
+ },
+ $push: {
+ migrations: { $each: set.migrations }
+ }
+ },
+ { upsert: true }
+ );
+ } catch (err) {
+ throw err;
+ } finally {
+ client.close();
+ }
+
+ return fn(null, result);
+ }
+}
+
+module.exports = MongoDbStore;
diff --git a/package-lock.json b/package-lock.json
index 3951434a..516a99ce 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,16 +1,21856 @@
{
"name": "binance-trading-bot",
"version": "0.0.72",
- "lockfileVersion": 1,
+ "lockfileVersion": 2,
"requires": true,
+ "packages": {
+ "": {
+ "version": "0.0.72",
+ "license": "MIT",
+ "dependencies": {
+ "axios": "^0.21.1",
+ "binance-api-node": "^0.11.5",
+ "bunyan": "^1.8.15",
+ "clean-webpack-plugin": "^3.0.0",
+ "config": "^3.3.6",
+ "cron": "^1.8.2",
+ "cross-env": "^7.0.3",
+ "express": "^4.17.1",
+ "ioredis": "^4.27.6",
+ "localtunnel": "^2.0.1",
+ "lodash": "^4.17.21",
+ "lodash-webpack-plugin": "^0.11.6",
+ "migrate": "^1.7.0",
+ "moment": "^2.29.1",
+ "moment-timezone": "^0.5.33",
+ "mongodb": "3.6.10",
+ "pubsub-js": "^1.9.3",
+ "redlock": "^4.2.0",
+ "uuid": "^8.3.2",
+ "ws": "^7.5.3"
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.14.5",
+ "@babel/preset-env": "^7.14.7",
+ "@types/express": "^4.17.13",
+ "@types/jest": "^26.0.24",
+ "@types/node": "^16.3.1",
+ "babel-core": "^6.26.3",
+ "babel-eslint": "^10.1.0",
+ "babel-loader": "^8.2.2",
+ "babel-plugin-lodash": "^3.3.4",
+ "babel-preset-env": "^1.7.0",
+ "eslint": "^7.30.0",
+ "eslint-config-airbnb": "^18.2.1",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-config-react-app": "^6.0.0",
+ "eslint-plugin-flowtype": "^5.8.0",
+ "eslint-plugin-import": "^2.23.4",
+ "eslint-plugin-jest": "^24.3.6",
+ "eslint-plugin-jsx-a11y": "^6.4.1",
+ "eslint-plugin-node": "^11.1.0",
+ "eslint-plugin-prettier": "^3.4.0",
+ "eslint-plugin-promise": "^5.1.0",
+ "eslint-plugin-react": "^7.24.0",
+ "eslint-plugin-react-hooks": "^4.2.0",
+ "husky": "^7.0.1",
+ "jest": "^27.0.6",
+ "lint-staged": "^11.0.0",
+ "nodemon": "^2.0.11",
+ "prettier": "^2.3.2",
+ "webpack": "^5.44.0",
+ "webpack-cli": "^4.7.2"
+ }
+ },
+ "node_modules/@babel/cli": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.5.tgz",
+ "integrity": "sha512-poegjhRvXHWO0EAsnYajwYZuqcz7gyfxwfaecUESxDujrqOivf3zrjFbub8IJkrqEaz3fvJWh001EzxBub54fg==",
+ "dev": true,
+ "dependencies": {
+ "commander": "^4.0.1",
+ "convert-source-map": "^1.1.0",
+ "fs-readdir-recursive": "^1.1.0",
+ "glob": "^7.0.0",
+ "make-dir": "^2.1.0",
+ "slash": "^2.0.0",
+ "source-map": "^0.5.0"
+ },
+ "bin": {
+ "babel": "bin/babel.js",
+ "babel-external-helpers": "bin/babel-external-helpers.js"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "optionalDependencies": {
+ "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.2",
+ "chokidar": "^3.4.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/cli/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
+ "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz",
+ "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz",
+ "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helpers": "^7.14.6",
+ "@babel/parser": "^7.14.6",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.1.2",
+ "semver": "^6.3.0",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/traverse": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/core/node_modules/json5": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@babel/core/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/@babel/core/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/core/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.1.tgz",
+ "integrity": "sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.1",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/@babel/types": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz",
+ "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz",
+ "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz",
+ "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-explode-assignable-expression": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-builder-binary-assignment-operator-visitor/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz",
+ "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.14.5",
+ "@babel/helper-validator-option": "^7.14.5",
+ "browserslist": "^4.16.6",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/browserslist": {
+ "version": "4.16.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
+ "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "dev": true,
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001219",
+ "colorette": "^1.2.2",
+ "electron-to-chromium": "^1.3.723",
+ "escalade": "^3.1.1",
+ "node-releases": "^1.1.71"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/caniuse-lite": {
+ "version": "1.0.30001243",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
+ "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/electron-to-chromium": {
+ "version": "1.3.772",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
+ "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz",
+ "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-member-expression-to-functions": "^7.14.5",
+ "@babel/helper-optimise-call-expression": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz",
+ "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "regexpu-core": "^4.7.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regexpu-core": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz",
+ "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.4.0",
+ "regenerate-unicode-properties": "^8.2.0",
+ "regjsgen": "^0.5.1",
+ "regjsparser": "^0.6.4",
+ "unicode-match-property-ecmascript": "^1.0.4",
+ "unicode-match-property-value-ecmascript": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regjsgen": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+ "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/regjsparser": {
+ "version": "0.6.9",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz",
+ "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==",
+ "dev": true,
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz",
+ "integrity": "sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.13.0",
+ "@babel/helper-module-imports": "^7.12.13",
+ "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/traverse": "^7.13.0",
+ "debug": "^4.1.1",
+ "lodash.debounce": "^4.0.8",
+ "resolve": "^1.14.2",
+ "semver": "^6.1.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.4.0-0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/helper-module-imports": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz",
+ "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/traverse": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/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/@babel/helper-define-polyfill-provider/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/helper-define-polyfill-provider/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/helper-explode-assignable-expression": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz",
+ "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-explode-assignable-expression/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-explode-assignable-expression/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz",
+ "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-function-name/node_modules/@babel/types": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz",
+ "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@babel/helper-get-function-arity": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz",
+ "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/helper-get-function-arity/node_modules/@babel/types": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz",
+ "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz",
+ "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz",
+ "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz",
+ "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.7.4"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz",
+ "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-simple-access": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-module-imports": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz",
+ "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/traverse": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/helper-module-transforms/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/@babel/helper-module-transforms/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz",
+ "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz",
+ "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz",
+ "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-wrap-function": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz",
+ "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.14.5",
+ "@babel/helper-optimise-call-expression": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/traverse": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/helper-replace-supers/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/@babel/helper-replace-supers/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz",
+ "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz",
+ "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz",
+ "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.11.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration/node_modules/@babel/types": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz",
+ "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz",
+ "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz",
+ "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/traverse": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/helper-wrap-function/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/@babel/helper-wrap-function/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz",
+ "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/traverse": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/helpers/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/@babel/helpers/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.12.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.3.tgz",
+ "integrity": "sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz",
+ "integrity": "sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5",
+ "@babel/plugin-proposal-optional-chaining": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.13.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz",
+ "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-remap-async-to-generator": "^7.14.5",
+ "@babel/plugin-syntax-async-generators": "^7.8.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-class-properties": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz",
+ "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.12.0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-dynamic-import": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz",
+ "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-export-namespace-from": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz",
+ "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-json-strings": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz",
+ "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-json-strings": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-logical-assignment-operators": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz",
+ "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz",
+ "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-numeric-separator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz",
+ "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz",
+ "integrity": "sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.14.7",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-transform-parameters": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-optional-catch-binding": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz",
+ "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-optional-chaining": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz",
+ "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-methods": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz",
+ "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-proposal-unicode-property-regex": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz",
+ "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz",
+ "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-arrow-functions": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz",
+ "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz",
+ "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-remap-async-to-generator": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-module-imports": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz",
+ "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-async-to-generator/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz",
+ "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-block-scoping": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz",
+ "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz",
+ "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-optimise-call-expression": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-classes/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-computed-properties": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz",
+ "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-destructuring": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz",
+ "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-dotall-regex": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz",
+ "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-duplicate-keys": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz",
+ "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz",
+ "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-for-of": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz",
+ "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz",
+ "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/helper-function-name": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/helper-get-function-arity": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/parser": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/template": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-function-name/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-literals": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz",
+ "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-member-expression-literals": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz",
+ "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-amd": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz",
+ "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-commonjs": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz",
+ "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-simple-access": "^7.14.5",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz",
+ "integrity": "sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-systemjs/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-modules-umd": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz",
+ "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz",
+ "integrity": "sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-new-target": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz",
+ "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-object-super": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz",
+ "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-parameters": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz",
+ "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-property-literals": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz",
+ "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz",
+ "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==",
+ "dev": true,
+ "dependencies": {
+ "regenerator-transform": "^0.14.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-regenerator/node_modules/regenerator-transform": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
+ "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "node_modules/@babel/plugin-transform-reserved-words": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz",
+ "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-shorthand-properties": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz",
+ "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-spread": {
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz",
+ "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-sticky-regex": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz",
+ "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-template-literals": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz",
+ "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typeof-symbol": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz",
+ "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-escapes": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz",
+ "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-unicode-regex": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz",
+ "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-env": {
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz",
+ "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.14.7",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-validator-option": "^7.14.5",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5",
+ "@babel/plugin-proposal-async-generator-functions": "^7.14.7",
+ "@babel/plugin-proposal-class-properties": "^7.14.5",
+ "@babel/plugin-proposal-class-static-block": "^7.14.5",
+ "@babel/plugin-proposal-dynamic-import": "^7.14.5",
+ "@babel/plugin-proposal-export-namespace-from": "^7.14.5",
+ "@babel/plugin-proposal-json-strings": "^7.14.5",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
+ "@babel/plugin-proposal-numeric-separator": "^7.14.5",
+ "@babel/plugin-proposal-object-rest-spread": "^7.14.7",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.14.5",
+ "@babel/plugin-proposal-optional-chaining": "^7.14.5",
+ "@babel/plugin-proposal-private-methods": "^7.14.5",
+ "@babel/plugin-proposal-private-property-in-object": "^7.14.5",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.14.5",
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-transform-arrow-functions": "^7.14.5",
+ "@babel/plugin-transform-async-to-generator": "^7.14.5",
+ "@babel/plugin-transform-block-scoped-functions": "^7.14.5",
+ "@babel/plugin-transform-block-scoping": "^7.14.5",
+ "@babel/plugin-transform-classes": "^7.14.5",
+ "@babel/plugin-transform-computed-properties": "^7.14.5",
+ "@babel/plugin-transform-destructuring": "^7.14.7",
+ "@babel/plugin-transform-dotall-regex": "^7.14.5",
+ "@babel/plugin-transform-duplicate-keys": "^7.14.5",
+ "@babel/plugin-transform-exponentiation-operator": "^7.14.5",
+ "@babel/plugin-transform-for-of": "^7.14.5",
+ "@babel/plugin-transform-function-name": "^7.14.5",
+ "@babel/plugin-transform-literals": "^7.14.5",
+ "@babel/plugin-transform-member-expression-literals": "^7.14.5",
+ "@babel/plugin-transform-modules-amd": "^7.14.5",
+ "@babel/plugin-transform-modules-commonjs": "^7.14.5",
+ "@babel/plugin-transform-modules-systemjs": "^7.14.5",
+ "@babel/plugin-transform-modules-umd": "^7.14.5",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7",
+ "@babel/plugin-transform-new-target": "^7.14.5",
+ "@babel/plugin-transform-object-super": "^7.14.5",
+ "@babel/plugin-transform-parameters": "^7.14.5",
+ "@babel/plugin-transform-property-literals": "^7.14.5",
+ "@babel/plugin-transform-regenerator": "^7.14.5",
+ "@babel/plugin-transform-reserved-words": "^7.14.5",
+ "@babel/plugin-transform-shorthand-properties": "^7.14.5",
+ "@babel/plugin-transform-spread": "^7.14.6",
+ "@babel/plugin-transform-sticky-regex": "^7.14.5",
+ "@babel/plugin-transform-template-literals": "^7.14.5",
+ "@babel/plugin-transform-typeof-symbol": "^7.14.5",
+ "@babel/plugin-transform-unicode-escapes": "^7.14.5",
+ "@babel/plugin-transform-unicode-regex": "^7.14.5",
+ "@babel/preset-modules": "^0.1.4",
+ "@babel/types": "^7.14.5",
+ "babel-plugin-polyfill-corejs2": "^0.2.2",
+ "babel-plugin-polyfill-corejs3": "^0.2.2",
+ "babel-plugin-polyfill-regenerator": "^0.2.2",
+ "core-js-compat": "^3.15.0",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/preset-env/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/preset-env/node_modules/@babel/types": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/preset-env/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/@babel/preset-modules": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz",
+ "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.1.tgz",
+ "integrity": "sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==",
+ "dev": true,
+ "dependencies": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "node_modules/@babel/runtime-corejs3": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.12.1.tgz",
+ "integrity": "sha512-umhPIcMrlBZ2aTWlWjUseW9LjQKxi1dpFlQS8DzsxB//5K+u6GLTC/JliPKHsd5kJVPIU6X/Hy0YvWOYPcMxBw==",
+ "dev": true,
+ "dependencies": {
+ "core-js-pure": "^3.0.0",
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz",
+ "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "node_modules/@babel/template/node_modules/@babel/types": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz",
+ "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.1.tgz",
+ "integrity": "sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.12.1",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-split-export-declaration": "^7.11.0",
+ "@babel/parser": "^7.12.1",
+ "@babel/types": "^7.12.1",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.19"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/types": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.1.tgz",
+ "integrity": "sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/debug": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
+ "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
+ "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/traverse/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/@babel/types": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
+ "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+ "dev": true,
+ "dependencies": {
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.13",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz",
+ "integrity": "sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz",
+ "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.1.1",
+ "espree": "^7.3.0",
+ "globals": "^13.9.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "13.10.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
+ "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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/@humanwhocodes/config-array": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
+ "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+ "dev": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.0",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "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/object-schema": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
+ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+ "dev": true
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/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/@istanbuljs/load-nyc-config/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/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.6.tgz",
+ "integrity": "sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/console/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/console/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/console/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/@jest/console/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/console/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/@jest/console/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/@jest/console/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console/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/@jest/console/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/@jest/core": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.6.tgz",
+ "integrity": "sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^27.0.6",
+ "@jest/reporters": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.8.1",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-changed-files": "^27.0.6",
+ "jest-config": "^27.0.6",
+ "jest-haste-map": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-resolve-dependencies": "^27.0.6",
+ "jest-runner": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
+ "jest-watcher": "^27.0.6",
+ "micromatch": "^4.0.4",
+ "p-each-series": "^2.1.0",
+ "rimraf": "^3.0.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/core/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/core/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/core/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/@jest/core/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/@jest/core/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/core/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/@jest/core/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/@jest/core/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/@jest/core/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/core/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/@jest/core/node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/@jest/core/node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@jest/core/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/@jest/core/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/@jest/core/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/@jest/core/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/@jest/environment": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.6.tgz",
+ "integrity": "sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "jest-mock": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/environment/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/environment/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/environment/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/@jest/environment/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/environment/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/@jest/environment/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/@jest/environment/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/environment/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/@jest/fake-timers": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.6.tgz",
+ "integrity": "sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "@sinonjs/fake-timers": "^7.0.2",
+ "@types/node": "*",
+ "jest-message-util": "^27.0.6",
+ "jest-mock": "^27.0.6",
+ "jest-util": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/fake-timers/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/@jest/fake-timers/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/fake-timers/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/@jest/fake-timers/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/@jest/fake-timers/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/fake-timers/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/@jest/globals": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.6.tgz",
+ "integrity": "sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "expect": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/globals/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/globals/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/globals/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/@jest/globals/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/globals/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/@jest/globals/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/@jest/globals/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/globals/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/@jest/reporters": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.6.tgz",
+ "integrity": "sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA==",
+ "dev": true,
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.2",
+ "graceful-fs": "^4.2.4",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^4.0.3",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.0.2",
+ "jest-haste-map": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-worker": "^27.0.6",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.0",
+ "string-length": "^4.0.1",
+ "terminal-link": "^2.0.0",
+ "v8-to-istanbul": "^8.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/reporters/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/reporters/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/reporters/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/@jest/reporters/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/reporters/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/@jest/reporters/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/@jest/reporters/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/reporters/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/@jest/reporters/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/@jest/source-map": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz",
+ "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "source-map": "^0.6.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.6.tgz",
+ "integrity": "sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/test-result/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/test-result/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/test-result/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/@jest/test-result/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/test-result/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/@jest/test-result/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/@jest/test-result/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/test-result/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/@jest/test-sequencer": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz",
+ "integrity": "sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/test-result": "^27.0.6",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^27.0.6",
+ "jest-runtime": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.6.tgz",
+ "integrity": "sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.1.0",
+ "@jest/types": "^27.0.6",
+ "babel-plugin-istanbul": "^6.0.0",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^1.4.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.1",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.1",
+ "write-file-atomic": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/transform/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/@jest/transform/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/transform/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/@jest/transform/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/@jest/transform/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/transform/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/@jest/transform/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/@jest/transform/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/@jest/transform/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/transform/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/@jest/transform/node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/@jest/transform/node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@jest/transform/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/@jest/transform/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/@jest/transform/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/@jest/types": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz",
+ "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 10.14.2"
+ }
+ },
+ "node_modules/@jest/types/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/@jest/types/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/@jest/types/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/@jest/types/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/@jest/types/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/types/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/@nicolo-ribaudo/chokidar-2": {
+ "version": "2.1.8-no-fsevents.2",
+ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.2.tgz",
+ "integrity": "sha512-Fb8WxUFOBQVl+CX4MWet5o7eCc6Pj04rXIwVKZ6h1NnqTo45eOQW6aWyhG25NIODvWFwTDMwBsYxrQ3imxpetg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "glob-parent": "^5.1.2",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
+ "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.4",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz",
+ "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz",
+ "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.4",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
+ "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+ "dev": true,
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz",
+ "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "node_modules/@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "dependencies": {
+ "defer-to-connect": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@types/anymatch": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
+ "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA=="
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.1.15",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz",
+ "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz",
+ "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz",
+ "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz",
+ "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==",
+ "dev": true,
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "7.2.14",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.14.tgz",
+ "integrity": "sha512-pESyhSbUOskqrGcaN+bCXIQDyT5zTaRWfj5ZjjSlMatgGjIn3QQPfocAu4WSabUR7CGyLZ2CQaZyISOEX7/saw==",
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz",
+ "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==",
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "0.0.50",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
+ "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
+ },
+ "node_modules/@types/events": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.13",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
+ "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
+ "dev": true,
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.18",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "4.17.24",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz",
+ "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+ "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+ "dependencies": {
+ "@types/events": "*",
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz",
+ "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
+ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==",
+ "dev": true
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "26.0.24",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz",
+ "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==",
+ "dev": true,
+ "dependencies": {
+ "jest-diff": "^26.0.0",
+ "pretty-format": "^26.0.0"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
+ "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA=="
+ },
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
+ "dev": true
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
+ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==",
+ "dev": true
+ },
+ "node_modules/@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
+ },
+ "node_modules/@types/node": {
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz",
+ "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA=="
+ },
+ "node_modules/@types/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+ "dev": true
+ },
+ "node_modules/@types/prettier": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==",
+ "dev": true
+ },
+ "node_modules/@types/qs": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
+ "dev": true
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
+ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
+ "dev": true
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.13.10",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz",
+ "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/source-list-map": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
+ "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA=="
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+ "dev": true
+ },
+ "node_modules/@types/tapable": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.4.tgz",
+ "integrity": "sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ=="
+ },
+ "node_modules/@types/uglify-js": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz",
+ "integrity": "sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ==",
+ "dependencies": {
+ "source-map": "^0.6.1"
+ }
+ },
+ "node_modules/@types/webpack": {
+ "version": "4.41.0",
+ "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.0.tgz",
+ "integrity": "sha512-tWkdf9nO0zFgAY/EumUKwrDUhraHKDqCPhwfFR/R8l0qnPdgb9le0Gzhvb7uzVpouuDGBgiE//ZdY+5jcZy2TA==",
+ "dependencies": {
+ "@types/anymatch": "*",
+ "@types/node": "*",
+ "@types/tapable": "*",
+ "@types/uglify-js": "*",
+ "@types/webpack-sources": "*",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/@types/webpack-sources": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.5.tgz",
+ "integrity": "sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w==",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/source-list-map": "*",
+ "source-map": "^0.6.1"
+ }
+ },
+ "node_modules/@types/yargs": {
+ "version": "15.0.14",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
+ "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "20.2.1",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz",
+ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/experimental-utils": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.1.tgz",
+ "integrity": "sha512-svYlHecSMCQGDO2qN1v477ax/IDQwWhc7PRBiwAdAMJE7GXk5stF4Z9R/8wbRkuX/5e9dHqbIWxjeOjckK3wLQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.3",
+ "@typescript-eslint/scope-manager": "4.22.1",
+ "@typescript-eslint/types": "4.22.1",
+ "@typescript-eslint/typescript-estree": "4.22.1",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^2.0.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "*"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.1.tgz",
+ "integrity": "sha512-d5bAiPBiessSmNi8Amq/RuLslvcumxLmyhf1/Xa9IuaoFJ0YtshlJKxhlbY7l2JdEk3wS0EnmnfeJWSvADOe0g==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "4.22.1",
+ "@typescript-eslint/visitor-keys": "4.22.1"
+ },
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.1.tgz",
+ "integrity": "sha512-2HTkbkdAeI3OOcWbqA8hWf/7z9c6gkmnWNGz0dKSLYLWywUlkOAQ2XcjhlKLj5xBFDf8FgAOF5aQbnLRvgNbCw==",
+ "dev": true,
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.1.tgz",
+ "integrity": "sha512-p3We0pAPacT+onSGM+sPR+M9CblVqdA9F1JEdIqRVlxK5Qth4ochXQgIyb9daBomyQKAXbygxp1aXQRV0GC79A==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "4.22.1",
+ "@typescript-eslint/visitor-keys": "4.22.1",
+ "debug": "^4.1.1",
+ "globby": "^11.0.1",
+ "is-glob": "^4.0.1",
+ "semver": "^7.3.2",
+ "tsutils": "^3.17.1"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/node_modules/semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.1.tgz",
+ "integrity": "sha512-WPkOrIRm+WCLZxXQHCi+WG8T2MMTUFR70rWjdWYddLT7cEfb2P4a3O/J2U1FBVsSFTocXLCoXWY6MZGejeStvQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "4.22.1",
+ "eslint-visitor-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
+ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
+ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ=="
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg=="
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
+ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA=="
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
+ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
+ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q=="
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
+ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
+ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
+ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
+ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ=="
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
+ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/helper-wasm-section": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-opt": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "@webassemblyjs/wast-printer": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
+ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
+ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
+ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
+ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.11.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webpack-cli/configtest": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.4.tgz",
+ "integrity": "sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==",
+ "dev": true,
+ "peerDependencies": {
+ "webpack": "4.x.x || 5.x.x",
+ "webpack-cli": "4.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/info": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.3.0.tgz",
+ "integrity": "sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==",
+ "dev": true,
+ "dependencies": {
+ "envinfo": "^7.7.3"
+ },
+ "peerDependencies": {
+ "webpack-cli": "4.x.x"
+ }
+ },
+ "node_modules/@webpack-cli/serve": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.1.tgz",
+ "integrity": "sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw==",
+ "dev": true,
+ "peerDependencies": {
+ "webpack-cli": "4.x.x"
+ },
+ "peerDependenciesMeta": {
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
+ },
+ "node_modules/abab": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+ "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.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "dependencies": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-globals": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+ "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^7.1.1",
+ "acorn-walk": "^7.1.1"
+ }
+ },
+ "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/acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/agent-base/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/agent-base/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/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==",
+ "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/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/ansi-align": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+ "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^3.0.0"
+ }
+ },
+ "node_modules/ansi-align/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-align/node_modules/emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "node_modules/ansi-align/node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ansi-align/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-align/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
+ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/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.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "node_modules/anymatch/node_modules/normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "remove-trailing-separator": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/aria-query": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz",
+ "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.2",
+ "@babel/runtime-corejs3": "^7.10.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "node_modules/array-includes": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
+ "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0",
+ "is-string": "^1.0.5"
+ },
+ "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-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz",
+ "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/es-abstract": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "is-callable": "^1.2.3",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/es-abstract/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/is-callable": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/is-regex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
+ "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/is-regex/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/is-string": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
+ "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/string.prototype.trimend/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat/node_modules/string.prototype.trimstart/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz",
+ "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1",
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/es-abstract": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "is-callable": "^1.2.3",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/es-abstract/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/is-callable": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/is-regex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
+ "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/is-regex/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/is-string": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
+ "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/string.prototype.trimend/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flatmap/node_modules/string.prototype.trimstart/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ast-types-flow": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
+ "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
+ "dev": true
+ },
+ "node_modules/astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/async-each": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "node_modules/atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true,
+ "optional": true,
+ "bin": {
+ "atob": "bin/atob.js"
+ },
+ "engines": {
+ "node": ">= 4.5.0"
+ }
+ },
+ "node_modules/axe-core": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.0.2.tgz",
+ "integrity": "sha512-arU1h31OGFu+LPrOLGZ7nB45v940NMDMEJeNmbutu57P+UFDVnkZg3e+J1I2HJRZ9hT7gO8J91dn/PMrAiKakA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/axios": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+ "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+ "dependencies": {
+ "follow-redirects": "^1.10.0"
+ }
+ },
+ "node_modules/axobject-query": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
+ "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==",
+ "dev": true
+ },
+ "node_modules/babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ },
+ "node_modules/babel-code-frame/node_modules/strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-code-frame/node_modules/supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/babel-core": {
+ "version": "6.26.3",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+ "dev": true,
+ "dependencies": {
+ "babel-code-frame": "^6.26.0",
+ "babel-generator": "^6.26.0",
+ "babel-helpers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-register": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "convert-source-map": "^1.5.1",
+ "debug": "^2.6.9",
+ "json5": "^0.5.1",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.4",
+ "path-is-absolute": "^1.0.1",
+ "private": "^0.1.8",
+ "slash": "^1.0.0",
+ "source-map": "^0.5.7"
+ }
+ },
+ "node_modules/babel-core/node_modules/json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/babel-core/node_modules/slash": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-core/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-eslint": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
+ "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==",
+ "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/parser": "^7.7.0",
+ "@babel/traverse": "^7.7.0",
+ "@babel/types": "^7.7.0",
+ "eslint-visitor-keys": "^1.0.0",
+ "resolve": "^1.12.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "eslint": ">= 4.12.1"
+ }
+ },
+ "node_modules/babel-generator": {
+ "version": "6.26.1",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+ "dev": true,
+ "dependencies": {
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "detect-indent": "^4.0.0",
+ "jsesc": "^1.3.0",
+ "lodash": "^4.17.4",
+ "source-map": "^0.5.7",
+ "trim-right": "^1.0.1"
+ }
+ },
+ "node_modules/babel-generator/node_modules/jsesc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/babel-generator/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-helper-builder-binary-assignment-operator-visitor": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-explode-assignable-expression": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-call-delegate": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-define-map": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/babel-helper-explode-assignable-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-get-function-arity": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-hoist-variables": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-optimise-call-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-regex": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/babel-helper-remap-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helper-replace-supers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-helpers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/babel-jest": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.6.tgz",
+ "integrity": "sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.0.0",
+ "babel-preset-jest": "^27.0.6",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
+ }
+ },
+ "node_modules/babel-jest/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/babel-jest/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/babel-jest/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/babel-jest/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/babel-jest/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/babel-jest/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/babel-jest/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/babel-jest/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/babel-jest/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/babel-loader": {
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz",
+ "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==",
+ "dev": true,
+ "dependencies": {
+ "find-cache-dir": "^3.3.1",
+ "loader-utils": "^1.4.0",
+ "make-dir": "^3.1.0",
+ "schema-utils": "^2.6.5"
+ },
+ "engines": {
+ "node": ">= 8.9"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "webpack": ">=2"
+ }
+ },
+ "node_modules/babel-loader/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/babel-loader/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-check-es2015-constants": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "dependencies": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
+ "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^4.0.0",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz",
+ "integrity": "sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.0.0",
+ "@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/babel-plugin-lodash": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz",
+ "integrity": "sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.0.0-beta.49",
+ "@babel/types": "^7.0.0-beta.49",
+ "glob": "^7.1.1",
+ "lodash": "^4.17.10",
+ "require-package-name": "^2.0.1"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz",
+ "integrity": "sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.13.11",
+ "@babel/helper-define-polyfill-provider": "^0.2.2",
+ "semver": "^6.1.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-corejs3": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz",
+ "integrity": "sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.2.2",
+ "core-js-compat": "^3.14.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/babel-plugin-polyfill-regenerator": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz",
+ "integrity": "sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-define-polyfill-provider": "^0.2.2"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/babel-plugin-syntax-async-functions": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+ "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+ "dev": true
+ },
+ "node_modules/babel-plugin-syntax-exponentiation-operator": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+ "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+ "dev": true
+ },
+ "node_modules/babel-plugin-syntax-trailing-function-commas": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+ "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+ "dev": true
+ },
+ "node_modules/babel-plugin-transform-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-remap-async-to-generator": "^6.24.1",
+ "babel-plugin-syntax-async-functions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-classes": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-define-map": "^6.24.1",
+ "babel-helper-function-name": "^6.24.1",
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-destructuring": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-for-of": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+ "dev": true,
+ "dependencies": {
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.26.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+ "dev": true,
+ "dependencies": {
+ "babel-plugin-transform-strict-mode": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-types": "^6.26.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+ "dev": true,
+ "dependencies": {
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-object-super": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-parameters": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-call-delegate": "^6.24.1",
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-spread": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-template-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "regexpu-core": "^2.0.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-exponentiation-operator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+ "dev": true,
+ "dependencies": {
+ "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+ "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-regenerator": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+ "dev": true,
+ "dependencies": {
+ "regenerator-transform": "^0.10.0"
+ }
+ },
+ "node_modules/babel-plugin-transform-strict-mode": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-preset-env": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
+ "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
+ "dev": true,
+ "dependencies": {
+ "babel-plugin-check-es2015-constants": "^6.22.0",
+ "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+ "babel-plugin-transform-async-to-generator": "^6.22.0",
+ "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
+ "babel-plugin-transform-es2015-classes": "^6.23.0",
+ "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-destructuring": "^6.23.0",
+ "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
+ "babel-plugin-transform-es2015-for-of": "^6.23.0",
+ "babel-plugin-transform-es2015-function-name": "^6.22.0",
+ "babel-plugin-transform-es2015-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
+ "babel-plugin-transform-es2015-object-super": "^6.22.0",
+ "babel-plugin-transform-es2015-parameters": "^6.23.0",
+ "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-spread": "^6.22.0",
+ "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
+ "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
+ "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
+ "babel-plugin-transform-exponentiation-operator": "^6.22.0",
+ "babel-plugin-transform-regenerator": "^6.22.0",
+ "browserslist": "^3.2.6",
+ "invariant": "^2.2.2",
+ "semver": "^5.3.0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz",
+ "integrity": "sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw==",
+ "dev": true,
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^27.0.6",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-register": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+ "dev": true,
+ "dependencies": {
+ "babel-core": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "home-or-tmp": "^2.0.0",
+ "lodash": "^4.17.4",
+ "mkdirp": "^0.5.1",
+ "source-map-support": "^0.4.15"
+ }
+ },
+ "node_modules/babel-register/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-register/node_modules/source-map-support": {
+ "version": "0.4.18",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+ "dev": true,
+ "dependencies": {
+ "source-map": "^0.5.6"
+ }
+ },
+ "node_modules/babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "dependencies": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ }
+ },
+ "node_modules/babel-runtime/node_modules/regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ },
+ "node_modules/babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+ "dev": true,
+ "dependencies": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ }
+ },
+ "node_modules/babel-traverse/node_modules/globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ }
+ },
+ "node_modules/babel-types/node_modules/to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true,
+ "bin": {
+ "babylon": "bin/babylon.js"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "node_modules/base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/binance-api-node": {
+ "version": "0.11.5",
+ "resolved": "https://registry.npmjs.org/binance-api-node/-/binance-api-node-0.11.5.tgz",
+ "integrity": "sha512-YLVpcU14d8+iw24c56TgZkZG0u86Lrctm1WloDttYP7DXsmg9meu21zDgRKkiQhZqfjoDoHAXxgByxwLOPQLsQ==",
+ "dependencies": {
+ "isomorphic-fetch": "^2.2.1",
+ "isomorphic-ws": "^4.0.1",
+ "lodash.zipobject": "^4.1.3",
+ "reconnecting-websocket": "^4.2.0",
+ "ws": "^7.2.0"
+ },
+ "engines": {
+ "yarn": ">= 1.0.0"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/bl": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
+ "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==",
+ "dependencies": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+ },
+ "node_modules/body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "dependencies": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/body-parser/node_modules/qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/boxen": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
+ "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-align": "^3.0.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^3.0.0",
+ "cli-boxes": "^2.2.0",
+ "string-width": "^4.1.0",
+ "term-size": "^2.1.0",
+ "type-fest": "^0.8.1",
+ "widest-line": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/boxen/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/boxen/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/boxen/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/boxen/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/boxen/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/boxen/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/boxen/node_modules/type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/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": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/braces/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+ "dev": true
+ },
+ "node_modules/browserslist": {
+ "version": "3.2.8",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+ "dev": true,
+ "dependencies": {
+ "caniuse-lite": "^1.0.30000844",
+ "electron-to-chromium": "^1.3.47"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/bson": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz",
+ "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
+ },
+ "node_modules/bunyan": {
+ "version": "1.8.15",
+ "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz",
+ "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==",
+ "engines": [
+ "node >=0.10.0"
+ ],
+ "bin": {
+ "bunyan": "bin/bunyan"
+ },
+ "optionalDependencies": {
+ "dtrace-provider": "~0.8",
+ "moment": "^2.19.3",
+ "mv": "~2",
+ "safe-json-stringify": "~1"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "dependencies": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz",
+ "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001015",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz",
+ "integrity": "sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ==",
+ "dev": true
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
+ "dev": true,
+ "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/chokidar/node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/chokidar/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/chokidar/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/chokidar/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/chokidar/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/chokidar/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/chokidar/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/chokidar/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/chrome-trace-event": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
+ "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
+ "dev": true
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz",
+ "integrity": "sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw==",
+ "dev": true
+ },
+ "node_modules/class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/class-utils/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/clean-webpack-plugin": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz",
+ "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==",
+ "dependencies": {
+ "@types/webpack": "^4.4.31",
+ "del": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ },
+ "peerDependencies": {
+ "webpack": "*"
+ }
+ },
+ "node_modules/clean-webpack-plugin/node_modules/array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dependencies": {
+ "array-uniq": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/clean-webpack-plugin/node_modules/del": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+ "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+ "dependencies": {
+ "@types/glob": "^7.1.1",
+ "globby": "^6.1.0",
+ "is-path-cwd": "^2.0.0",
+ "is-path-in-cwd": "^2.0.0",
+ "p-map": "^2.0.0",
+ "pify": "^4.0.1",
+ "rimraf": "^2.6.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/clean-webpack-plugin/node_modules/globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dependencies": {
+ "array-union": "^1.0.1",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/clean-webpack-plugin/node_modules/globby/node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cli-boxes": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
+ "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+ "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+ "dev": true,
+ "dependencies": {
+ "slice-ansi": "^3.0.0",
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate/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/cli-truncate/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/cli-truncate/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/cli-truncate/node_modules/slice-ansi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+ "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz",
+ "integrity": "sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true,
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "node_modules/collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ },
+ "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "node_modules/colorette": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
+ "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "node_modules/component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "node_modules/config": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/config/-/config-3.3.6.tgz",
+ "integrity": "sha512-Hj5916C5HFawjYJat1epbyY2PlAgLpBtDUlr0MxGLgo3p5+7kylyvnRY18PqJHgnNWXcdd0eWDemT7eYWuFgwg==",
+ "dependencies": {
+ "json5": "^2.1.1"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/config/node_modules/json5": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/configstore": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
+ "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
+ "dev": true,
+ "dependencies": {
+ "dot-prop": "^5.2.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^3.0.0",
+ "unique-string": "^2.0.0",
+ "write-file-atomic": "^3.0.0",
+ "xdg-basedir": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/configstore/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/configstore/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/confusing-browser-globals": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz",
+ "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==",
+ "dev": true
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "node_modules/copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/core-js": {
+ "version": "2.6.10",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
+ "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==",
+ "deprecated": "core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.",
+ "dev": true,
+ "hasInstallScript": true
+ },
+ "node_modules/core-js-compat": {
+ "version": "3.15.2",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz",
+ "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==",
+ "dev": true,
+ "dependencies": {
+ "browserslist": "^4.16.6",
+ "semver": "7.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-js-compat/node_modules/browserslist": {
+ "version": "4.16.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
+ "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "dev": true,
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001219",
+ "colorette": "^1.2.2",
+ "electron-to-chromium": "^1.3.723",
+ "escalade": "^3.1.1",
+ "node-releases": "^1.1.71"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ }
+ },
+ "node_modules/core-js-compat/node_modules/caniuse-lite": {
+ "version": "1.0.30001243",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
+ "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==",
+ "dev": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ }
+ },
+ "node_modules/core-js-compat/node_modules/electron-to-chromium": {
+ "version": "1.3.772",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
+ "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==",
+ "dev": true
+ },
+ "node_modules/core-js-compat/node_modules/semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/core-js-pure": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz",
+ "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "node_modules/cosmiconfig": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
+ "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==",
+ "dev": true,
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cosmiconfig/node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cosmiconfig/node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cron": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz",
+ "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==",
+ "dependencies": {
+ "moment-timezone": "^0.5.x"
+ }
+ },
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "bin": {
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
+ "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cssom": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+ "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+ "dev": true
+ },
+ "node_modules/cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "dev": true,
+ "dependencies": {
+ "cssom": "~0.3.6"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cssstyle/node_modules/cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true
+ },
+ "node_modules/damerau-levenshtein": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz",
+ "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==",
+ "dev": true
+ },
+ "node_modules/data-urls": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
+ "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
+ "dev": true,
+ "dependencies": {
+ "abab": "^2.0.3",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/dateformat": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
+ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "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/decimal.js": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
+ "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==",
+ "dev": true
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+ "dev": true
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "node_modules/deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+ "dev": true
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "^1.0.12"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-property/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/denque": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz",
+ "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "node_modules/detect-indent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+ "dev": true,
+ "dependencies": {
+ "repeating": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz",
+ "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.14.2"
+ }
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dir-glob/node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/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/domexception": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
+ "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
+ "dev": true,
+ "dependencies": {
+ "webidl-conversions": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/domexception/node_modules/webidl-conversions": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
+ "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dot-prop/node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
+ "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/dtrace-provider": {
+ "version": "0.8.8",
+ "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz",
+ "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==",
+ "hasInstallScript": true,
+ "optional": true,
+ "dependencies": {
+ "nan": "^2.14.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.3.322",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz",
+ "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==",
+ "dev": true
+ },
+ "node_modules/emittery": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz",
+ "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "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==",
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/encoding/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.8.2",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz",
+ "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-colors": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz",
+ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
+ "dev": true,
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.17.6",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
+ "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
+ "dev": true,
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.0",
+ "is-regex": "^1.1.0",
+ "object-inspect": "^1.7.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
+ "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw=="
+ },
+ "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/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-goat": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
+ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/escodegen": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+ "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+ "dev": true,
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/escodegen/node_modules/estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/escodegen/node_modules/levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/escodegen/node_modules/optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/escodegen/node_modules/prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/escodegen/node_modules/type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "dependencies": {
+ "prelude-ls": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "7.30.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz",
+ "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "7.12.11",
+ "@eslint/eslintrc": "^0.4.2",
+ "@humanwhocodes/config-array": "^0.5.0",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "enquirer": "^2.3.5",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^2.1.0",
+ "eslint-visitor-keys": "^2.0.0",
+ "espree": "^7.3.1",
+ "esquery": "^1.4.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.1.2",
+ "globals": "^13.6.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.0.4",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "progress": "^2.0.0",
+ "regexpp": "^3.1.0",
+ "semver": "^7.2.1",
+ "strip-ansi": "^6.0.0",
+ "strip-json-comments": "^3.1.0",
+ "table": "^6.0.9",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-config-airbnb": {
+ "version": "18.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz",
+ "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-config-airbnb-base": "^14.2.1",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "peerDependencies": {
+ "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0",
+ "eslint-plugin-import": "^2.22.1",
+ "eslint-plugin-jsx-a11y": "^6.4.1",
+ "eslint-plugin-react": "^7.21.5",
+ "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0"
+ }
+ },
+ "node_modules/eslint-config-airbnb-base": {
+ "version": "14.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz",
+ "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==",
+ "dev": true,
+ "dependencies": {
+ "confusing-browser-globals": "^1.0.10",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "peerDependencies": {
+ "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0",
+ "eslint-plugin-import": "^2.22.1"
+ }
+ },
+ "node_modules/eslint-config-airbnb-base/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-config-airbnb/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz",
+ "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-config-react-app": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz",
+ "integrity": "sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==",
+ "dev": true,
+ "dependencies": {
+ "confusing-browser-globals": "^1.0.10"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/eslint-plugin": "^4.0.0",
+ "@typescript-eslint/parser": "^4.0.0",
+ "babel-eslint": "^10.0.0",
+ "eslint": "^7.5.0",
+ "eslint-plugin-flowtype": "^5.2.0",
+ "eslint-plugin-import": "^2.22.0",
+ "eslint-plugin-jest": "^24.0.0",
+ "eslint-plugin-jsx-a11y": "^6.3.1",
+ "eslint-plugin-react": "^7.20.3",
+ "eslint-plugin-react-hooks": "^4.0.8",
+ "eslint-plugin-testing-library": "^3.9.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint-plugin-jest": {
+ "optional": true
+ },
+ "eslint-plugin-testing-library": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz",
+ "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.6.9",
+ "resolve": "^1.13.1"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz",
+ "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.2.7",
+ "pkg-dir": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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-module-utils/node_modules/pkg-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-plugin-es": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz",
+ "integrity": "sha512-6/Jb/J/ZvSebydwbBJO1R9E5ky7YeElfK56Veh7e4QGFHCXoIXGH9HhVz+ibJLM3XJ1XjP+T7rKBLUa/Y7eIng==",
+ "dev": true,
+ "dependencies": {
+ "eslint-utils": "^2.0.0",
+ "regexpp": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=4.19.1"
+ }
+ },
+ "node_modules/eslint-plugin-flowtype": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.8.0.tgz",
+ "integrity": "sha512-feK1xnUTsMSNTOw9jFw7aVgZl7Ep+ghpta/YEoaV6jbXU6Yso30B7BIj9ObHLzZ5TFJL7D98az080wfykLCrcw==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.15",
+ "string-natural-compare": "^3.0.1"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.1.0"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.23.4",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz",
+ "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.3",
+ "array.prototype.flat": "^1.2.4",
+ "debug": "^2.6.9",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.4",
+ "eslint-module-utils": "^2.6.1",
+ "find-up": "^2.0.0",
+ "has": "^1.0.3",
+ "is-core-module": "^2.4.0",
+ "minimatch": "^3.0.4",
+ "object.values": "^1.1.3",
+ "pkg-up": "^2.0.0",
+ "read-pkg-up": "^3.0.0",
+ "resolve": "^1.20.0",
+ "tsconfig-paths": "^3.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/array-includes": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz",
+ "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.2",
+ "get-intrinsic": "^1.1.1",
+ "is-string": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/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/es-abstract": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "is-callable": "^1.2.3",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/es-abstract/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/es-abstract/node_modules/is-string": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
+ "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/is-callable": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/is-regex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
+ "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/is-regex/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-jest": {
+ "version": "24.3.6",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz",
+ "integrity": "sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/experimental-utils": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/eslint-plugin": ">= 4",
+ "eslint": ">=5"
+ },
+ "peerDependenciesMeta": {
+ "@typescript-eslint/eslint-plugin": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz",
+ "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "aria-query": "^4.2.2",
+ "array-includes": "^3.1.1",
+ "ast-types-flow": "^0.0.7",
+ "axe-core": "^4.0.2",
+ "axobject-query": "^2.2.0",
+ "damerau-levenshtein": "^1.0.6",
+ "emoji-regex": "^9.0.0",
+ "has": "^1.0.3",
+ "jsx-ast-utils": "^3.1.0",
+ "language-tags": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7"
+ }
+ },
+ "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz",
+ "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==",
+ "dev": true
+ },
+ "node_modules/eslint-plugin-node": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
+ "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
+ "dev": true,
+ "dependencies": {
+ "eslint-plugin-es": "^3.0.0",
+ "eslint-utils": "^2.0.0",
+ "ignore": "^5.1.1",
+ "minimatch": "^3.0.4",
+ "resolve": "^1.10.1",
+ "semver": "^6.1.0"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=5.16.0"
+ }
+ },
+ "node_modules/eslint-plugin-node/node_modules/ignore": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
+ "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/eslint-plugin-node/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-plugin-prettier": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz",
+ "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==",
+ "dev": true,
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=5.0.0",
+ "prettier": ">=1.13.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-promise": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz",
+ "integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==",
+ "dev": true,
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react": {
+ "version": "7.24.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz",
+ "integrity": "sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.3",
+ "array.prototype.flatmap": "^1.2.4",
+ "doctrine": "^2.1.0",
+ "has": "^1.0.3",
+ "jsx-ast-utils": "^2.4.1 || ^3.0.0",
+ "minimatch": "^3.0.4",
+ "object.entries": "^1.1.4",
+ "object.fromentries": "^2.0.4",
+ "object.values": "^1.1.4",
+ "prop-types": "^15.7.2",
+ "resolve": "^2.0.0-next.3",
+ "string.prototype.matchall": "^4.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^3 || ^4 || ^5 || ^6 || ^7"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz",
+ "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/array-includes": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz",
+ "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.2",
+ "get-intrinsic": "^1.1.1",
+ "is-string": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/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-react/node_modules/es-abstract": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "is-callable": "^1.2.3",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/es-abstract/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/es-abstract/node_modules/is-string": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
+ "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/is-callable": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/is-regex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
+ "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/is-regex/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/object.entries": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz",
+ "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/resolve": {
+ "version": "2.0.0-next.3",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz",
+ "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+ "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint/node_modules/@babel/code-frame": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+ "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "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.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+ "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint/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/eslint/node_modules/globals": {
+ "version": "13.10.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
+ "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/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/node_modules/semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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/espree": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
+ "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+ "dev": true,
+ "dependencies": {
+ "acorn": "^7.4.0",
+ "acorn-jsx": "^5.3.1",
+ "eslint-visitor-keys": "^1.3.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+ "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "dev": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esquery/node_modules/estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "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/execa/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/execa/node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/execa/node_modules/is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-brackets/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expand-brackets/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz",
+ "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-styles": "^5.0.0",
+ "jest-get-type": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-regex-util": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/expect/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/expect/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/expect/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/expect/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/expect/node_modules/chalk/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/expect/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/expect/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/expect/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/expect/node_modules/jest-get-type": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/expect/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/express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "dependencies": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/express/node_modules/qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extend-shallow/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
+ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
+ },
+ "node_modules/fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "node_modules/fast-glob": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
+ "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.0",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.2",
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fast-glob/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/fast-glob/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/fast-glob/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/fast-glob/node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/fast-glob/node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz",
+ "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/fast-glob/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/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=="
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
+ "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
+ "dev": true
+ },
+ "node_modules/fastq": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz",
+ "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+ "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+ "dev": true,
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "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/fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fill-range/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/find-cache-dir": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+ "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+ "dev": true,
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-cache-dir/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/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/flat-cache/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/flatted": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz",
+ "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==",
+ "dev": true
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz",
+ "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "map-cache": "^0.2.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs-readdir-recursive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+ "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
+ "dev": true
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "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==",
+ "dev": true
+ },
+ "node_modules/functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz",
+ "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-own-enumerable-property-symbols": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
+ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
+ "dev": true
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
+ },
+ "node_modules/global-dirs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
+ "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==",
+ "dev": true,
+ "dependencies": {
+ "ini": "1.3.7"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz",
+ "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==",
+ "dev": true,
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.1.1",
+ "ignore": "^5.1.4",
+ "merge2": "^1.3.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/ignore": {
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
+ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/globby/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/got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-ansi/node_modules/ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-bigints": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
+ "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+ "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": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values/node_modules/kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-yarn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
+ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/home-or-tmp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+ "dev": true,
+ "dependencies": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
+ "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
+ "dev": true,
+ "dependencies": {
+ "whatwg-encoding": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+ "dev": true
+ },
+ "node_modules/http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "dev": true,
+ "dependencies": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/http-proxy-agent/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/https-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/https-proxy-agent/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/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/husky": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.1.tgz",
+ "integrity": "sha512-gceRaITVZ+cJH9sNHqx5tFwbzlLCVxtVZcusME8JYQ8Edy5mpGDOqD8QBCdMhpyo9a+JXddnujQ4rpY2Ff9SJA==",
+ "dev": true,
+ "bin": {
+ "husky": "lib/bin.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
+ "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": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "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": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
+ "dev": true
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
+ "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+ "dev": true,
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "node_modules/ini": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
+ "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==",
+ "dev": true
+ },
+ "node_modules/internal-slot": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
+ "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.0",
+ "has": "^1.0.3",
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/internal-slot/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/interpret": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz",
+ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "node_modules/ioredis": {
+ "version": "4.27.6",
+ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.27.6.tgz",
+ "integrity": "sha512-6W3ZHMbpCa8ByMyC1LJGOi7P2WiOKP9B3resoZOVLDhi+6dDBOW+KNsRq3yI36Hmnb2sifCxHX+YSarTeXh48A==",
+ "dependencies": {
+ "cluster-key-slot": "^1.1.0",
+ "debug": "^4.3.1",
+ "denque": "^1.1.0",
+ "lodash.defaults": "^4.2.0",
+ "lodash.flatten": "^4.4.0",
+ "p-map": "^2.1.0",
+ "redis-commands": "1.7.0",
+ "redis-errors": "^1.2.0",
+ "redis-parser": "^3.0.0",
+ "standard-as-callback": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ioredis"
+ }
+ },
+ "node_modules/ioredis/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ioredis/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/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-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-accessor-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "node_modules/is-bigint": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz",
+ "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "binary-extensions": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-boolean-object": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
+ "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-boolean-object/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
+ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-ci": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
+ "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
+ "dev": true,
+ "dependencies": {
+ "ci-info": "^3.1.1"
+ },
+ "bin": {
+ "is-ci": "bin.js"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
+ "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-data-descriptor/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-descriptor/node_modules/kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "dependencies": {
+ "number-is-nan": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
+ "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
+ "dev": true,
+ "dependencies": {
+ "global-dirs": "^2.0.1",
+ "is-path-inside": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-negative-zero": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz",
+ "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-npm": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
+ "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number-object": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
+ "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-path-in-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
+ "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+ "dependencies": {
+ "is-path-inside": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-path-in-cwd/node_modules/is-path-inside": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+ "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+ "dependencies": {
+ "path-is-inside": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true
+ },
+ "node_modules/is-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+ "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-string": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
+ "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-yarn-global": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
+ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
+ "dev": true
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isomorphic-fetch": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+ "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+ "dependencies": {
+ "node-fetch": "^1.0.1",
+ "whatwg-fetch": ">=0.10.0"
+ }
+ },
+ "node_modules/isomorphic-ws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
+ "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==",
+ "peerDependencies": {
+ "ws": "*"
+ }
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+ "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
+ "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.7.5",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.0.0",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/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/istanbul-lib-report/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
+ "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/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/istanbul-reports": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
+ "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.6.tgz",
+ "integrity": "sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/core": "^27.0.6",
+ "import-local": "^3.0.2",
+ "jest-cli": "^27.0.6"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.6.tgz",
+ "integrity": "sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "execa": "^5.0.0",
+ "throat": "^6.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-changed-files/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-changed-files/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/jest-changed-files/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-changed-files/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/jest-changed-files/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/jest-changed-files/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-changed-files/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/jest-circus": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.6.tgz",
+ "integrity": "sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "expect": "^27.0.6",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "pretty-format": "^27.0.6",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3",
+ "throat": "^6.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-circus/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/jest-circus/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-circus/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/jest-circus/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/jest-circus/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-circus/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-circus/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/jest-circus/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/jest-config": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.6.tgz",
+ "integrity": "sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.1.0",
+ "@jest/test-sequencer": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "babel-jest": "^27.0.6",
+ "chalk": "^4.0.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.1",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^3.0.0",
+ "jest-circus": "^27.0.6",
+ "jest-environment-jsdom": "^27.0.6",
+ "jest-environment-node": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "jest-jasmine2": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-runner": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "peerDependencies": {
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-config/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-config/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/jest-config/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/jest-config/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-config/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/jest-config/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/jest-config/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/jest-config/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-config/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/jest-config/node_modules/jest-get-type": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-config/node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/jest-config/node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/jest-config/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-config/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-config/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/jest-config/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/jest-diff": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz",
+ "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^26.6.2",
+ "jest-get-type": "^26.3.0",
+ "pretty-format": "^26.6.2"
+ },
+ "engines": {
+ "node": ">= 10.14.2"
+ }
+ },
+ "node_modules/jest-diff/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/jest-diff/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-diff/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/jest-diff/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/jest-diff/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-diff/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/jest-docblock": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz",
+ "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==",
+ "dev": true,
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.6.tgz",
+ "integrity": "sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "pretty-format": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-each/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/jest-each/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-each/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/jest-each/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/jest-each/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-each/node_modules/jest-get-type": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-each/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/jest-environment-jsdom": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz",
+ "integrity": "sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^27.0.6",
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "jest-mock": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jsdom": "^16.6.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-environment-jsdom/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-environment-jsdom/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-environment-jsdom/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/jest-environment-jsdom/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-environment-jsdom/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/jest-environment-jsdom/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/jest-environment-jsdom/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-environment-jsdom/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/jest-environment-node": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.6.tgz",
+ "integrity": "sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^27.0.6",
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "jest-mock": "^27.0.6",
+ "jest-util": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-environment-node/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-environment-node/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-environment-node/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/jest-environment-node/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-environment-node/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/jest-environment-node/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/jest-environment-node/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-environment-node/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/jest-get-type": {
+ "version": "26.3.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz",
+ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.14.2"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.6.tgz",
+ "integrity": "sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "@types/graceful-fs": "^4.1.2",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-regex-util": "^27.0.6",
+ "jest-serializer": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-worker": "^27.0.6",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.7"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
+ }
+ },
+ "node_modules/jest-haste-map/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-haste-map/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-haste-map/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/jest-haste-map/node_modules/anymatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/jest-haste-map/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/jest-haste-map/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-haste-map/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/jest-haste-map/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/jest-haste-map/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/jest-haste-map/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-haste-map/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/jest-haste-map/node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/jest-haste-map/node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/jest-haste-map/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/jest-haste-map/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/jest-jasmine2": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz",
+ "integrity": "sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.1.0",
+ "@jest/environment": "^27.0.6",
+ "@jest/source-map": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "expect": "^27.0.6",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "pretty-format": "^27.0.6",
+ "throat": "^6.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-jasmine2/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-jasmine2/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-jasmine2/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/jest-jasmine2/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-jasmine2/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/jest-jasmine2/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/jest-jasmine2/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-jasmine2/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-jasmine2/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-jasmine2/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/jest-leak-detector": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz",
+ "integrity": "sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ==",
+ "dev": true,
+ "dependencies": {
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-leak-detector/node_modules/chalk/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/jest-leak-detector/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/jest-leak-detector/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/jest-leak-detector/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/jest-get-type": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/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/jest-matcher-utils": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz",
+ "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-matcher-utils/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/jest-matcher-utils/node_modules/diff-sequences": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
+ "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/jest-diff": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
+ "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/jest-get-type": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-message-util": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz",
+ "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^27.0.6",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^27.0.6",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/@babel/code-frame": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/jest-message-util/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==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-message-util/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/jest-message-util/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-message-util/node_modules/chalk/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/jest-message-util/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/jest-message-util/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/jest-message-util/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/jest-message-util/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/jest-message-util/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-message-util/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/jest-message-util/node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-message-util/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/jest-message-util/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/jest-mock": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.6.tgz",
+ "integrity": "sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "@types/node": "*"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-mock/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-mock/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-mock/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/jest-mock/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-mock/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/jest-mock/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/jest-mock/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-mock/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/jest-pnp-resolver": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
+ "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz",
+ "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.6.tgz",
+ "integrity": "sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "chalk": "^4.0.0",
+ "escalade": "^3.1.1",
+ "graceful-fs": "^4.2.4",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
+ "resolve": "^1.20.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz",
+ "integrity": "sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-snapshot": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-resolve-dependencies/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/jest-resolve-dependencies/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-resolve-dependencies/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/jest-resolve-dependencies/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/jest-resolve-dependencies/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-resolve-dependencies/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/jest-resolve/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-resolve/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-resolve/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/jest-resolve/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-resolve/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/jest-resolve/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/jest-resolve/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-resolve/node_modules/resolve": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
+ "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.2.0",
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/jest-resolve/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/jest-resolve/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/jest-runner": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.6.tgz",
+ "integrity": "sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^27.0.6",
+ "@jest/environment": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.8.1",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-docblock": "^27.0.6",
+ "jest-environment-jsdom": "^27.0.6",
+ "jest-environment-node": "^27.0.6",
+ "jest-haste-map": "^27.0.6",
+ "jest-leak-detector": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-worker": "^27.0.6",
+ "source-map-support": "^0.5.6",
+ "throat": "^6.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-runner/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-runner/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-runner/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/jest-runner/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-runner/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/jest-runner/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/jest-runner/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-runner/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/jest-runtime": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.6.tgz",
+ "integrity": "sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^27.0.6",
+ "@jest/environment": "^27.0.6",
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/globals": "^27.0.6",
+ "@jest/source-map": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-mock": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0",
+ "yargs": "^16.0.3"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-runtime/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-runtime/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-runtime/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/jest-runtime/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-runtime/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/jest-runtime/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/jest-runtime/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-runtime/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/jest-runtime/node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-runtime/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/jest-serializer": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz",
+ "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "graceful-fs": "^4.2.4"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.6.tgz",
+ "integrity": "sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.7.2",
+ "@babel/generator": "^7.7.2",
+ "@babel/parser": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.0.0",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/babel__traverse": "^7.0.4",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^27.0.6",
+ "graceful-fs": "^4.2.4",
+ "jest-diff": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "jest-haste-map": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^27.0.6",
+ "semver": "^7.3.2"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-snapshot/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/jest-snapshot/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-snapshot/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/jest-snapshot/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/jest-snapshot/node_modules/diff-sequences": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
+ "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/jest-diff": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
+ "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/jest-get-type": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jest-snapshot/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/jest-util": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz",
+ "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^3.0.0",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-util/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-util/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/jest-util/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-util/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/jest-util/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/jest-util/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-util/node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/jest-util/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/jest-validate": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.6.tgz",
+ "integrity": "sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^27.0.6",
+ "leven": "^3.1.0",
+ "pretty-format": "^27.0.6"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-validate/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/jest-validate/node_modules/camelcase": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
+ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-validate/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-validate/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/jest-validate/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/jest-validate/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-validate/node_modules/jest-get-type": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/pretty-format": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^27.0.6",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-validate/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/jest-watcher": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.6.tgz",
+ "integrity": "sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "jest-util": "^27.0.6",
+ "string-length": "^4.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-watcher/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-watcher/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest-watcher/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/jest-watcher/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest-watcher/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/jest-watcher/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/jest-watcher/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-watcher/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/jest-worker": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
+ "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/jest/node_modules/@jest/types": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^16.0.0",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest/node_modules/@types/yargs": {
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/jest/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/jest/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/jest/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/jest/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/jest/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest/node_modules/jest-cli": {
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.6.tgz",
+ "integrity": "sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/core": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "import-local": "^3.0.2",
+ "jest-config": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
+ "prompts": "^2.0.1",
+ "yargs": "^16.0.3"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest/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/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "16.6.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz",
+ "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==",
+ "dev": true,
+ "dependencies": {
+ "abab": "^2.0.5",
+ "acorn": "^8.2.4",
+ "acorn-globals": "^6.0.0",
+ "cssom": "^0.4.4",
+ "cssstyle": "^2.3.0",
+ "data-urls": "^2.0.0",
+ "decimal.js": "^10.2.1",
+ "domexception": "^2.0.1",
+ "escodegen": "^2.0.0",
+ "form-data": "^3.0.0",
+ "html-encoding-sniffer": "^2.0.1",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.0",
+ "parse5": "6.0.1",
+ "saxes": "^5.0.1",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.0.0",
+ "w3c-hr-time": "^1.0.2",
+ "w3c-xmlserializer": "^2.0.0",
+ "webidl-conversions": "^6.1.0",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^8.5.0",
+ "ws": "^7.4.5",
+ "xml-name-validator": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "canvas": "^2.5.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jsdom/node_modules/acorn": {
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
+ "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "dev": true
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json-schema-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=="
+ },
+ "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/jsx-ast-utils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.1.0.tgz",
+ "integrity": "sha512-d4/UOjg+mxAWxCiF0c5UTSwyqbchkbqCvK87aBovhnh8GtysTjWmgC63tY0cJx/HzGgm9qnA147jVBdpOiQ2RA==",
+ "dev": true,
+ "dependencies": {
+ "array-includes": "^3.1.1",
+ "object.assign": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/jsx-ast-utils/node_modules/es-abstract": {
+ "version": "1.18.0-next.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
+ "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
+ "dev": true,
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/jsx-ast-utils/node_modules/is-callable": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
+ "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/jsx-ast-utils/node_modules/object.assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz",
+ "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.0",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "dependencies": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/language-subtag-registry": {
+ "version": "0.3.21",
+ "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
+ "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==",
+ "dev": true
+ },
+ "node_modules/language-tags": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz",
+ "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=",
+ "dev": true,
+ "dependencies": {
+ "language-subtag-registry": "~0.3.2"
+ }
+ },
+ "node_modules/latest-version": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+ "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+ "dev": true,
+ "dependencies": {
+ "package-json": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/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/lines-and-columns": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+ "dev": true
+ },
+ "node_modules/lint-staged": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.0.0.tgz",
+ "integrity": "sha512-3rsRIoyaE8IphSUtO1RVTFl1e0SLBtxxUOPBtHxQgBHS5/i6nqvjcUfNioMa4BU9yGnPzbO+xkfLtXtxBpCzjw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.1",
+ "cli-truncate": "^2.1.0",
+ "commander": "^7.2.0",
+ "cosmiconfig": "^7.0.0",
+ "debug": "^4.3.1",
+ "dedent": "^0.7.0",
+ "enquirer": "^2.3.6",
+ "execa": "^5.0.0",
+ "listr2": "^3.8.2",
+ "log-symbols": "^4.1.0",
+ "micromatch": "^4.0.4",
+ "normalize-path": "^3.0.0",
+ "please-upgrade-node": "^3.2.0",
+ "string-argv": "0.3.1",
+ "stringify-object": "^3.3.0"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/lint-staged/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/lint-staged/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/lint-staged/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "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/lint-staged/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/lint-staged/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/lint-staged/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/lint-staged/node_modules/debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/lint-staged/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/lint-staged/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/lint-staged/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/lint-staged/node_modules/micromatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
+ "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/lint-staged/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/lint-staged/node_modules/picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/lint-staged/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/lint-staged/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/listr2": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.9.0.tgz",
+ "integrity": "sha512-+JxQt7Vi4WEWgJsxmOEX9lDbCumrb3mrEYIeE1VI7I4lf2rXE4v9pq3RMVNp+a9s6mCgc/IsF0ppHsLrx2BEAw==",
+ "dev": true,
+ "dependencies": {
+ "cli-truncate": "^2.1.0",
+ "colorette": "^1.2.2",
+ "log-update": "^4.0.0",
+ "p-map": "^4.0.0",
+ "rxjs": "^6.6.7",
+ "through": "^2.3.8",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "enquirer": ">= 2.3.0 < 3"
+ }
+ },
+ "node_modules/listr2/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/load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/load-json-file/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/loader-runner": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
+ "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "dev": true,
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/localtunnel": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.1.tgz",
+ "integrity": "sha512-LiaI5wZdz0xFkIQpXbNI62ZnNn8IMsVhwxHmhA+h4vj8R9JG/07bQHWwQlyy7b95/5fVOCHJfIHv+a5XnkvaJA==",
+ "dependencies": {
+ "axios": "0.21.1",
+ "debug": "4.3.1",
+ "openurl": "1.1.1",
+ "yargs": "16.2.0"
+ },
+ "bin": {
+ "lt": "bin/lt.js"
+ },
+ "engines": {
+ "node": ">=8.3.0"
+ }
+ },
+ "node_modules/localtunnel/node_modules/debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/localtunnel/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/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "node_modules/lodash-webpack-plugin": {
+ "version": "0.11.6",
+ "resolved": "https://registry.npmjs.org/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.6.tgz",
+ "integrity": "sha512-nsHN/+IxZK/C425vGC8pAxkKJ8KQH2+NJnhDul14zYNWr6HJcA95w+oRR7Cp0oZpOdMplDZXmjVROp8prPk7ig==",
+ "dependencies": {
+ "lodash": "^4.17.20"
+ },
+ "peerDependencies": {
+ "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.1.0"
+ }
+ },
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+ "dev": true
+ },
+ "node_modules/lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
+ },
+ "node_modules/lodash.flatten": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
+ },
+ "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.truncate": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
+ "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+ "dev": true
+ },
+ "node_modules/lodash.zipobject": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz",
+ "integrity": "sha1-s5n1q6j/YqdG9peb8gshT5ZNvvg="
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-symbols/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/log-symbols/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/log-symbols/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/log-symbols/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/log-symbols/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/log-update": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
+ "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^4.3.0",
+ "cli-cursor": "^3.1.0",
+ "slice-ansi": "^4.0.0",
+ "wrap-ansi": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/log-update/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/log-update/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
+ "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+ "dev": true,
+ "dependencies": {
+ "tmpl": "1.0.x"
+ }
+ },
+ "node_modules/map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memory-pager": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+ "optional": true
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "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==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/migrate": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/migrate/-/migrate-1.7.0.tgz",
+ "integrity": "sha512-I63YykITgWyI+ET4KO8xGePYkR9U7CtSe/RrR13vLbZSpUcAh4/ry2GswNv7Lywcsp3BaDHj7YdjC7ihVYCFmw==",
+ "dependencies": {
+ "chalk": "^2.4.1",
+ "commander": "^2.19.0",
+ "dateformat": "^3.0.3",
+ "dotenv": "^6.1.0",
+ "inherits": "^2.0.3",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "slug": "^0.9.2"
+ },
+ "bin": {
+ "migrate": "bin/migrate",
+ "migrate-create": "bin/migrate-create",
+ "migrate-down": "bin/migrate-down",
+ "migrate-init": "bin/migrate-init",
+ "migrate-list": "bin/migrate-list",
+ "migrate-up": "bin/migrate-up"
+ },
+ "engines": {
+ "node": ">= 0.4.x"
+ }
+ },
+ "node_modules/migrate/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
+ "node_modules/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.44.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+ "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.27",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+ "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+ "dependencies": {
+ "mime-db": "1.44.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "node_modules/mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mixin-deep/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/moment": {
+ "version": "2.29.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
+ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/moment-timezone": {
+ "version": "0.5.33",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.33.tgz",
+ "integrity": "sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w==",
+ "dependencies": {
+ "moment": ">= 2.9.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mongodb": {
+ "version": "3.6.10",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.10.tgz",
+ "integrity": "sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q==",
+ "dependencies": {
+ "bl": "^2.2.1",
+ "bson": "^1.1.4",
+ "denque": "^1.4.1",
+ "optional-require": "^1.0.3",
+ "safe-buffer": "^5.1.2"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "optionalDependencies": {
+ "saslprep": "^1.0.0"
+ },
+ "peerDependenciesMeta": {
+ "aws4": {
+ "optional": true
+ },
+ "bson-ext": {
+ "optional": true
+ },
+ "kerberos": {
+ "optional": true
+ },
+ "mongodb-client-encryption": {
+ "optional": true
+ },
+ "mongodb-extjson": {
+ "optional": true
+ },
+ "snappy": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "node_modules/mv": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
+ "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=",
+ "optional": true,
+ "dependencies": {
+ "mkdirp": "~0.5.1",
+ "ncp": "~2.0.0",
+ "rimraf": "~2.4.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/mv/node_modules/glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+ "optional": true,
+ "dependencies": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mv/node_modules/rimraf": {
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
+ "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=",
+ "optional": true,
+ "dependencies": {
+ "glob": "^6.0.1"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/nan": {
+ "version": "2.14.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+ "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "optional": true
+ },
+ "node_modules/nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "node_modules/ncp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
+ "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=",
+ "optional": true,
+ "bin": {
+ "ncp": "bin/ncp"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
+ },
+ "node_modules/node-fetch": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+ "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+ "dependencies": {
+ "encoding": "^0.1.11",
+ "is-stream": "^1.0.1"
+ }
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+ "dev": true
+ },
+ "node_modules/node-modules-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
+ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "1.1.73",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
+ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
+ },
+ "node_modules/nodemon": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.11.tgz",
+ "integrity": "sha512-V9UizUMs7hM63YC+e+26FC4iTqEA1GJsrM8C7DiNyPvYBOG/QE169kMIe+sH7FSe8YteMQpaKkUDwfAF83+kEQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "chokidar": "^3.2.2",
+ "debug": "^3.2.6",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^3.0.4",
+ "pstree.remy": "^1.1.7",
+ "semver": "^5.7.1",
+ "supports-color": "^5.5.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.3",
+ "update-notifier": "^4.1.0"
+ },
+ "bin": {
+ "nodemon": "bin/nodemon.js"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ },
+ "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/nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+ "dev": true,
+ "dependencies": {
+ "abbrev": "1"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+ "dev": true
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz",
+ "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==",
+ "dev": true,
+ "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-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.entries": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz",
+ "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5",
+ "has": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.fromentries": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz",
+ "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.2",
+ "has": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/es-abstract": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "is-callable": "^1.2.3",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/es-abstract/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/is-callable": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/is-regex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
+ "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/is-regex/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/is-string": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
+ "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.fromentries/node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.values": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz",
+ "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/es-abstract": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "is-callable": "^1.2.3",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/es-abstract/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/is-callable": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/is-regex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
+ "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/is-regex/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/is-string": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
+ "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.values/node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "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": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/openurl": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz",
+ "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c="
+ },
+ "node_modules/optional-require": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz",
+ "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+ "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "dev": true,
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-each-series": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
+ "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/package-json": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
+ "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
+ "dev": true,
+ "dependencies": {
+ "got": "^9.6.0",
+ "registry-auth-token": "^4.0.0",
+ "registry-url": "^5.0.0",
+ "semver": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/package-json/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/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-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true
+ },
+ "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/pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ },
+ "node_modules/path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-type/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dependencies": {
+ "pinkie": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
+ "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
+ "dev": true,
+ "dependencies": {
+ "node-modules-regexp": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz",
+ "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/please-upgrade-node": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+ "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+ "dev": true,
+ "dependencies": {
+ "semver-compare": "^1.0.0"
+ }
+ },
+ "node_modules/posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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/prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "26.6.2",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz",
+ "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^26.6.2",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/pretty-format/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/pretty-format/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/pretty-format/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/private": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/process-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/progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/prompts": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz",
+ "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==",
+ "dev": true,
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.7.2",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+ "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+ "dev": true,
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.8.1"
+ }
+ },
+ "node_modules/prop-types/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "dev": true
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+ "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+ "dependencies": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
+ "dev": true
+ },
+ "node_modules/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/pubsub-js": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/pubsub-js/-/pubsub-js-1.9.3.tgz",
+ "integrity": "sha512-FhYYlPNOywTh7zN38u5AlG67emA47w6JZd7YgdQU1w8gQbZhhIGxVM0AQosdaINHb2ALb+fhfnVyBJAt4D4IzA=="
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pupa": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz",
+ "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==",
+ "dev": true,
+ "dependencies": {
+ "escape-goat": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/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==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "dependencies": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": 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/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "node_modules/read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "dependencies": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/read-pkg-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
+ "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "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/readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/rechoir": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz",
+ "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==",
+ "dev": true,
+ "dependencies": {
+ "resolve": "^1.9.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/reconnecting-websocket": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz",
+ "integrity": "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng=="
+ },
+ "node_modules/redis-commands": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
+ "integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
+ },
+ "node_modules/redis-errors": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
+ "integrity": "sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=",
+ "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": "sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=",
+ "dependencies": {
+ "redis-errors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/redlock": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/redlock/-/redlock-4.2.0.tgz",
+ "integrity": "sha512-j+oQlG+dOwcetUt2WJWttu4CZVeRzUrcVcISFmEmfyuwCVSJ93rDT7YSgg7H7rnxwoRyk/jU46kycVka5tW7jA==",
+ "dependencies": {
+ "bluebird": "^3.7.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/regenerate": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
+ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
+ "dev": true
+ },
+ "node_modules/regenerate-unicode-properties": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+ "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.4.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
+ "dev": true
+ },
+ "node_modules/regenerator-transform": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+ "dev": true,
+ "dependencies": {
+ "babel-runtime": "^6.18.0",
+ "babel-types": "^6.19.0",
+ "private": "^0.1.6"
+ }
+ },
+ "node_modules/regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regexp.prototype.flags": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz",
+ "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==",
+ "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/regexp.prototype.flags/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexp.prototype.flags/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/regexpp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ }
+ },
+ "node_modules/regexpu-core": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+ "dev": true,
+ "dependencies": {
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
+ }
+ },
+ "node_modules/registry-auth-token": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz",
+ "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==",
+ "dev": true,
+ "dependencies": {
+ "rc": "^1.2.8"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/registry-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
+ "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+ "dev": true,
+ "dependencies": {
+ "rc": "^1.2.8"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/regjsgen": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+ "dev": true
+ },
+ "node_modules/regjsparser": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+ "dev": true,
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/regjsparser/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/repeat-element": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
+ "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "dev": true,
+ "dependencies": {
+ "is-finite": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-package-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
+ "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk=",
+ "dev": true
+ },
+ "node_modules/resolve": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+ "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+ "dev": true,
+ "dependencies": {
+ "path-parse": "^1.0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-cwd/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-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-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "deprecated": "https://github.com/lydell/resolve-url#deprecated",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "dependencies": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "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": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "6.6.7",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
+ "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^1.9.0"
+ },
+ "engines": {
+ "npm": ">=2.0.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/safe-json-stringify": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz",
+ "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==",
+ "optional": true
+ },
+ "node_modules/safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "ret": "~0.1.10"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/saslprep": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
+ "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
+ "optional": true,
+ "dependencies": {
+ "sparse-bitfield": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/saxes": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+ "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+ "dev": true,
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 8.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+ "dev": true
+ },
+ "node_modules/semver-diff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
+ "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/semver-diff/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "dependencies": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/set-value/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ },
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "dependencies": {
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "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/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "node_modules/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": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/slug": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/slug/-/slug-0.9.4.tgz",
+ "integrity": "sha512-3YHq0TeJ4+AIFbJm+4UWSQs5A1mmeWOTQqydW3OoPmQfNKxlO96NDRTIrp+TBkmvEsEFrd+Z/LXw8OD/6OlZ5g==",
+ "dependencies": {
+ "unicode": ">= 0.3.1"
+ },
+ "bin": {
+ "slug": "bin/slug.js"
+ }
+ },
+ "node_modules/snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-util/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-list-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+ "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw=="
+ },
+ "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==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-url": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
+ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/sparse-bitfield": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+ "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
+ "optional": true,
+ "dependencies": {
+ "memory-pager": "^1.0.2"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz",
+ "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",
+ "dev": true
+ },
+ "node_modules/split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "extend-shallow": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/stack-utils/node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/static-extend/node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "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/string-argv": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
+ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-natural-compare": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz",
+ "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==",
+ "dev": true
+ },
+ "node_modules/string-width": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
+ "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.matchall": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz",
+ "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.2",
+ "get-intrinsic": "^1.1.1",
+ "has-symbols": "^1.0.2",
+ "internal-slot": "^1.0.3",
+ "regexp.prototype.flags": "^1.3.1",
+ "side-channel": "^1.0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/es-abstract": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz",
+ "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.2",
+ "is-callable": "^1.2.3",
+ "is-negative-zero": "^2.0.1",
+ "is-regex": "^1.1.3",
+ "is-string": "^1.0.6",
+ "object-inspect": "^1.10.3",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.2",
+ "string.prototype.trimend": "^1.0.4",
+ "string.prototype.trimstart": "^1.0.4",
+ "unbox-primitive": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/get-intrinsic": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+ "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/is-callable": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz",
+ "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/is-regex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz",
+ "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/is-string": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz",
+ "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/object-inspect": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
+ "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/string.prototype.trimend": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
+ "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.matchall/node_modules/string.prototype.trimstart": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
+ "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimend": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+ "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimstart": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+ "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.5"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/stringify-object": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
+ "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
+ "dev": true,
+ "dependencies": {
+ "get-own-enumerable-property-symbols": "^3.0.0",
+ "is-obj": "^1.0.1",
+ "is-regexp": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dependencies": {
+ "ansi-regex": "^5.0.0"
+ },
+ "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": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/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/supports-hyperlinks": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz",
+ "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true
+ },
+ "node_modules/table": {
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz",
+ "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^8.0.1",
+ "lodash.clonedeep": "^4.5.0",
+ "lodash.truncate": "^4.4.2",
+ "slice-ansi": "^4.0.0",
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/table/node_modules/ajv": {
+ "version": "8.6.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz",
+ "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/table/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/tapable": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
+ "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/term-size": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
+ "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terminal-link": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
+ "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^4.2.1",
+ "supports-hyperlinks": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz",
+ "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==",
+ "dependencies": {
+ "commander": "^2.20.0",
+ "source-map": "~0.7.2",
+ "source-map-support": "~0.5.19"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz",
+ "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==",
+ "dependencies": {
+ "jest-worker": "^27.0.2",
+ "p-limit": "^3.1.0",
+ "schema-utils": "^3.0.0",
+ "serialize-javascript": "^6.0.0",
+ "source-map": "^0.6.1",
+ "terser": "^5.7.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ }
+ },
+ "node_modules/terser-webpack-plugin/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==",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz",
+ "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==",
+ "dependencies": {
+ "@types/json-schema": "^7.0.7",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
+ "node_modules/terser/node_modules/source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "node_modules/throat": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz",
+ "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==",
+ "dev": true
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
+ "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
+ "dev": true
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-object-path/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "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/tough-cookie": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
+ "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
+ "dev": true,
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.1.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
+ "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
+ "dev": true,
+ "dependencies": {
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/trim-right": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/tsconfig-paths": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
+ "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==",
+ "dev": true,
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.1",
+ "minimist": "^1.2.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
+ "node_modules/tsutils": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+ "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^1.8.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+ }
+ },
+ "node_modules/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-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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/typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "dependencies": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "node_modules/unbox-primitive": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
+ "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has-bigints": "^1.0.1",
+ "has-symbols": "^1.0.2",
+ "which-boxed-primitive": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/unbox-primitive/node_modules/has-symbols": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
+ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/undefsafe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
+ "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^2.2.0"
+ }
+ },
+ "node_modules/unicode": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/unicode/-/unicode-13.0.0.tgz",
+ "integrity": "sha512-osNPLT4Lqna/sV6DQikrB8m4WxR61/k0fnhfKnkPGcZImczW3IysRXvWxfdqGUjh0Ju2o/tGGgu46mlfc/cpZw==",
+ "engines": {
+ "node": ">= 0.8.x"
+ }
+ },
+ "node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+ "dev": true,
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^1.0.4",
+ "unicode-property-aliases-ecmascript": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-match-property-value-ecmascript": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+ "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicode-property-aliases-ecmascript": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "dev": true,
+ "dependencies": {
+ "crypto-random-string": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "isarray": "1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=4",
+ "yarn": "*"
+ }
+ },
+ "node_modules/update-notifier": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz",
+ "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==",
+ "dev": true,
+ "dependencies": {
+ "boxen": "^4.2.0",
+ "chalk": "^3.0.0",
+ "configstore": "^5.0.1",
+ "has-yarn": "^2.1.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^2.0.0",
+ "is-installed-globally": "^0.3.1",
+ "is-npm": "^4.0.0",
+ "is-yarn-global": "^0.3.0",
+ "latest-version": "^5.0.0",
+ "pupa": "^2.0.1",
+ "semver-diff": "^3.1.1",
+ "xdg-basedir": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/yeoman/update-notifier?sponsor=1"
+ }
+ },
+ "node_modules/update-notifier/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/update-notifier/node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/update-notifier/node_modules/ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "node_modules/update-notifier/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/update-notifier/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/update-notifier/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/update-notifier/node_modules/is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "dependencies": {
+ "ci-info": "^2.0.0"
+ },
+ "bin": {
+ "is-ci": "bin.js"
+ }
+ },
+ "node_modules/update-notifier/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/uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "deprecated": "Please see https://github.com/lydell/urix#deprecated",
+ "dev": true,
+ "optional": true
+ },
+ "node_modules/url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
+ "dependencies": {
+ "prepend-http": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/v8-compile-cache": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+ "dev": true
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz",
+ "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0",
+ "source-map": "^0.7.3"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/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/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/w3c-hr-time": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "dev": true,
+ "dependencies": {
+ "browser-process-hrtime": "^1.0.0"
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
+ "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
+ "dev": true,
+ "dependencies": {
+ "xml-name-validator": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/walker": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
+ "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+ "dev": true,
+ "dependencies": {
+ "makeerror": "1.0.x"
+ }
+ },
+ "node_modules/watchpack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz",
+ "integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==",
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
+ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.4"
+ }
+ },
+ "node_modules/webpack": {
+ "version": "5.44.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.44.0.tgz",
+ "integrity": "sha512-I1S1w4QLoKmH19pX6YhYN0NiSXaWY8Ou00oA+aMcr9IUGeF5azns+IKBkfoAAG9Bu5zOIzZt/mN35OffBya8AQ==",
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.0",
+ "@types/estree": "^0.0.50",
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/wasm-edit": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "acorn": "^8.4.1",
+ "browserslist": "^4.14.5",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.8.0",
+ "es-module-lexer": "^0.7.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.4",
+ "json-parse-better-errors": "^1.0.2",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.0.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.1.3",
+ "watchpack": "^2.2.0",
+ "webpack-sources": "^2.3.0"
+ },
+ "bin": {
+ "webpack": "bin/webpack.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependenciesMeta": {
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli": {
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.2.tgz",
+ "integrity": "sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw==",
+ "dev": true,
+ "dependencies": {
+ "@discoveryjs/json-ext": "^0.5.0",
+ "@webpack-cli/configtest": "^1.0.4",
+ "@webpack-cli/info": "^1.3.0",
+ "@webpack-cli/serve": "^1.5.1",
+ "colorette": "^1.2.1",
+ "commander": "^7.0.0",
+ "execa": "^5.0.0",
+ "fastest-levenshtein": "^1.0.12",
+ "import-local": "^3.0.2",
+ "interpret": "^2.2.0",
+ "rechoir": "^0.7.0",
+ "v8-compile-cache": "^2.2.0",
+ "webpack-merge": "^5.7.3"
+ },
+ "bin": {
+ "webpack-cli": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "peerDependencies": {
+ "webpack": "4.x.x || 5.x.x"
+ },
+ "peerDependenciesMeta": {
+ "@webpack-cli/generators": {
+ "optional": true
+ },
+ "@webpack-cli/migrate": {
+ "optional": true
+ },
+ "webpack-bundle-analyzer": {
+ "optional": true
+ },
+ "webpack-dev-server": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-cli/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/webpack-merge": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
+ "dev": true,
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz",
+ "integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==",
+ "dependencies": {
+ "source-list-map": "^2.0.1",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack/node_modules/acorn": {
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
+ "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/webpack/node_modules/browserslist": {
+ "version": "4.16.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
+ "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001219",
+ "colorette": "^1.2.2",
+ "electron-to-chromium": "^1.3.723",
+ "escalade": "^3.1.1",
+ "node-releases": "^1.1.71"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ }
+ },
+ "node_modules/webpack/node_modules/caniuse-lite": {
+ "version": "1.0.30001243",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
+ "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ }
+ },
+ "node_modules/webpack/node_modules/electron-to-chromium": {
+ "version": "1.3.772",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
+ "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA=="
+ },
+ "node_modules/webpack/node_modules/schema-utils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz",
+ "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==",
+ "dependencies": {
+ "@types/json-schema": "^7.0.7",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+ "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+ "dev": true,
+ "dependencies": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "node_modules/whatwg-fetch": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
+ "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA=="
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+ "dev": true
+ },
+ "node_modules/whatwg-url": {
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+ "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.7.0",
+ "tr46": "^2.1.0",
+ "webidl-conversions": "^6.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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/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/widest-line": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+ "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wildcard": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz",
+ "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==",
+ "dev": true
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "node_modules/write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "node_modules/ws": {
+ "version": "7.5.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
+ "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xdg-basedir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
+ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ },
"dependencies": {
"@babel/cli": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.3.tgz",
- "integrity": "sha512-zU4JLvwk32ay1lhhyGfqiRUSPoltVDjhYkA3aQq8+Yby9z30s/EsFw1EPOHxWG9YZo2pAGfgdRNeHZQAYU5m9A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.14.5.tgz",
+ "integrity": "sha512-poegjhRvXHWO0EAsnYajwYZuqcz7gyfxwfaecUESxDujrqOivf3zrjFbub8IJkrqEaz3fvJWh001EzxBub54fg==",
"dev": true,
"requires": {
- "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents",
+ "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.2",
"chokidar": "^3.4.0",
"commander": "^4.0.1",
"convert-source-map": "^1.1.0",
@@ -39,26 +21879,26 @@
}
},
"@babel/compat-data": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz",
- "integrity": "sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz",
+ "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==",
"dev": true
},
"@babel/core": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz",
- "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.3",
- "@babel/helper-compilation-targets": "^7.13.16",
- "@babel/helper-module-transforms": "^7.14.2",
- "@babel/helpers": "^7.14.0",
- "@babel/parser": "^7.14.3",
- "@babel/template": "^7.12.13",
- "@babel/traverse": "^7.14.2",
- "@babel/types": "^7.14.2",
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz",
+ "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helpers": "^7.14.6",
+ "@babel/parser": "^7.14.6",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -68,118 +21908,119 @@
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/generator": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
- "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.2",
+ "@babel/types": "^7.14.5",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/traverse": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
- "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.2",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.14.2",
- "@babel/types": "^7.14.2",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -245,68 +22086,68 @@
}
},
"@babel/helper-annotate-as-pure": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz",
- "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz",
+ "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-builder-binary-assignment-operator-visitor": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz",
- "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz",
+ "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==",
"dev": true,
"requires": {
- "@babel/helper-explode-assignable-expression": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/helper-explode-assignable-expression": "^7.14.5",
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-compilation-targets": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz",
- "integrity": "sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz",
+ "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==",
"dev": true,
"requires": {
- "@babel/compat-data": "^7.14.4",
- "@babel/helper-validator-option": "^7.12.17",
+ "@babel/compat-data": "^7.14.5",
+ "@babel/helper-validator-option": "^7.14.5",
"browserslist": "^4.16.6",
"semver": "^6.3.0"
},
@@ -325,15 +22166,15 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001234",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz",
- "integrity": "sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA==",
+ "version": "1.0.30001243",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
+ "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==",
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.749",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz",
- "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==",
+ "version": "1.3.772",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
+ "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==",
"dev": true
},
"semver": {
@@ -345,110 +22186,110 @@
}
},
"@babel/helper-create-class-features-plugin": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz",
- "integrity": "sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw==",
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz",
+ "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.12.13",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-member-expression-to-functions": "^7.13.12",
- "@babel/helper-optimise-call-expression": "^7.12.13",
- "@babel/helper-replace-supers": "^7.14.4",
- "@babel/helper-split-export-declaration": "^7.12.13"
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-member-expression-to-functions": "^7.14.5",
+ "@babel/helper-optimise-call-expression": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-create-regexp-features-plugin": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz",
- "integrity": "sha512-JIB2+XJrb7v3zceV2XzDhGIB902CmKGSpSl4q2C6agU9SNLG/2V1RtFRGPG1Ajh9STj3+q6zJMOC+N/pp2P9DA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz",
+ "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.12.13",
+ "@babel/helper-annotate-as-pure": "^7.14.5",
"regexpu-core": "^4.7.1"
},
"dependencies": {
@@ -506,127 +22347,128 @@
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/generator": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
- "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.2",
+ "@babel/types": "^7.14.5",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-module-imports": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
- "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz",
+ "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.13.12"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/traverse": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
- "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.2",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.14.2",
- "@babel/types": "^7.14.2",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -653,27 +22495,27 @@
}
},
"@babel/helper-explode-assignable-expression": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz",
- "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz",
+ "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.13.0"
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
@@ -726,169 +22568,54 @@
}
},
"@babel/helper-hoist-variables": {
- "version": "7.13.16",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz",
- "integrity": "sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz",
+ "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==",
"dev": true,
"requires": {
- "@babel/traverse": "^7.13.15",
- "@babel/types": "^7.13.16"
+ "@babel/types": "^7.14.5"
},
"dependencies": {
- "@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
- "dev": true,
- "requires": {
- "@babel/highlight": "^7.12.13"
- }
- },
- "@babel/generator": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
- "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
- "dev": true,
- "requires": {
- "@babel/types": "^7.14.2",
- "jsesc": "^2.5.1",
- "source-map": "^0.5.0"
- }
- },
- "@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
- "dev": true,
- "requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
- }
- },
- "@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
- "dev": true,
- "requires": {
- "@babel/types": "^7.12.13"
- }
- },
- "@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
- "dev": true,
- "requires": {
- "@babel/types": "^7.12.13"
- }
- },
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
- "dev": true
- },
- "@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
- "dev": true,
- "requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
- "chalk": "^2.0.0",
- "js-tokens": "^4.0.0"
- }
- },
- "@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
- "@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
- }
- },
- "@babel/traverse": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
- "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.2",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.14.2",
- "@babel/types": "^7.14.2",
- "debug": "^4.1.0",
- "globals": "^11.1.0"
- }
- },
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
- },
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "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
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
}
}
},
"@babel/helper-member-expression-to-functions": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
- "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz",
+ "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==",
"dev": true,
"requires": {
- "@babel/types": "^7.13.12"
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
@@ -904,143 +22631,144 @@
}
},
"@babel/helper-module-transforms": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz",
- "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==",
- "dev": true,
- "requires": {
- "@babel/helper-module-imports": "^7.13.12",
- "@babel/helper-replace-supers": "^7.13.12",
- "@babel/helper-simple-access": "^7.13.12",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/helper-validator-identifier": "^7.14.0",
- "@babel/template": "^7.12.13",
- "@babel/traverse": "^7.14.2",
- "@babel/types": "^7.14.2"
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz",
+ "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-simple-access": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/generator": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
- "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.2",
+ "@babel/types": "^7.14.5",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-module-imports": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
- "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz",
+ "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.13.12"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/traverse": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
- "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.2",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.14.2",
- "@babel/types": "^7.14.2",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
},
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -1061,192 +22789,193 @@
}
},
"@babel/helper-optimise-call-expression": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz",
- "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz",
+ "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-plugin-utils": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
- "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz",
+ "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==",
"dev": true
},
"@babel/helper-remap-async-to-generator": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz",
- "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz",
+ "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.12.13",
- "@babel/helper-wrap-function": "^7.13.0",
- "@babel/types": "^7.13.0"
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-wrap-function": "^7.14.5",
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-replace-supers": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz",
- "integrity": "sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz",
+ "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==",
"dev": true,
"requires": {
- "@babel/helper-member-expression-to-functions": "^7.13.12",
- "@babel/helper-optimise-call-expression": "^7.12.13",
- "@babel/traverse": "^7.14.2",
- "@babel/types": "^7.14.4"
+ "@babel/helper-member-expression-to-functions": "^7.14.5",
+ "@babel/helper-optimise-call-expression": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/generator": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
- "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.2",
+ "@babel/types": "^7.14.5",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/traverse": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
- "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.2",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.14.2",
- "@babel/types": "^7.14.2",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -1267,54 +22996,54 @@
}
},
"@babel/helper-simple-access": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz",
- "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz",
+ "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==",
"dev": true,
"requires": {
- "@babel/types": "^7.13.12"
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.12.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
- "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz",
+ "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.1"
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
@@ -1349,136 +23078,137 @@
"dev": true
},
"@babel/helper-validator-option": {
- "version": "7.12.17",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
- "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz",
+ "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==",
"dev": true
},
"@babel/helper-wrap-function": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz",
- "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz",
+ "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==",
"dev": true,
"requires": {
- "@babel/helper-function-name": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/traverse": "^7.13.0",
- "@babel/types": "^7.13.0"
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/generator": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
- "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.2",
+ "@babel/types": "^7.14.5",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/traverse": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
- "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.2",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.14.2",
- "@babel/types": "^7.14.2",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -1499,129 +23229,130 @@
}
},
"@babel/helpers": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz",
- "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==",
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz",
+ "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==",
"dev": true,
"requires": {
- "@babel/template": "^7.12.13",
- "@babel/traverse": "^7.14.0",
- "@babel/types": "^7.14.0"
+ "@babel/template": "^7.14.5",
+ "@babel/traverse": "^7.14.5",
+ "@babel/types": "^7.14.5"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/generator": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
- "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz",
+ "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==",
"dev": true,
"requires": {
- "@babel/types": "^7.14.2",
+ "@babel/types": "^7.14.5",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/traverse": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
- "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/generator": "^7.14.2",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-split-export-declaration": "^7.12.13",
- "@babel/parser": "^7.14.2",
- "@babel/types": "^7.14.2",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz",
+ "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.14.5",
+ "@babel/generator": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
+ "@babel/parser": "^7.14.7",
+ "@babel/types": "^7.14.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -1659,172 +23390,172 @@
"dev": true
},
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz",
- "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz",
+ "integrity": "sha512-ZoJS2XCKPBfTmL122iP6NM9dOg+d4lc9fFk3zxc8iDjvt8Pk4+TlsHSKhIPf6X+L5ORCdBzqMZDjL/WHj7WknQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
- "@babel/plugin-proposal-optional-chaining": "^7.13.12"
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5",
+ "@babel/plugin-proposal-optional-chaining": "^7.14.5"
}
},
"@babel/plugin-proposal-async-generator-functions": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz",
- "integrity": "sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz",
+ "integrity": "sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-remap-async-to-generator": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-remap-async-to-generator": "^7.14.5",
"@babel/plugin-syntax-async-generators": "^7.8.4"
}
},
"@babel/plugin-proposal-class-properties": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz",
- "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz",
+ "integrity": "sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg==",
"dev": true,
"requires": {
- "@babel/helper-create-class-features-plugin": "^7.13.0",
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-proposal-class-static-block": {
- "version": "7.14.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.3.tgz",
- "integrity": "sha512-HEjzp5q+lWSjAgJtSluFDrGGosmwTgKwCXdDQZvhKsRlwv3YdkUEqxNrrjesJd+B9E9zvr1PVPVBvhYZ9msjvQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-KBAH5ksEnYHCegqseI5N9skTdxgJdmDoAOc0uXa+4QMYKeZD0w5IARh4FMlTNtaHhbB8v+KzMdTgxMMzsIy6Yg==",
"dev": true,
"requires": {
- "@babel/helper-create-class-features-plugin": "^7.14.3",
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/plugin-syntax-class-static-block": "^7.12.13"
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5"
}
},
"@babel/plugin-proposal-dynamic-import": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz",
- "integrity": "sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz",
+ "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-dynamic-import": "^7.8.3"
}
},
"@babel/plugin-proposal-export-namespace-from": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz",
- "integrity": "sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz",
+ "integrity": "sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-export-namespace-from": "^7.8.3"
}
},
"@babel/plugin-proposal-json-strings": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz",
- "integrity": "sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz",
+ "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-json-strings": "^7.8.3"
}
},
"@babel/plugin-proposal-logical-assignment-operators": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz",
- "integrity": "sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz",
+ "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
}
},
"@babel/plugin-proposal-nullish-coalescing-operator": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz",
- "integrity": "sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz",
+ "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
}
},
"@babel/plugin-proposal-numeric-separator": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz",
- "integrity": "sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz",
+ "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-numeric-separator": "^7.10.4"
}
},
"@babel/plugin-proposal-object-rest-spread": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.4.tgz",
- "integrity": "sha512-AYosOWBlyyXEagrPRfLJ1enStufsr7D1+ddpj8OLi9k7B6+NdZ0t/9V7Fh+wJ4g2Jol8z2JkgczYqtWrZd4vbA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz",
+ "integrity": "sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==",
"dev": true,
"requires": {
- "@babel/compat-data": "^7.14.4",
- "@babel/helper-compilation-targets": "^7.14.4",
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/compat-data": "^7.14.7",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
- "@babel/plugin-transform-parameters": "^7.14.2"
+ "@babel/plugin-transform-parameters": "^7.14.5"
}
},
"@babel/plugin-proposal-optional-catch-binding": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz",
- "integrity": "sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz",
+ "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-plugin-utils": "^7.14.5",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
}
},
"@babel/plugin-proposal-optional-chaining": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz",
- "integrity": "sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz",
+ "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5",
"@babel/plugin-syntax-optional-chaining": "^7.8.3"
}
},
"@babel/plugin-proposal-private-methods": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz",
- "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz",
+ "integrity": "sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g==",
"dev": true,
"requires": {
- "@babel/helper-create-class-features-plugin": "^7.13.0",
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-proposal-private-property-in-object": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz",
- "integrity": "sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-62EyfyA3WA0mZiF2e2IV9mc9Ghwxcg8YTu8BS4Wss4Y3PY725OmS9M0qLORbJwLqFtGh+jiE4wAmocK2CTUK2Q==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.12.13",
- "@babel/helper-create-class-features-plugin": "^7.14.0",
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.0"
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-create-class-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
}
},
"@babel/plugin-proposal-unicode-property-regex": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz",
- "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz",
+ "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.12.13",
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-syntax-async-generators": {
@@ -1855,12 +23586,12 @@
}
},
"@babel/plugin-syntax-class-static-block": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz",
- "integrity": "sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-syntax-dynamic-import": {
@@ -1954,459 +23685,459 @@
}
},
"@babel/plugin-syntax-private-property-in-object": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz",
- "integrity": "sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-syntax-top-level-await": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz",
- "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-syntax-typescript": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz",
- "integrity": "sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz",
+ "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-arrow-functions": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz",
- "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz",
+ "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-async-to-generator": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz",
- "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz",
+ "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==",
"dev": true,
"requires": {
- "@babel/helper-module-imports": "^7.12.13",
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-remap-async-to-generator": "^7.13.0"
+ "@babel/helper-module-imports": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-remap-async-to-generator": "^7.14.5"
},
"dependencies": {
"@babel/helper-module-imports": {
- "version": "7.13.12",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
- "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz",
+ "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.13.12"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/plugin-transform-block-scoped-functions": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz",
- "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz",
+ "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-block-scoping": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.4.tgz",
- "integrity": "sha512-5KdpkGxsZlTk+fPleDtGKsA+pon28+ptYmMO8GBSa5fHERCJWAzj50uAfCKBqq42HO+Zot6JF1x37CRprwmN4g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz",
+ "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-classes": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.4.tgz",
- "integrity": "sha512-p73t31SIj6y94RDVX57rafVjttNr8MvKEgs5YFatNB/xC68zM3pyosuOEcQmYsYlyQaGY9R7rAULVRcat5FKJQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz",
+ "integrity": "sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.12.13",
- "@babel/helper-function-name": "^7.14.2",
- "@babel/helper-optimise-call-expression": "^7.12.13",
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-replace-supers": "^7.14.4",
- "@babel/helper-split-export-declaration": "^7.12.13",
+ "@babel/helper-annotate-as-pure": "^7.14.5",
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-optimise-call-expression": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5",
+ "@babel/helper-split-export-declaration": "^7.14.5",
"globals": "^11.1.0"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
- "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz",
+ "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/plugin-transform-computed-properties": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz",
- "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz",
+ "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-destructuring": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.4.tgz",
- "integrity": "sha512-JyywKreTCGTUsL1OKu1A3ms/R1sTP0WxbpXlALeGzF53eB3bxtNkYdMj9SDgK7g6ImPy76J5oYYKoTtQImlhQA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz",
+ "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-dotall-regex": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz",
- "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz",
+ "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.12.13",
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-duplicate-keys": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz",
- "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz",
+ "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-exponentiation-operator": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz",
- "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz",
+ "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==",
"dev": true,
"requires": {
- "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13",
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-for-of": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz",
- "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz",
+ "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-function-name": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz",
- "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz",
+ "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==",
"dev": true,
"requires": {
- "@babel/helper-function-name": "^7.12.13",
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-function-name": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/helper-function-name": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
- "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz",
+ "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==",
"dev": true,
"requires": {
- "@babel/helper-get-function-arity": "^7.12.13",
- "@babel/template": "^7.12.13",
- "@babel/types": "^7.14.2"
+ "@babel/helper-get-function-arity": "^7.14.5",
+ "@babel/template": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-get-function-arity": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
- "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz",
+ "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==",
"dev": true,
"requires": {
- "@babel/types": "^7.12.13"
+ "@babel/types": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz",
- "integrity": "sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
+ "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==",
"dev": true
},
"@babel/template": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
- "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz",
+ "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.12.13",
- "@babel/parser": "^7.12.13",
- "@babel/types": "^7.12.13"
+ "@babel/code-frame": "^7.14.5",
+ "@babel/parser": "^7.14.5",
+ "@babel/types": "^7.14.5"
}
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
}
}
},
"@babel/plugin-transform-literals": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz",
- "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz",
+ "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-member-expression-literals": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz",
- "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz",
+ "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-modules-amd": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz",
- "integrity": "sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz",
+ "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.14.2",
- "@babel/helper-plugin-utils": "^7.13.0",
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
"@babel/plugin-transform-modules-commonjs": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz",
- "integrity": "sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz",
+ "integrity": "sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.14.0",
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-simple-access": "^7.13.12",
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-simple-access": "^7.14.5",
"babel-plugin-dynamic-import-node": "^2.3.3"
}
},
"@babel/plugin-transform-modules-systemjs": {
- "version": "7.13.8",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz",
- "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.14.5.tgz",
+ "integrity": "sha512-mNMQdvBEE5DcMQaL5LbzXFMANrQjd2W7FPzg34Y4yEz7dBgdaC+9B84dSO+/1Wba98zoDbInctCDo4JGxz1VYA==",
"dev": true,
"requires": {
- "@babel/helper-hoist-variables": "^7.13.0",
- "@babel/helper-module-transforms": "^7.13.0",
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-validator-identifier": "^7.12.11",
+ "@babel/helper-hoist-variables": "^7.14.5",
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-validator-identifier": "^7.14.5",
"babel-plugin-dynamic-import-node": "^2.3.3"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
}
}
},
"@babel/plugin-transform-modules-umd": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz",
- "integrity": "sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz",
+ "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.14.0",
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-module-transforms": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz",
- "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz",
+ "integrity": "sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.12.13"
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5"
}
},
"@babel/plugin-transform-new-target": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz",
- "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz",
+ "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-object-super": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz",
- "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz",
+ "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13",
- "@babel/helper-replace-supers": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-replace-supers": "^7.14.5"
}
},
"@babel/plugin-transform-parameters": {
- "version": "7.14.2",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz",
- "integrity": "sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz",
+ "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-property-literals": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz",
- "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz",
+ "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-regenerator": {
- "version": "7.13.15",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz",
- "integrity": "sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz",
+ "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==",
"dev": true,
"requires": {
"regenerator-transform": "^0.14.2"
@@ -2424,108 +24155,108 @@
}
},
"@babel/plugin-transform-reserved-words": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz",
- "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz",
+ "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-shorthand-properties": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz",
- "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz",
+ "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-spread": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz",
- "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==",
+ "version": "7.14.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz",
+ "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5"
}
},
"@babel/plugin-transform-sticky-regex": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz",
- "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz",
+ "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-template-literals": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz",
- "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz",
+ "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-typeof-symbol": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz",
- "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz",
+ "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-unicode-escapes": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz",
- "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz",
+ "integrity": "sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/plugin-transform-unicode-regex": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz",
- "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz",
+ "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==",
"dev": true,
"requires": {
- "@babel/helper-create-regexp-features-plugin": "^7.12.13",
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-create-regexp-features-plugin": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5"
}
},
"@babel/preset-env": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.4.tgz",
- "integrity": "sha512-GwMMsuAnDtULyOtuxHhzzuSRxFeP0aR/LNzrHRzP8y6AgDNgqnrfCCBm/1cRdTU75tRs28Eh76poHLcg9VF0LA==",
- "dev": true,
- "requires": {
- "@babel/compat-data": "^7.14.4",
- "@babel/helper-compilation-targets": "^7.14.4",
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/helper-validator-option": "^7.12.17",
- "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12",
- "@babel/plugin-proposal-async-generator-functions": "^7.14.2",
- "@babel/plugin-proposal-class-properties": "^7.13.0",
- "@babel/plugin-proposal-class-static-block": "^7.14.3",
- "@babel/plugin-proposal-dynamic-import": "^7.14.2",
- "@babel/plugin-proposal-export-namespace-from": "^7.14.2",
- "@babel/plugin-proposal-json-strings": "^7.14.2",
- "@babel/plugin-proposal-logical-assignment-operators": "^7.14.2",
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.2",
- "@babel/plugin-proposal-numeric-separator": "^7.14.2",
- "@babel/plugin-proposal-object-rest-spread": "^7.14.4",
- "@babel/plugin-proposal-optional-catch-binding": "^7.14.2",
- "@babel/plugin-proposal-optional-chaining": "^7.14.2",
- "@babel/plugin-proposal-private-methods": "^7.13.0",
- "@babel/plugin-proposal-private-property-in-object": "^7.14.0",
- "@babel/plugin-proposal-unicode-property-regex": "^7.12.13",
+ "version": "7.14.7",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.7.tgz",
+ "integrity": "sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.14.7",
+ "@babel/helper-compilation-targets": "^7.14.5",
+ "@babel/helper-plugin-utils": "^7.14.5",
+ "@babel/helper-validator-option": "^7.14.5",
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.14.5",
+ "@babel/plugin-proposal-async-generator-functions": "^7.14.7",
+ "@babel/plugin-proposal-class-properties": "^7.14.5",
+ "@babel/plugin-proposal-class-static-block": "^7.14.5",
+ "@babel/plugin-proposal-dynamic-import": "^7.14.5",
+ "@babel/plugin-proposal-export-namespace-from": "^7.14.5",
+ "@babel/plugin-proposal-json-strings": "^7.14.5",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.14.5",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5",
+ "@babel/plugin-proposal-numeric-separator": "^7.14.5",
+ "@babel/plugin-proposal-object-rest-spread": "^7.14.7",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.14.5",
+ "@babel/plugin-proposal-optional-chaining": "^7.14.5",
+ "@babel/plugin-proposal-private-methods": "^7.14.5",
+ "@babel/plugin-proposal-private-property-in-object": "^7.14.5",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.14.5",
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-class-properties": "^7.12.13",
- "@babel/plugin-syntax-class-static-block": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-export-namespace-from": "^7.8.3",
"@babel/plugin-syntax-json-strings": "^7.8.3",
@@ -2535,62 +24266,62 @@
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-private-property-in-object": "^7.14.0",
- "@babel/plugin-syntax-top-level-await": "^7.12.13",
- "@babel/plugin-transform-arrow-functions": "^7.13.0",
- "@babel/plugin-transform-async-to-generator": "^7.13.0",
- "@babel/plugin-transform-block-scoped-functions": "^7.12.13",
- "@babel/plugin-transform-block-scoping": "^7.14.4",
- "@babel/plugin-transform-classes": "^7.14.4",
- "@babel/plugin-transform-computed-properties": "^7.13.0",
- "@babel/plugin-transform-destructuring": "^7.14.4",
- "@babel/plugin-transform-dotall-regex": "^7.12.13",
- "@babel/plugin-transform-duplicate-keys": "^7.12.13",
- "@babel/plugin-transform-exponentiation-operator": "^7.12.13",
- "@babel/plugin-transform-for-of": "^7.13.0",
- "@babel/plugin-transform-function-name": "^7.12.13",
- "@babel/plugin-transform-literals": "^7.12.13",
- "@babel/plugin-transform-member-expression-literals": "^7.12.13",
- "@babel/plugin-transform-modules-amd": "^7.14.2",
- "@babel/plugin-transform-modules-commonjs": "^7.14.0",
- "@babel/plugin-transform-modules-systemjs": "^7.13.8",
- "@babel/plugin-transform-modules-umd": "^7.14.0",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13",
- "@babel/plugin-transform-new-target": "^7.12.13",
- "@babel/plugin-transform-object-super": "^7.12.13",
- "@babel/plugin-transform-parameters": "^7.14.2",
- "@babel/plugin-transform-property-literals": "^7.12.13",
- "@babel/plugin-transform-regenerator": "^7.13.15",
- "@babel/plugin-transform-reserved-words": "^7.12.13",
- "@babel/plugin-transform-shorthand-properties": "^7.12.13",
- "@babel/plugin-transform-spread": "^7.13.0",
- "@babel/plugin-transform-sticky-regex": "^7.12.13",
- "@babel/plugin-transform-template-literals": "^7.13.0",
- "@babel/plugin-transform-typeof-symbol": "^7.12.13",
- "@babel/plugin-transform-unicode-escapes": "^7.12.13",
- "@babel/plugin-transform-unicode-regex": "^7.12.13",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5",
+ "@babel/plugin-transform-arrow-functions": "^7.14.5",
+ "@babel/plugin-transform-async-to-generator": "^7.14.5",
+ "@babel/plugin-transform-block-scoped-functions": "^7.14.5",
+ "@babel/plugin-transform-block-scoping": "^7.14.5",
+ "@babel/plugin-transform-classes": "^7.14.5",
+ "@babel/plugin-transform-computed-properties": "^7.14.5",
+ "@babel/plugin-transform-destructuring": "^7.14.7",
+ "@babel/plugin-transform-dotall-regex": "^7.14.5",
+ "@babel/plugin-transform-duplicate-keys": "^7.14.5",
+ "@babel/plugin-transform-exponentiation-operator": "^7.14.5",
+ "@babel/plugin-transform-for-of": "^7.14.5",
+ "@babel/plugin-transform-function-name": "^7.14.5",
+ "@babel/plugin-transform-literals": "^7.14.5",
+ "@babel/plugin-transform-member-expression-literals": "^7.14.5",
+ "@babel/plugin-transform-modules-amd": "^7.14.5",
+ "@babel/plugin-transform-modules-commonjs": "^7.14.5",
+ "@babel/plugin-transform-modules-systemjs": "^7.14.5",
+ "@babel/plugin-transform-modules-umd": "^7.14.5",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.14.7",
+ "@babel/plugin-transform-new-target": "^7.14.5",
+ "@babel/plugin-transform-object-super": "^7.14.5",
+ "@babel/plugin-transform-parameters": "^7.14.5",
+ "@babel/plugin-transform-property-literals": "^7.14.5",
+ "@babel/plugin-transform-regenerator": "^7.14.5",
+ "@babel/plugin-transform-reserved-words": "^7.14.5",
+ "@babel/plugin-transform-shorthand-properties": "^7.14.5",
+ "@babel/plugin-transform-spread": "^7.14.6",
+ "@babel/plugin-transform-sticky-regex": "^7.14.5",
+ "@babel/plugin-transform-template-literals": "^7.14.5",
+ "@babel/plugin-transform-typeof-symbol": "^7.14.5",
+ "@babel/plugin-transform-unicode-escapes": "^7.14.5",
+ "@babel/plugin-transform-unicode-regex": "^7.14.5",
"@babel/preset-modules": "^0.1.4",
- "@babel/types": "^7.14.4",
- "babel-plugin-polyfill-corejs2": "^0.2.0",
- "babel-plugin-polyfill-corejs3": "^0.2.0",
- "babel-plugin-polyfill-regenerator": "^0.2.0",
- "core-js-compat": "^3.9.0",
+ "@babel/types": "^7.14.5",
+ "babel-plugin-polyfill-corejs2": "^0.2.2",
+ "babel-plugin-polyfill-corejs3": "^0.2.2",
+ "babel-plugin-polyfill-regenerator": "^0.2.2",
+ "core-js-compat": "^3.15.0",
"semver": "^6.3.0"
},
"dependencies": {
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/types": {
- "version": "7.14.4",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz",
- "integrity": "sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
+ "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"to-fast-properties": "^2.0.0"
}
},
@@ -2744,18 +24475,18 @@
},
"dependencies": {
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
},
"globals": {
- "version": "13.9.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz",
- "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==",
+ "version": "13.10.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
+ "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -2766,15 +24497,43 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
+ }
+ }
+ },
+ "@humanwhocodes/config-array": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
+ "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+ "dev": true,
+ "requires": {
+ "@humanwhocodes/object-schema": "^1.2.0",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
},
- "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==",
+ "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/object-schema": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
+ "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
+ "dev": true
+ },
"@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -2852,23 +24611,23 @@
"dev": true
},
"@jest/console": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.2.tgz",
- "integrity": "sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.0.6.tgz",
+ "integrity": "sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
"chalk": "^4.0.0",
- "jest-message-util": "^27.0.2",
- "jest-util": "^27.0.2",
+ "jest-message-util": "^27.0.6",
+ "jest-util": "^27.0.6",
"slash": "^3.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -2879,9 +24638,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -2945,35 +24704,35 @@
}
},
"@jest/core": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.4.tgz",
- "integrity": "sha512-+dsmV8VUs1h/Szb+rEWk8xBM1fp1I///uFy9nk3wXGvRsF2lBp8EVPmtWc+QFRb3MY2b7u2HbkGF1fzoDzQTLA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.0.6.tgz",
+ "integrity": "sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow==",
"dev": true,
"requires": {
- "@jest/console": "^27.0.2",
- "@jest/reporters": "^27.0.4",
- "@jest/test-result": "^27.0.2",
- "@jest/transform": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/console": "^27.0.6",
+ "@jest/reporters": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
"emittery": "^0.8.1",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-changed-files": "^27.0.2",
- "jest-config": "^27.0.4",
- "jest-haste-map": "^27.0.2",
- "jest-message-util": "^27.0.2",
- "jest-regex-util": "^27.0.1",
- "jest-resolve": "^27.0.4",
- "jest-resolve-dependencies": "^27.0.4",
- "jest-runner": "^27.0.4",
- "jest-runtime": "^27.0.4",
- "jest-snapshot": "^27.0.4",
- "jest-util": "^27.0.2",
- "jest-validate": "^27.0.2",
- "jest-watcher": "^27.0.2",
+ "jest-changed-files": "^27.0.6",
+ "jest-config": "^27.0.6",
+ "jest-haste-map": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-resolve-dependencies": "^27.0.6",
+ "jest-runner": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
+ "jest-watcher": "^27.0.6",
"micromatch": "^4.0.4",
"p-each-series": "^2.1.0",
"rimraf": "^3.0.0",
@@ -2982,9 +24741,9 @@
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -2995,9 +24754,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -3119,21 +24878,21 @@
}
},
"@jest/environment": {
- "version": "27.0.3",
- "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.3.tgz",
- "integrity": "sha512-pN9m7fbKsop5vc3FOfH8NF7CKKdRbEZzcxfIo1n2TT6ucKWLFq0P6gCJH0GpnQp036++yY9utHOxpeT1WnkWTA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.0.6.tgz",
+ "integrity": "sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg==",
"dev": true,
"requires": {
- "@jest/fake-timers": "^27.0.3",
- "@jest/types": "^27.0.2",
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
- "jest-mock": "^27.0.3"
+ "jest-mock": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -3144,9 +24903,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -3204,23 +24963,23 @@
}
},
"@jest/fake-timers": {
- "version": "27.0.3",
- "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.3.tgz",
- "integrity": "sha512-fQ+UCKRIYKvTCEOyKPnaPnomLATIhMnHC/xPZ7yT1Uldp7yMgMxoYIFidDbpSTgB79+/U+FgfoD30c6wg3IUjA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.0.6.tgz",
+ "integrity": "sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"@sinonjs/fake-timers": "^7.0.2",
"@types/node": "*",
- "jest-message-util": "^27.0.2",
- "jest-mock": "^27.0.3",
- "jest-util": "^27.0.2"
+ "jest-message-util": "^27.0.6",
+ "jest-mock": "^27.0.6",
+ "jest-util": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -3231,9 +24990,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -3291,20 +25050,20 @@
}
},
"@jest/globals": {
- "version": "27.0.3",
- "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.3.tgz",
- "integrity": "sha512-OzsIuf7uf+QalqAGbjClyezzEcLQkdZ+7PejUrZgDs+okdAK8GwRCGcYCirHvhMBBQh60Jr3NlIGbn/KBPQLEQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.0.6.tgz",
+ "integrity": "sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.3",
- "@jest/types": "^27.0.2",
- "expect": "^27.0.2"
+ "@jest/environment": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "expect": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -3315,9 +25074,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -3375,16 +25134,16 @@
}
},
"@jest/reporters": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.4.tgz",
- "integrity": "sha512-Xa90Nm3JnV0xCe4M6A10M9WuN9krb+WFKxV1A98Y4ePCw40n++r7uxFUNU7DT1i9Behj7fjrAIju9oU0t1QtCg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.0.6.tgz",
+ "integrity": "sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA==",
"dev": true,
"requires": {
"@bcoe/v8-coverage": "^0.2.3",
- "@jest/console": "^27.0.2",
- "@jest/test-result": "^27.0.2",
- "@jest/transform": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/console": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
"chalk": "^4.0.0",
"collect-v8-coverage": "^1.0.0",
"exit": "^0.1.2",
@@ -3395,21 +25154,21 @@
"istanbul-lib-report": "^3.0.0",
"istanbul-lib-source-maps": "^4.0.0",
"istanbul-reports": "^3.0.2",
- "jest-haste-map": "^27.0.2",
- "jest-resolve": "^27.0.4",
- "jest-util": "^27.0.2",
- "jest-worker": "^27.0.2",
+ "jest-haste-map": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-worker": "^27.0.6",
"slash": "^3.0.0",
"source-map": "^0.6.0",
"string-length": "^4.0.1",
"terminal-link": "^2.0.0",
- "v8-to-istanbul": "^7.0.0"
+ "v8-to-istanbul": "^8.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -3420,9 +25179,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -3486,9 +25245,9 @@
}
},
"@jest/source-map": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.1.tgz",
- "integrity": "sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz",
+ "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==",
"dev": true,
"requires": {
"callsites": "^3.0.0",
@@ -3497,21 +25256,21 @@
}
},
"@jest/test-result": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.2.tgz",
- "integrity": "sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.0.6.tgz",
+ "integrity": "sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w==",
"dev": true,
"requires": {
- "@jest/console": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/console": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/istanbul-lib-coverage": "^2.0.0",
"collect-v8-coverage": "^1.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -3522,9 +25281,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -3582,33 +25341,33 @@
}
},
"@jest/test-sequencer": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.4.tgz",
- "integrity": "sha512-6UFEVwdmxYdyNffBxVVZxmXEdBE4riSddXYSnFNH0ELFQFk/bvagizim8WfgJTqF4EKd+j1yFxvhb8BMHfOjSQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz",
+ "integrity": "sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA==",
"dev": true,
"requires": {
- "@jest/test-result": "^27.0.2",
+ "@jest/test-result": "^27.0.6",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^27.0.2",
- "jest-runtime": "^27.0.4"
+ "jest-haste-map": "^27.0.6",
+ "jest-runtime": "^27.0.6"
}
},
"@jest/transform": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.2.tgz",
- "integrity": "sha512-H8sqKlgtDfVog/s9I4GG2XMbi4Ar7RBxjsKQDUhn2XHAi3NG+GoQwWMER+YfantzExbjNqQvqBHzo/G2pfTiPw==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.0.6.tgz",
+ "integrity": "sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"babel-plugin-istanbul": "^6.0.0",
"chalk": "^4.0.0",
"convert-source-map": "^1.4.0",
"fast-json-stable-stringify": "^2.0.0",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^27.0.2",
- "jest-regex-util": "^27.0.1",
- "jest-util": "^27.0.2",
+ "jest-haste-map": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-util": "^27.0.6",
"micromatch": "^4.0.4",
"pirates": "^4.0.1",
"slash": "^3.0.0",
@@ -3617,9 +25376,9 @@
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -3630,9 +25389,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -3809,16 +25568,16 @@
}
},
"@nicolo-ribaudo/chokidar-2": {
- "version": "2.1.8-no-fsevents",
- "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.tgz",
- "integrity": "sha512-+nb9vWloHNNMFHjGofEam3wopE3m1yuambrrd/fnPc+lFOMB9ROTqQlche9ByFWNkdNqfSgR/kkQtQ8DzEWt2w==",
+ "version": "2.1.8-no-fsevents.2",
+ "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.2.tgz",
+ "integrity": "sha512-Fb8WxUFOBQVl+CX4MWet5o7eCc6Pj04rXIwVKZ6h1NnqTo45eOQW6aWyhG25NIODvWFwTDMwBsYxrQ3imxpetg==",
"dev": true,
"optional": true,
"requires": {
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
- "glob-parent": "^3.1.0",
+ "glob-parent": "^5.1.2",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
"is-glob": "^4.0.0",
@@ -3899,9 +25658,9 @@
"integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA=="
},
"@types/babel__core": {
- "version": "7.1.14",
- "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.14.tgz",
- "integrity": "sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==",
+ "version": "7.1.15",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz",
+ "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==",
"dev": true,
"requires": {
"@babel/parser": "^7.1.0",
@@ -3912,18 +25671,18 @@
}
},
"@types/babel__generator": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz",
- "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==",
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz",
+ "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
},
"@types/babel__template": {
- "version": "7.4.0",
- "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz",
- "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
"dev": true,
"requires": {
"@babel/parser": "^7.1.0",
@@ -3931,18 +25690,18 @@
}
},
"@types/babel__traverse": {
- "version": "7.11.1",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.1.tgz",
- "integrity": "sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==",
+ "version": "7.14.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz",
+ "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==",
"dev": true,
"requires": {
"@babel/types": "^7.3.0"
}
},
"@types/body-parser": {
- "version": "1.19.0",
- "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
- "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz",
+ "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==",
"dev": true,
"requires": {
"@types/connect": "*",
@@ -3950,39 +25709,36 @@
}
},
"@types/connect": {
- "version": "3.4.34",
- "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
- "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
+ "version": "3.4.35",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
+ "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/eslint": {
- "version": "7.2.13",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.13.tgz",
- "integrity": "sha512-LKmQCWAlnVHvvXq4oasNUMTJJb2GwSyTY8+1C7OH5ILR8mPLaljv1jxL1bXW3xB3jFbQxTKxJAvI8PyjB09aBg==",
- "dev": true,
+ "version": "7.2.14",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.14.tgz",
+ "integrity": "sha512-pESyhSbUOskqrGcaN+bCXIQDyT5zTaRWfj5ZjjSlMatgGjIn3QQPfocAu4WSabUR7CGyLZ2CQaZyISOEX7/saw==",
"requires": {
"@types/estree": "*",
"@types/json-schema": "*"
}
},
"@types/eslint-scope": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz",
- "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==",
- "dev": true,
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.1.tgz",
+ "integrity": "sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==",
"requires": {
"@types/eslint": "*",
"@types/estree": "*"
}
},
"@types/estree": {
- "version": "0.0.47",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz",
- "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==",
- "dev": true
+ "version": "0.0.50",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz",
+ "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw=="
},
"@types/events": {
"version": "3.0.0",
@@ -3990,9 +25746,9 @@
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
},
"@types/express": {
- "version": "4.17.12",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz",
- "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==",
+ "version": "4.17.13",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz",
+ "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==",
"dev": true,
"requires": {
"@types/body-parser": "*",
@@ -4002,9 +25758,9 @@
}
},
"@types/express-serve-static-core": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz",
- "integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==",
+ "version": "4.17.24",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz",
+ "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==",
"dev": true,
"requires": {
"@types/node": "*",
@@ -4047,18 +25803,18 @@
}
},
"@types/istanbul-reports": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
- "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
"dev": true,
"requires": {
"@types/istanbul-lib-report": "*"
}
},
"@types/jest": {
- "version": "26.0.23",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz",
- "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==",
+ "version": "26.0.24",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz",
+ "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==",
"dev": true,
"requires": {
"jest-diff": "^26.0.0",
@@ -4068,8 +25824,7 @@
"@types/json-schema": {
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz",
- "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==",
- "dev": true
+ "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA=="
},
"@types/json5": {
"version": "0.0.29",
@@ -4089,9 +25844,9 @@
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
},
"@types/node": {
- "version": "15.12.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.1.tgz",
- "integrity": "sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw=="
+ "version": "16.3.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz",
+ "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA=="
},
"@types/parse-json": {
"version": "4.0.0",
@@ -4100,27 +25855,27 @@
"dev": true
},
"@types/prettier": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz",
- "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==",
"dev": true
},
"@types/qs": {
- "version": "6.9.6",
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz",
- "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==",
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
+ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==",
"dev": true
},
"@types/range-parser": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
- "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
+ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==",
"dev": true
},
"@types/serve-static": {
- "version": "1.13.9",
- "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz",
- "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==",
+ "version": "1.13.10",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz",
+ "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==",
"dev": true,
"requires": {
"@types/mime": "^1",
@@ -4133,9 +25888,9 @@
"integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA=="
},
"@types/stack-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz",
- "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
"dev": true
},
"@types/tapable": {
@@ -4175,18 +25930,18 @@
}
},
"@types/yargs": {
- "version": "15.0.9",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.9.tgz",
- "integrity": "sha512-HmU8SeIRhZCWcnRskCs36Q1Q00KBV6Cqh/ora8WN1+22dY07AZdn6Gel8QZ3t26XYPImtcL8WV/eqjhVmMEw4g==",
+ "version": "15.0.14",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
+ "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
}
},
"@types/yargs-parser": {
- "version": "15.0.0",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz",
- "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
+ "version": "20.2.1",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz",
+ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==",
"dev": true
},
"@typescript-eslint/experimental-utils": {
@@ -4279,183 +26034,168 @@
}
},
"@webassemblyjs/ast": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz",
- "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
+ "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
"requires": {
- "@webassemblyjs/helper-numbers": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0"
+ "@webassemblyjs/helper-numbers": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
}
},
"@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz",
- "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==",
- "dev": true
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
+ "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ=="
},
"@webassemblyjs/helper-api-error": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz",
- "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==",
- "dev": true
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
+ "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg=="
},
"@webassemblyjs/helper-buffer": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz",
- "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==",
- "dev": true
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
+ "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA=="
},
"@webassemblyjs/helper-numbers": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz",
- "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
+ "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
"requires": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.0",
- "@webassemblyjs/helper-api-error": "1.11.0",
+ "@webassemblyjs/floating-point-hex-parser": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
"@xtuc/long": "4.2.2"
}
},
"@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz",
- "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==",
- "dev": true
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
+ "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q=="
},
"@webassemblyjs/helper-wasm-section": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz",
- "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
+ "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-buffer": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/wasm-gen": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1"
}
},
"@webassemblyjs/ieee754": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz",
- "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
+ "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
"requires": {
"@xtuc/ieee754": "^1.2.0"
}
},
"@webassemblyjs/leb128": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz",
- "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
+ "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
"requires": {
"@xtuc/long": "4.2.2"
}
},
"@webassemblyjs/utf8": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz",
- "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==",
- "dev": true
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
+ "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ=="
},
"@webassemblyjs/wasm-edit": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz",
- "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
+ "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-buffer": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/helper-wasm-section": "1.11.0",
- "@webassemblyjs/wasm-gen": "1.11.0",
- "@webassemblyjs/wasm-opt": "1.11.0",
- "@webassemblyjs/wasm-parser": "1.11.0",
- "@webassemblyjs/wast-printer": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/helper-wasm-section": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-opt": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "@webassemblyjs/wast-printer": "1.11.1"
}
},
"@webassemblyjs/wasm-gen": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz",
- "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
+ "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/ieee754": "1.11.0",
- "@webassemblyjs/leb128": "1.11.0",
- "@webassemblyjs/utf8": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
}
},
"@webassemblyjs/wasm-opt": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz",
- "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
+ "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-buffer": "1.11.0",
- "@webassemblyjs/wasm-gen": "1.11.0",
- "@webassemblyjs/wasm-parser": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-buffer": "1.11.1",
+ "@webassemblyjs/wasm-gen": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1"
}
},
"@webassemblyjs/wasm-parser": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz",
- "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
+ "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
"requires": {
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/helper-api-error": "1.11.0",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.0",
- "@webassemblyjs/ieee754": "1.11.0",
- "@webassemblyjs/leb128": "1.11.0",
- "@webassemblyjs/utf8": "1.11.0"
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
+ "@webassemblyjs/ieee754": "1.11.1",
+ "@webassemblyjs/leb128": "1.11.1",
+ "@webassemblyjs/utf8": "1.11.1"
}
},
"@webassemblyjs/wast-printer": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz",
- "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==",
- "dev": true,
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
+ "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
"requires": {
- "@webassemblyjs/ast": "1.11.0",
+ "@webassemblyjs/ast": "1.11.1",
"@xtuc/long": "4.2.2"
}
},
"@webpack-cli/configtest": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz",
- "integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==",
- "dev": true
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.4.tgz",
+ "integrity": "sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==",
+ "dev": true,
+ "requires": {}
},
"@webpack-cli/info": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.4.tgz",
- "integrity": "sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.3.0.tgz",
+ "integrity": "sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==",
"dev": true,
"requires": {
"envinfo": "^7.7.3"
}
},
"@webpack-cli/serve": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz",
- "integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==",
- "dev": true
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.1.tgz",
+ "integrity": "sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw==",
+ "dev": true,
+ "requires": {}
},
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
- "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
- "dev": true
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="
},
"@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
- "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
- "dev": true
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
},
"abab": {
"version": "2.0.5",
@@ -4495,10 +26235,11 @@
}
},
"acorn-jsx": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
- "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
- "dev": true
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "requires": {}
},
"acorn-walk": {
"version": "7.2.0",
@@ -4516,9 +26257,9 @@
},
"dependencies": {
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -4546,7 +26287,6 @@
"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",
@@ -4558,7 +26298,7 @@
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true
+ "requires": {}
},
"ansi-align": {
"version": "3.0.0",
@@ -4641,7 +26381,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
"requires": {
"color-convert": "^1.9.0"
}
@@ -5427,25 +27166,25 @@
}
},
"babel-jest": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.2.tgz",
- "integrity": "sha512-9OThPl3/IQbo4Yul2vMz4FYwILPQak8XelX4YGowygfHaOl5R5gfjm4iVx4d8aUugkW683t8aq0A74E7b5DU1Q==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.0.6.tgz",
+ "integrity": "sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA==",
"dev": true,
"requires": {
- "@jest/transform": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/babel__core": "^7.1.14",
"babel-plugin-istanbul": "^6.0.0",
- "babel-preset-jest": "^27.0.1",
+ "babel-preset-jest": "^27.0.6",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"slash": "^3.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -5456,9 +27195,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -5591,9 +27330,9 @@
}
},
"babel-plugin-jest-hoist": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz",
- "integrity": "sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz",
+ "integrity": "sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw==",
"dev": true,
"requires": {
"@babel/template": "^7.3.3",
@@ -5635,13 +27374,13 @@
}
},
"babel-plugin-polyfill-corejs3": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz",
- "integrity": "sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A==",
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz",
+ "integrity": "sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g==",
"dev": true,
"requires": {
"@babel/helper-define-polyfill-provider": "^0.2.2",
- "core-js-compat": "^3.9.1"
+ "core-js-compat": "^3.14.0"
}
},
"babel-plugin-polyfill-regenerator": {
@@ -6005,12 +27744,12 @@
}
},
"babel-preset-jest": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz",
- "integrity": "sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz",
+ "integrity": "sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw==",
"dev": true,
"requires": {
- "babel-plugin-jest-hoist": "^27.0.1",
+ "babel-plugin-jest-hoist": "^27.0.6",
"babel-preset-current-node-syntax": "^1.0.0"
}
},
@@ -6029,15 +27768,6 @@
"source-map-support": "^0.4.15"
},
"dependencies": {
- "mkdirp": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
- "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.5"
- }
- },
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -6209,9 +27939,9 @@
"dev": true
},
"binance-api-node": {
- "version": "0.10.47",
- "resolved": "https://registry.npmjs.org/binance-api-node/-/binance-api-node-0.10.47.tgz",
- "integrity": "sha512-zM5VBy3/lrQ5KPCo6mVDAZerABND+iopyv0zm+U0BZBwuaoPSgLenP3nIxyh9h+H/YFTCoxHSV+jmS0K0lqE5g==",
+ "version": "0.11.5",
+ "resolved": "https://registry.npmjs.org/binance-api-node/-/binance-api-node-0.11.5.tgz",
+ "integrity": "sha512-YLVpcU14d8+iw24c56TgZkZG0u86Lrctm1WloDttYP7DXsmg9meu21zDgRKkiQhZqfjoDoHAXxgByxwLOPQLsQ==",
"requires": {
"isomorphic-fetch": "^2.2.1",
"isomorphic-ws": "^4.0.1",
@@ -6329,6 +28059,12 @@
"requires": {
"has-flag": "^4.0.0"
}
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
}
}
},
@@ -6405,8 +28141,7 @@
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
- "dev": true
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
},
"bunyan": {
"version": "1.8.15",
@@ -6506,7 +28241,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -6520,25 +28254,25 @@
"dev": true
},
"chokidar": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
- "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
+ "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
"dev": true,
"requires": {
- "anymatch": "~3.1.1",
+ "anymatch": "~3.1.2",
"braces": "~3.0.2",
- "fsevents": "~2.3.1",
- "glob-parent": "~5.1.0",
+ "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.5.0"
+ "readdirp": "~3.6.0"
},
"dependencies": {
"anymatch": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
- "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+ "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
"dev": true,
"requires": {
"normalize-path": "^3.0.0",
@@ -6569,15 +28303,6 @@
"to-regex-range": "^5.0.1"
}
},
- "glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "requires": {
- "is-glob": "^4.0.1"
- }
- },
"is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -6594,9 +28319,9 @@
"dev": true
},
"readdirp": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
- "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+ "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"
@@ -6616,13 +28341,12 @@
"chrome-trace-event": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
- "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
- "dev": true
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg=="
},
"ci-info": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
+ "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
"dev": true
},
"cjs-module-lexer": {
@@ -6711,16 +28435,6 @@
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
}
}
- },
- "p-map": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
- "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="
- },
- "pify": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
}
}
},
@@ -6790,7 +28504,6 @@
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "dev": true,
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
@@ -6849,7 +28562,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
"requires": {
"color-name": "1.1.3"
}
@@ -6857,14 +28569,12 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"colorette": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
- "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
- "dev": true
+ "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
},
"combined-stream": {
"version": "1.0.8",
@@ -7000,9 +28710,9 @@
"dev": true
},
"core-js-compat": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.13.1.tgz",
- "integrity": "sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ==",
+ "version": "3.15.2",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.15.2.tgz",
+ "integrity": "sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==",
"dev": true,
"requires": {
"browserslist": "^4.16.6",
@@ -7023,15 +28733,15 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001234",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz",
- "integrity": "sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA==",
+ "version": "1.0.30001243",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
+ "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==",
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.749",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz",
- "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==",
+ "version": "1.3.772",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
+ "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==",
"dev": true
},
"semver": {
@@ -7158,6 +28868,11 @@
"whatwg-url": "^8.0.0"
}
},
+ "dateformat": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
+ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q=="
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -7167,9 +28882,9 @@
}
},
"decimal.js": {
- "version": "10.2.1",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
- "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==",
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
+ "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==",
"dev": true
},
"decode-uri-component": {
@@ -7374,6 +29089,11 @@
}
}
},
+ "dotenv": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
+ "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
+ },
"dtrace-provider": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz",
@@ -7409,8 +29129,7 @@
"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
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"emojis-list": {
"version": "3.0.0",
@@ -7454,7 +29173,6 @@
"version": "5.8.2",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz",
"integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==",
- "dev": true,
"requires": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@@ -7504,10 +29222,9 @@
}
},
"es-module-lexer": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz",
- "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==",
- "dev": true
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz",
+ "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw=="
},
"es-to-primitive": {
"version": "1.2.1",
@@ -7539,8 +29256,7 @@
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
- "dev": true
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"escodegen": {
"version": "2.0.0",
@@ -7603,13 +29319,14 @@
}
},
"eslint": {
- "version": "7.28.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz",
- "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==",
+ "version": "7.30.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz",
+ "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==",
"dev": true,
"requires": {
"@babel/code-frame": "7.12.11",
"@eslint/eslintrc": "^0.4.2",
+ "@humanwhocodes/config-array": "^0.5.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -7693,9 +29410,9 @@
"dev": true
},
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -7719,19 +29436,10 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
- "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.9.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz",
- "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==",
+ "version": "13.10.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
+ "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -7766,12 +29474,6 @@
"requires": {
"has-flag": "^4.0.0"
}
- },
- "type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
- "dev": true
}
}
},
@@ -7829,7 +29531,8 @@
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz",
"integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"eslint-config-react-app": {
"version": "6.0.0",
@@ -7890,33 +29593,16 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz",
"integrity": "sha512-6/Jb/J/ZvSebydwbBJO1R9E5ky7YeElfK56Veh7e4QGFHCXoIXGH9HhVz+ibJLM3XJ1XjP+T7rKBLUa/Y7eIng==",
- "dev": true,
- "requires": {
- "eslint-utils": "^2.0.0",
- "regexpp": "^3.0.0"
- },
- "dependencies": {
- "eslint-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
- "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
- "dev": true,
- "requires": {
- "eslint-visitor-keys": "^1.1.0"
- }
- },
- "regexpp": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
- "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
- "dev": true
- }
+ "dev": true,
+ "requires": {
+ "eslint-utils": "^2.0.0",
+ "regexpp": "^3.0.0"
}
},
"eslint-plugin-flowtype": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.7.2.tgz",
- "integrity": "sha512-7Oq/N0+3nijBnYWQYzz/Mp/7ZCpwxYvClRyW/PLAmimY9uLCBvoXsNsERcJdkKceyOjgRbFhhxs058KTrne9Mg==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.8.0.tgz",
+ "integrity": "sha512-feK1xnUTsMSNTOw9jFw7aVgZl7Ep+ghpta/YEoaV6jbXU6Yso30B7BIj9ObHLzZ5TFJL7D98az080wfykLCrcw==",
"dev": true,
"requires": {
"lodash": "^4.17.15",
@@ -8157,15 +29843,6 @@
"semver": "^6.1.0"
},
"dependencies": {
- "eslint-utils": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
- "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
- "dev": true,
- "requires": {
- "eslint-visitor-keys": "^1.1.0"
- }
- },
"ignore": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
@@ -8193,7 +29870,8 @@
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz",
"integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"eslint-plugin-react": {
"version": "7.24.0",
@@ -8391,13 +30069,13 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz",
"integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "dev": true,
"requires": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@@ -8464,7 +30142,6 @@
"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"
},
@@ -8472,16 +30149,14 @@
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
- "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
- "dev": true
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
}
}
},
"estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "dev": true
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
},
"esutils": {
"version": "2.0.3",
@@ -8497,8 +30172,7 @@
"events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
- "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
- "dev": true
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
},
"execa": {
"version": "5.1.1",
@@ -8587,23 +30261,23 @@
}
},
"expect": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz",
- "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz",
+ "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-styles": "^5.0.0",
- "jest-get-type": "^27.0.1",
- "jest-matcher-utils": "^27.0.2",
- "jest-message-util": "^27.0.2",
- "jest-regex-util": "^27.0.1"
+ "jest-get-type": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-regex-util": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -8614,9 +30288,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -8671,9 +30345,9 @@
"dev": true
},
"jest-get-type": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
- "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"supports-color": {
@@ -8828,8 +30502,7 @@
"fast-deep-equal": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
- "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
- "dev": true
+ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
},
"fast-diff": {
"version": "1.2.0",
@@ -8869,15 +30542,6 @@
"to-regex-range": "^5.0.1"
}
},
- "glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "requires": {
- "is-glob": "^4.0.1"
- }
- },
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -8916,8 +30580,7 @@
"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
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"fast-levenshtein": {
"version": "2.0.6",
@@ -9056,9 +30719,9 @@
}
},
"flatted": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
- "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz",
+ "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==",
"dev": true
},
"follow-redirects": {
@@ -9198,33 +30861,18 @@
}
},
"glob-parent": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
- "optional": true,
"requires": {
- "is-glob": "^3.1.0",
- "path-dirname": "^1.0.0"
- },
- "dependencies": {
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "dev": true,
- "optional": true,
- "requires": {
- "is-extglob": "^2.1.0"
- }
- }
+ "is-glob": "^4.0.1"
}
},
"glob-to-regexp": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
- "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
- "dev": true
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
},
"global-dirs": {
"version": "2.1.0",
@@ -9291,8 +30939,7 @@
"graceful-fs": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
- "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
- "dev": true
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
},
"has": {
"version": "1.0.3",
@@ -9329,8 +30976,7 @@
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-symbols": {
"version": "1.0.1",
@@ -9440,9 +31086,9 @@
},
"dependencies": {
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -9467,9 +31113,9 @@
},
"dependencies": {
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -9490,9 +31136,9 @@
"dev": true
},
"husky": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz",
- "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.1.tgz",
+ "integrity": "sha512-gceRaITVZ+cJH9sNHqx5tFwbzlLCVxtVZcusME8JYQ8Edy5mpGDOqD8QBCdMhpyo9a+JXddnujQ4rpY2Ff9SJA==",
"dev": true
},
"iconv-lite": {
@@ -9613,9 +31259,9 @@
}
},
"ioredis": {
- "version": "4.27.4",
- "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.27.4.tgz",
- "integrity": "sha512-1n91WZ+L1tHL4hEN9pT16s3f0+Dg82GfvyJGaD47BhEvQb63gIsmDkt/dmzDFBTYfwwlQn8TsT/QSPcjHiT3CQ==",
+ "version": "4.27.6",
+ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.27.6.tgz",
+ "integrity": "sha512-6W3ZHMbpCa8ByMyC1LJGOi7P2WiOKP9B3resoZOVLDhi+6dDBOW+KNsRq3yI36Hmnb2sifCxHX+YSarTeXh48A==",
"requires": {
"cluster-key-slot": "^1.1.0",
"debug": "^4.3.1",
@@ -9630,9 +31276,9 @@
},
"dependencies": {
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
@@ -9739,12 +31385,12 @@
"dev": true
},
"is-ci": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
- "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
+ "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
"dev": true,
"requires": {
- "ci-info": "^2.0.0"
+ "ci-info": "^3.1.1"
}
},
"is-core-module": {
@@ -9830,8 +31476,7 @@
"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
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"is-generator-fn": {
"version": "2.1.0",
@@ -9928,9 +31573,9 @@
}
},
"is-path-inside": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
- "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+ "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": {
@@ -10036,7 +31681,8 @@
"isomorphic-ws": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
- "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w=="
+ "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==",
+ "requires": {}
},
"istanbul-lib-coverage": {
"version": "3.0.0",
@@ -10119,9 +31765,9 @@
},
"dependencies": {
"debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
+ "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -10146,20 +31792,20 @@
}
},
"jest": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.4.tgz",
- "integrity": "sha512-Px1iKFooXgGSkk1H8dJxxBIrM3tsc5SIuI4kfKYK2J+4rvCvPGr/cXktxh0e9zIPQ5g09kOMNfHQEmusBUf/ZA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-27.0.6.tgz",
+ "integrity": "sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA==",
"dev": true,
"requires": {
- "@jest/core": "^27.0.4",
+ "@jest/core": "^27.0.6",
"import-local": "^3.0.2",
- "jest-cli": "^27.0.4"
+ "jest-cli": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -10170,9 +31816,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -10219,21 +31865,21 @@
"dev": true
},
"jest-cli": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.4.tgz",
- "integrity": "sha512-E0T+/i2lxsWAzV7LKYd0SB7HUAvePqaeIh5vX43/G5jXLhv1VzjYzJAGEkTfvxV774ll9cyE2ljcL73PVMEOXQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.0.6.tgz",
+ "integrity": "sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg==",
"dev": true,
"requires": {
- "@jest/core": "^27.0.4",
- "@jest/test-result": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/core": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
"chalk": "^4.0.0",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
"import-local": "^3.0.2",
- "jest-config": "^27.0.4",
- "jest-util": "^27.0.2",
- "jest-validate": "^27.0.2",
+ "jest-config": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
"prompts": "^2.0.1",
"yargs": "^16.0.3"
}
@@ -10250,20 +31896,20 @@
}
},
"jest-changed-files": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.2.tgz",
- "integrity": "sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.0.6.tgz",
+ "integrity": "sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"execa": "^5.0.0",
"throat": "^6.0.1"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -10274,9 +31920,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -10334,36 +31980,36 @@
}
},
"jest-circus": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.4.tgz",
- "integrity": "sha512-QD+eblDiRphta630WRKewuASLs/oY1Zki2G4bccntRvrTHQ63ljwFR5TLduuK4Zg0ZPzW0+8o6AP7KRd1yKOjw==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.0.6.tgz",
+ "integrity": "sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.3",
- "@jest/test-result": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/environment": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
"dedent": "^0.7.0",
- "expect": "^27.0.2",
+ "expect": "^27.0.6",
"is-generator-fn": "^2.0.0",
- "jest-each": "^27.0.2",
- "jest-matcher-utils": "^27.0.2",
- "jest-message-util": "^27.0.2",
- "jest-runtime": "^27.0.4",
- "jest-snapshot": "^27.0.4",
- "jest-util": "^27.0.2",
- "pretty-format": "^27.0.2",
+ "jest-each": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "pretty-format": "^27.0.6",
"slash": "^3.0.0",
"stack-utils": "^2.0.3",
"throat": "^6.0.1"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -10374,9 +32020,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -10423,12 +32069,12 @@
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -10460,38 +32106,38 @@
}
},
"jest-config": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.4.tgz",
- "integrity": "sha512-VkQFAHWnPQefdvHU9A+G3H/Z3NrrTKqWpvxgQz3nkUdkDTWeKJE6e//BL+R7z79dXOMVksYgM/z6ndtN0hfChg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.0.6.tgz",
+ "integrity": "sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w==",
"dev": true,
"requires": {
"@babel/core": "^7.1.0",
- "@jest/test-sequencer": "^27.0.4",
- "@jest/types": "^27.0.2",
- "babel-jest": "^27.0.2",
+ "@jest/test-sequencer": "^27.0.6",
+ "@jest/types": "^27.0.6",
+ "babel-jest": "^27.0.6",
"chalk": "^4.0.0",
"deepmerge": "^4.2.2",
"glob": "^7.1.1",
"graceful-fs": "^4.2.4",
"is-ci": "^3.0.0",
- "jest-circus": "^27.0.4",
- "jest-environment-jsdom": "^27.0.3",
- "jest-environment-node": "^27.0.3",
- "jest-get-type": "^27.0.1",
- "jest-jasmine2": "^27.0.4",
- "jest-regex-util": "^27.0.1",
- "jest-resolve": "^27.0.4",
- "jest-runner": "^27.0.4",
- "jest-util": "^27.0.2",
- "jest-validate": "^27.0.2",
+ "jest-circus": "^27.0.6",
+ "jest-environment-jsdom": "^27.0.6",
+ "jest-environment-node": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "jest-jasmine2": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-runner": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
"micromatch": "^4.0.4",
- "pretty-format": "^27.0.2"
+ "pretty-format": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -10502,9 +32148,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -10538,12 +32184,6 @@
"supports-color": "^7.1.0"
}
},
- "ci-info": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
- "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
- "dev": true
- },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -10574,15 +32214,6 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
- "is-ci": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
- "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
- "dev": true,
- "requires": {
- "ci-info": "^3.1.1"
- }
- },
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -10590,9 +32221,9 @@
"dev": true
},
"jest-get-type": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
- "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"micromatch": {
@@ -10612,12 +32243,12 @@
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -10715,31 +32346,31 @@
}
},
"jest-docblock": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.1.tgz",
- "integrity": "sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz",
+ "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==",
"dev": true,
"requires": {
"detect-newline": "^3.0.0"
}
},
"jest-each": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.2.tgz",
- "integrity": "sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.0.6.tgz",
+ "integrity": "sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"chalk": "^4.0.0",
- "jest-get-type": "^27.0.1",
- "jest-util": "^27.0.2",
- "pretty-format": "^27.0.2"
+ "jest-get-type": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "pretty-format": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -10750,9 +32381,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -10799,18 +32430,18 @@
"dev": true
},
"jest-get-type": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
- "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -10836,24 +32467,24 @@
}
},
"jest-environment-jsdom": {
- "version": "27.0.3",
- "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.3.tgz",
- "integrity": "sha512-5KLmgv1bhiimpSA8oGTnZYk6g4fsNyZiA/6gI2tAZUgrufd7heRUSVh4gRokzZVEj8zlwAQYT0Zs6tuJSW/ECA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz",
+ "integrity": "sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.3",
- "@jest/fake-timers": "^27.0.3",
- "@jest/types": "^27.0.2",
+ "@jest/environment": "^27.0.6",
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
- "jest-mock": "^27.0.3",
- "jest-util": "^27.0.2",
+ "jest-mock": "^27.0.6",
+ "jest-util": "^27.0.6",
"jsdom": "^16.6.0"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -10864,9 +32495,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -10924,23 +32555,23 @@
}
},
"jest-environment-node": {
- "version": "27.0.3",
- "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.3.tgz",
- "integrity": "sha512-co2/IVnIFL3cItpFULCvXFg9us4gvWXgs7mutAMPCbFhcqh56QAOdKhNzC2+RycsC/k4mbMj1VF+9F/NzA0ROg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.0.6.tgz",
+ "integrity": "sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w==",
"dev": true,
"requires": {
- "@jest/environment": "^27.0.3",
- "@jest/fake-timers": "^27.0.3",
- "@jest/types": "^27.0.2",
+ "@jest/environment": "^27.0.6",
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
- "jest-mock": "^27.0.3",
- "jest-util": "^27.0.2"
+ "jest-mock": "^27.0.6",
+ "jest-util": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -10951,9 +32582,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11017,30 +32648,30 @@
"dev": true
},
"jest-haste-map": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.2.tgz",
- "integrity": "sha512-37gYfrYjjhEfk37C4bCMWAC0oPBxDpG0qpl8lYg8BT//wf353YT/fzgA7+Dq0EtM7rPFS3JEcMsxdtDwNMi2cA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.0.6.tgz",
+ "integrity": "sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"@types/graceful-fs": "^4.1.2",
"@types/node": "*",
"anymatch": "^3.0.3",
"fb-watchman": "^2.0.0",
"fsevents": "^2.3.2",
"graceful-fs": "^4.2.4",
- "jest-regex-util": "^27.0.1",
- "jest-serializer": "^27.0.1",
- "jest-util": "^27.0.2",
- "jest-worker": "^27.0.2",
+ "jest-regex-util": "^27.0.6",
+ "jest-serializer": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-worker": "^27.0.6",
"micromatch": "^4.0.4",
"walker": "^1.0.7"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11051,9 +32682,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11172,35 +32803,35 @@
}
},
"jest-jasmine2": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.4.tgz",
- "integrity": "sha512-yj3WrjjquZwkJw+eA4c9yucHw4/+EHndHWSqgHbHGQfT94ihaaQsa009j1a0puU8CNxPDk0c1oAPeOpdJUElwA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz",
+ "integrity": "sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA==",
"dev": true,
"requires": {
"@babel/traverse": "^7.1.0",
- "@jest/environment": "^27.0.3",
- "@jest/source-map": "^27.0.1",
- "@jest/test-result": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/environment": "^27.0.6",
+ "@jest/source-map": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
"chalk": "^4.0.0",
"co": "^4.6.0",
- "expect": "^27.0.2",
+ "expect": "^27.0.6",
"is-generator-fn": "^2.0.0",
- "jest-each": "^27.0.2",
- "jest-matcher-utils": "^27.0.2",
- "jest-message-util": "^27.0.2",
- "jest-runtime": "^27.0.4",
- "jest-snapshot": "^27.0.4",
- "jest-util": "^27.0.2",
- "pretty-format": "^27.0.2",
+ "jest-each": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "pretty-format": "^27.0.6",
"throat": "^6.0.1"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11211,9 +32842,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11260,12 +32891,12 @@
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -11291,19 +32922,19 @@
}
},
"jest-leak-detector": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz",
- "integrity": "sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz",
+ "integrity": "sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ==",
"dev": true,
"requires": {
- "jest-get-type": "^27.0.1",
- "pretty-format": "^27.0.2"
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11314,9 +32945,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11371,18 +33002,18 @@
"dev": true
},
"jest-get-type": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
- "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -11400,21 +33031,21 @@
}
},
"jest-matcher-utils": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz",
- "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz",
+ "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
- "jest-diff": "^27.0.2",
- "jest-get-type": "^27.0.1",
- "pretty-format": "^27.0.2"
+ "jest-diff": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11425,9 +33056,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11468,9 +33099,9 @@
"dev": true
},
"diff-sequences": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz",
- "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
+ "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
"dev": true
},
"has-flag": {
@@ -11480,30 +33111,30 @@
"dev": true
},
"jest-diff": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz",
- "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
+ "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
- "diff-sequences": "^27.0.1",
- "jest-get-type": "^27.0.1",
- "pretty-format": "^27.0.2"
+ "diff-sequences": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
}
},
"jest-get-type": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
- "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -11529,44 +33160,44 @@
}
},
"jest-message-util": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz",
- "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz",
+ "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"micromatch": "^4.0.4",
- "pretty-format": "^27.0.2",
+ "pretty-format": "^27.0.6",
"slash": "^3.0.0",
"stack-utils": "^2.0.3"
},
"dependencies": {
"@babel/code-frame": {
- "version": "7.12.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
- "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
+ "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.12.13"
+ "@babel/highlight": "^7.14.5"
}
},
"@babel/helper-validator-identifier": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
- "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
+ "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",
"dev": true
},
"@babel/highlight": {
- "version": "7.14.0",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
- "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.14.0",
+ "@babel/helper-validator-identifier": "^7.14.5",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
},
@@ -11585,9 +33216,9 @@
}
},
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11598,9 +33229,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11698,12 +33329,12 @@
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -11735,19 +33366,19 @@
}
},
"jest-mock": {
- "version": "27.0.3",
- "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.3.tgz",
- "integrity": "sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.0.6.tgz",
+ "integrity": "sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"@types/node": "*"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11758,9 +33389,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11821,35 +33452,36 @@
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
"integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
- "dev": true
+ "dev": true,
+ "requires": {}
},
"jest-regex-util": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz",
- "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz",
+ "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==",
"dev": true
},
"jest-resolve": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.4.tgz",
- "integrity": "sha512-BcfyK2i3cG79PDb/6gB6zFeFQlcqLsQjGBqznFCpA0L/3l1L/oOsltdUjs5eISAWA9HS9qtj8v2PSZr/yWxONQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.0.6.tgz",
+ "integrity": "sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"chalk": "^4.0.0",
"escalade": "^3.1.1",
"graceful-fs": "^4.2.4",
"jest-pnp-resolver": "^1.2.2",
- "jest-util": "^27.0.2",
- "jest-validate": "^27.0.2",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
"resolve": "^1.20.0",
"slash": "^3.0.0"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11860,9 +33492,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -11936,20 +33568,20 @@
}
},
"jest-resolve-dependencies": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.4.tgz",
- "integrity": "sha512-F33UPfw1YGWCV2uxJl7wD6TvcQn5IC0LtguwY3r4L7R6H4twpLkp5Q2ZfzRx9A2I3G8feiy0O0sqcn/Qoym71A==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz",
+ "integrity": "sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
- "jest-regex-util": "^27.0.1",
- "jest-snapshot": "^27.0.4"
+ "@jest/types": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-snapshot": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -11960,9 +33592,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -12020,39 +33652,39 @@
}
},
"jest-runner": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.4.tgz",
- "integrity": "sha512-NfmvSYLCsCJk2AG8Ar2NAh4PhsJJpO+/r+g4bKR5L/5jFzx/indUpnVBdrfDvuqhGLLAvrKJ9FM/Nt8o1dsqxg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.0.6.tgz",
+ "integrity": "sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ==",
"dev": true,
"requires": {
- "@jest/console": "^27.0.2",
- "@jest/environment": "^27.0.3",
- "@jest/test-result": "^27.0.2",
- "@jest/transform": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/console": "^27.0.6",
+ "@jest/environment": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
"chalk": "^4.0.0",
"emittery": "^0.8.1",
"exit": "^0.1.2",
"graceful-fs": "^4.2.4",
- "jest-docblock": "^27.0.1",
- "jest-environment-jsdom": "^27.0.3",
- "jest-environment-node": "^27.0.3",
- "jest-haste-map": "^27.0.2",
- "jest-leak-detector": "^27.0.2",
- "jest-message-util": "^27.0.2",
- "jest-resolve": "^27.0.4",
- "jest-runtime": "^27.0.4",
- "jest-util": "^27.0.2",
- "jest-worker": "^27.0.2",
+ "jest-docblock": "^27.0.6",
+ "jest-environment-jsdom": "^27.0.6",
+ "jest-environment-node": "^27.0.6",
+ "jest-haste-map": "^27.0.6",
+ "jest-leak-detector": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-runtime": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-worker": "^27.0.6",
"source-map-support": "^0.5.6",
"throat": "^6.0.1"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -12063,9 +33695,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -12123,19 +33755,19 @@
}
},
"jest-runtime": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.4.tgz",
- "integrity": "sha512-voJB4xbAjS/qYPboV+e+gmg3jfvHJJY4CagFWBOM9dQKtlaiTjcpD2tWwla84Z7PtXSQPeIpXY0qksA9Dum29A==",
- "dev": true,
- "requires": {
- "@jest/console": "^27.0.2",
- "@jest/environment": "^27.0.3",
- "@jest/fake-timers": "^27.0.3",
- "@jest/globals": "^27.0.3",
- "@jest/source-map": "^27.0.1",
- "@jest/test-result": "^27.0.2",
- "@jest/transform": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.0.6.tgz",
+ "integrity": "sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^27.0.6",
+ "@jest/environment": "^27.0.6",
+ "@jest/fake-timers": "^27.0.6",
+ "@jest/globals": "^27.0.6",
+ "@jest/source-map": "^27.0.6",
+ "@jest/test-result": "^27.0.6",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/yargs": "^16.0.0",
"chalk": "^4.0.0",
"cjs-module-lexer": "^1.0.0",
@@ -12143,23 +33775,23 @@
"exit": "^0.1.2",
"glob": "^7.1.3",
"graceful-fs": "^4.2.4",
- "jest-haste-map": "^27.0.2",
- "jest-message-util": "^27.0.2",
- "jest-mock": "^27.0.3",
- "jest-regex-util": "^27.0.1",
- "jest-resolve": "^27.0.4",
- "jest-snapshot": "^27.0.4",
- "jest-util": "^27.0.2",
- "jest-validate": "^27.0.2",
+ "jest-haste-map": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-mock": "^27.0.6",
+ "jest-regex-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-snapshot": "^27.0.6",
+ "jest-util": "^27.0.6",
+ "jest-validate": "^27.0.6",
"slash": "^3.0.0",
"strip-bom": "^4.0.0",
"yargs": "^16.0.3"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -12170,9 +33802,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -12242,9 +33874,9 @@
}
},
"jest-serializer": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.1.tgz",
- "integrity": "sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz",
+ "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==",
"dev": true,
"requires": {
"@types/node": "*",
@@ -12252,9 +33884,9 @@
}
},
"jest-snapshot": {
- "version": "27.0.4",
- "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.4.tgz",
- "integrity": "sha512-hnjrvpKGdSMvKfbHyaG5Kul7pDJGZvjVy0CKpzhu28MmAssDXS6GpynhXzgst1wBQoKD8c9b2VS2a5yhDLQRCA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.0.6.tgz",
+ "integrity": "sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A==",
"dev": true,
"requires": {
"@babel/core": "^7.7.2",
@@ -12263,30 +33895,30 @@
"@babel/plugin-syntax-typescript": "^7.7.2",
"@babel/traverse": "^7.7.2",
"@babel/types": "^7.0.0",
- "@jest/transform": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/transform": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/babel__traverse": "^7.0.4",
"@types/prettier": "^2.1.5",
"babel-preset-current-node-syntax": "^1.0.0",
"chalk": "^4.0.0",
- "expect": "^27.0.2",
+ "expect": "^27.0.6",
"graceful-fs": "^4.2.4",
- "jest-diff": "^27.0.2",
- "jest-get-type": "^27.0.1",
- "jest-haste-map": "^27.0.2",
- "jest-matcher-utils": "^27.0.2",
- "jest-message-util": "^27.0.2",
- "jest-resolve": "^27.0.4",
- "jest-util": "^27.0.2",
+ "jest-diff": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "jest-haste-map": "^27.0.6",
+ "jest-matcher-utils": "^27.0.6",
+ "jest-message-util": "^27.0.6",
+ "jest-resolve": "^27.0.6",
+ "jest-util": "^27.0.6",
"natural-compare": "^1.4.0",
- "pretty-format": "^27.0.2",
+ "pretty-format": "^27.0.6",
"semver": "^7.3.2"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -12297,9 +33929,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -12340,9 +33972,9 @@
"dev": true
},
"diff-sequences": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz",
- "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
+ "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
"dev": true
},
"has-flag": {
@@ -12352,30 +33984,30 @@
"dev": true
},
"jest-diff": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz",
- "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz",
+ "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
- "diff-sequences": "^27.0.1",
- "jest-get-type": "^27.0.1",
- "pretty-format": "^27.0.2"
+ "diff-sequences": "^27.0.6",
+ "jest-get-type": "^27.0.6",
+ "pretty-format": "^27.0.6"
}
},
"jest-get-type": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
- "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -12410,12 +34042,12 @@
}
},
"jest-util": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.2.tgz",
- "integrity": "sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.0.6.tgz",
+ "integrity": "sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
@@ -12424,9 +34056,9 @@
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -12437,9 +34069,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -12464,12 +34096,6 @@
"supports-color": "^7.1.0"
}
},
- "ci-info": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
- "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
- "dev": true
- },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -12491,15 +34117,6 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
- "is-ci": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
- "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
- "dev": true,
- "requires": {
- "ci-info": "^3.1.1"
- }
- },
"picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
@@ -12518,23 +34135,23 @@
}
},
"jest-validate": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.2.tgz",
- "integrity": "sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.0.6.tgz",
+ "integrity": "sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"camelcase": "^6.2.0",
"chalk": "^4.0.0",
- "jest-get-type": "^27.0.1",
+ "jest-get-type": "^27.0.6",
"leven": "^3.1.0",
- "pretty-format": "^27.0.2"
+ "pretty-format": "^27.0.6"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -12545,9 +34162,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -12600,18 +34217,18 @@
"dev": true
},
"jest-get-type": {
- "version": "27.0.1",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
- "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
+ "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"pretty-format": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz",
- "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz",
+ "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==",
"dev": true,
"requires": {
- "@jest/types": "^27.0.2",
+ "@jest/types": "^27.0.6",
"ansi-regex": "^5.0.0",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
@@ -12637,24 +34254,24 @@
}
},
"jest-watcher": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.2.tgz",
- "integrity": "sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.0.6.tgz",
+ "integrity": "sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ==",
"dev": true,
"requires": {
- "@jest/test-result": "^27.0.2",
- "@jest/types": "^27.0.2",
+ "@jest/test-result": "^27.0.6",
+ "@jest/types": "^27.0.6",
"@types/node": "*",
"ansi-escapes": "^4.2.1",
"chalk": "^4.0.0",
- "jest-util": "^27.0.2",
+ "jest-util": "^27.0.6",
"string-length": "^4.0.1"
},
"dependencies": {
"@jest/types": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz",
- "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==",
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz",
+ "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -12665,9 +34282,9 @@
}
},
"@types/yargs": {
- "version": "16.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz",
- "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==",
+ "version": "16.0.4",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
+ "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
@@ -12725,10 +34342,9 @@
}
},
"jest-worker": {
- "version": "27.0.2",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.2.tgz",
- "integrity": "sha512-EoBdilOTTyOgmHXtw/cPc+ZrCA0KJMrkXzkrPGNwLmnvvlN1nj7MPrxpT7m+otSv2e1TLaVffzDnE/LB14zJMg==",
- "dev": true,
+ "version": "27.0.6",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.0.6.tgz",
+ "integrity": "sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA==",
"requires": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@@ -12738,14 +34354,12 @@
"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
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "dev": true,
"requires": {
"has-flag": "^4.0.0"
}
@@ -12804,9 +34418,9 @@
},
"dependencies": {
"acorn": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz",
- "integrity": "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==",
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
+ "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
"dev": true
}
}
@@ -12826,8 +34440,7 @@
"json-parse-better-errors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
- "dev": true
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
},
"json-parse-even-better-errors": {
"version": "2.3.1",
@@ -12838,8 +34451,7 @@
"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
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
@@ -12854,14 +34466,6 @@
"dev": true,
"requires": {
"minimist": "^1.2.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
- "dev": true
- }
}
},
"jsx-ast-utils": {
@@ -13174,8 +34778,7 @@
"loader-runner": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
- "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
- "dev": true
+ "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw=="
},
"loader-utils": {
"version": "1.4.0",
@@ -13199,37 +34802,6 @@
"yargs": "16.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==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "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=="
- },
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
@@ -13238,64 +34810,10 @@
"ms": "2.1.2"
}
},
- "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=="
- },
- "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=="
- },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- },
- "string-width": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
- "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "y18n": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
- "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg=="
- },
- "yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "requires": {
- "cliui": "^7.0.2",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.0",
- "y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
- }
- },
- "yargs-parser": {
- "version": "20.2.4",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
- "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
}
}
},
@@ -13550,8 +35068,7 @@
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "dev": true
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
},
"merge2": {
"version": "1.4.1",
@@ -13586,6 +35103,28 @@
"to-regex": "^3.0.2"
}
},
+ "migrate": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/migrate/-/migrate-1.7.0.tgz",
+ "integrity": "sha512-I63YykITgWyI+ET4KO8xGePYkR9U7CtSe/RrR13vLbZSpUcAh4/ry2GswNv7Lywcsp3BaDHj7YdjC7ihVYCFmw==",
+ "requires": {
+ "chalk": "^2.4.1",
+ "commander": "^2.19.0",
+ "dateformat": "^3.0.3",
+ "dotenv": "^6.1.0",
+ "inherits": "^2.0.3",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "slug": "^0.9.2"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ }
+ }
+ },
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
@@ -13656,7 +35195,6 @@
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
- "optional": true,
"requires": {
"minimist": "^1.2.5"
}
@@ -13675,9 +35213,9 @@
}
},
"mongodb": {
- "version": "3.6.9",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.9.tgz",
- "integrity": "sha512-1nSCKgSunzn/CXwgOWgbPHUWOO5OfERcuOWISmqd610jn0s8BU9K4879iJVabqgpPPbA6hO7rG48eq+fGED3Mg==",
+ "version": "3.6.10",
+ "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.10.tgz",
+ "integrity": "sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q==",
"requires": {
"bl": "^2.2.1",
"bson": "^1.1.4",
@@ -13773,8 +35311,7 @@
"neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
- "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
- "dev": true
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="
},
"node-fetch": {
"version": "1.7.3",
@@ -13798,15 +35335,14 @@
"dev": true
},
"node-releases": {
- "version": "1.1.72",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
- "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
- "dev": true
+ "version": "1.1.73",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
+ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg=="
},
"nodemon": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
- "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==",
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.11.tgz",
+ "integrity": "sha512-V9UizUMs7hM63YC+e+26FC4iTqEA1GJsrM8C7DiNyPvYBOG/QE169kMIe+sH7FSe8YteMQpaKkUDwfAF83+kEQ==",
"dev": true,
"requires": {
"chokidar": "^3.2.2",
@@ -14426,13 +35962,6 @@
"dev": true,
"optional": true
},
- "path-dirname": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
- "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
- "dev": true,
- "optional": true
- },
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@@ -14491,8 +36020,7 @@
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
- "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
- "dev": true
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
},
"pinkie": {
"version": "2.0.4",
@@ -14614,9 +36142,9 @@
"dev": true
},
"prettier": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.1.tgz",
- "integrity": "sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz",
+ "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==",
"dev": true
},
"prettier-linter-helpers": {
@@ -14751,8 +36279,7 @@
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "dev": true
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"pupa": {
"version": "2.1.1",
@@ -14773,7 +36300,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
"requires": {
"safe-buffer": "^5.1.0"
}
@@ -14815,9 +36341,9 @@
}
},
"react-is": {
- "version": "17.0.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz",
- "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==",
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true
},
"read-pkg": {
@@ -14984,9 +36510,9 @@
}
},
"regexpp": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
- "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
"dev": true
},
"regexpu-core": {
@@ -15297,10 +36823,9 @@
}
},
"serialize-javascript": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
- "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
- "dev": true,
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
+ "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
"requires": {
"randombytes": "^2.1.0"
}
@@ -15453,6 +36978,14 @@
}
}
},
+ "slug": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/slug/-/slug-0.9.4.tgz",
+ "integrity": "sha512-3YHq0TeJ4+AIFbJm+4UWSQs5A1mmeWOTQqydW3OoPmQfNKxlO96NDRTIrp+TBkmvEsEFrd+Z/LXw8OD/6OlZ5g==",
+ "requires": {
+ "unicode": ">= 0.3.1"
+ }
+ },
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -15580,8 +37113,7 @@
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
- "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
- "dev": true
+ "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw=="
},
"source-map": {
"version": "0.6.1",
@@ -15606,7 +37138,6 @@
"version": "0.5.19",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
- "dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -15726,6 +37257,14 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
+ "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"
+ }
+ },
"string-argv": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
@@ -15752,7 +37291,6 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
"integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
- "dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@@ -15914,14 +37452,6 @@
"es-abstract": "^1.17.5"
}
},
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
"stringify-object": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
@@ -15963,7 +37493,6 @@
"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"
}
@@ -16016,9 +37545,9 @@
},
"dependencies": {
"ajv": {
- "version": "8.5.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz",
- "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==",
+ "version": "8.6.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz",
+ "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@@ -16038,8 +37567,7 @@
"tapable": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz",
- "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==",
- "dev": true
+ "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw=="
},
"term-size": {
"version": "2.2.1",
@@ -16058,10 +37586,9 @@
}
},
"terser": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz",
- "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==",
- "dev": true,
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.1.tgz",
+ "integrity": "sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg==",
"requires": {
"commander": "^2.20.0",
"source-map": "~0.7.2",
@@ -16071,27 +37598,24 @@
"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
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
}
}
},
"terser-webpack-plugin": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.3.tgz",
- "integrity": "sha512-cxGbMqr6+A2hrIB5ehFIF+F/iST5ZOxvOmy9zih9ySbP1C2oEWQSOUS+2SNBTjzx5xLKO4xnod9eywdfq1Nb9A==",
- "dev": true,
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz",
+ "integrity": "sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA==",
"requires": {
"jest-worker": "^27.0.2",
"p-limit": "^3.1.0",
"schema-utils": "^3.0.0",
- "serialize-javascript": "^5.0.1",
+ "serialize-javascript": "^6.0.0",
"source-map": "^0.6.1",
"terser": "^5.7.0"
},
@@ -16100,18 +37624,16 @@
"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"
}
},
"schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz",
+ "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==",
"requires": {
- "@types/json-schema": "^7.0.6",
+ "@types/json-schema": "^7.0.7",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
@@ -16294,9 +37816,9 @@
"dev": true
},
"type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "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": {
@@ -16346,6 +37868,11 @@
"debug": "^2.2.0"
}
},
+ "unicode": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/unicode/-/unicode-13.0.0.tgz",
+ "integrity": "sha512-osNPLT4Lqna/sV6DQikrB8m4WxR61/k0fnhfKnkPGcZImczW3IysRXvWxfdqGUjh0Ju2o/tGGgu46mlfc/cpZw=="
+ },
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -16498,6 +38025,12 @@
"supports-color": "^7.1.0"
}
},
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -16519,6 +38052,15 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -16534,7 +38076,6 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
- "dev": true,
"requires": {
"punycode": "^2.1.0"
}
@@ -16584,9 +38125,9 @@
"dev": true
},
"v8-to-istanbul": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz",
- "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz",
+ "integrity": "sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.1",
@@ -16648,7 +38189,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.2.0.tgz",
"integrity": "sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==",
- "dev": true,
"requires": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@@ -16661,21 +38201,20 @@
"dev": true
},
"webpack": {
- "version": "5.38.1",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.38.1.tgz",
- "integrity": "sha512-OqRmYD1OJbHZph6RUMD93GcCZy4Z4wC0ele4FXyYF0J6AxO1vOSuIlU1hkS/lDlR9CDYBz64MZRmdbdnFFoT2g==",
- "dev": true,
+ "version": "5.44.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.44.0.tgz",
+ "integrity": "sha512-I1S1w4QLoKmH19pX6YhYN0NiSXaWY8Ou00oA+aMcr9IUGeF5azns+IKBkfoAAG9Bu5zOIzZt/mN35OffBya8AQ==",
"requires": {
"@types/eslint-scope": "^3.7.0",
- "@types/estree": "^0.0.47",
- "@webassemblyjs/ast": "1.11.0",
- "@webassemblyjs/wasm-edit": "1.11.0",
- "@webassemblyjs/wasm-parser": "1.11.0",
- "acorn": "^8.2.1",
+ "@types/estree": "^0.0.50",
+ "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/wasm-edit": "1.11.1",
+ "@webassemblyjs/wasm-parser": "1.11.1",
+ "acorn": "^8.4.1",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.8.0",
- "es-module-lexer": "^0.4.0",
+ "es-module-lexer": "^0.7.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
@@ -16686,22 +38225,20 @@
"neo-async": "^2.6.2",
"schema-utils": "^3.0.0",
"tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.1.1",
+ "terser-webpack-plugin": "^5.1.3",
"watchpack": "^2.2.0",
"webpack-sources": "^2.3.0"
},
"dependencies": {
"acorn": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.3.0.tgz",
- "integrity": "sha512-tqPKHZ5CaBJw0Xmy0ZZvLs1qTV+BNFSyvn77ASXkpBNfIRk8ev26fKrD9iLGwGA9zedPao52GSHzq8lyZG0NUw==",
- "dev": true
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
+ "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA=="
},
"browserslist": {
"version": "4.16.6",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
"integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
- "dev": true,
"requires": {
"caniuse-lite": "^1.0.30001219",
"colorette": "^1.2.2",
@@ -16711,24 +38248,21 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001234",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001234.tgz",
- "integrity": "sha512-a3gjUVKkmwLdNysa1xkUAwN2VfJUJyVW47rsi3aCbkRCtbHAfo+rOsCqVw29G6coQ8gzAPb5XBXwiGHwme3isA==",
- "dev": true
+ "version": "1.0.30001243",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz",
+ "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA=="
},
"electron-to-chromium": {
- "version": "1.3.749",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.749.tgz",
- "integrity": "sha512-F+v2zxZgw/fMwPz/VUGIggG4ZndDsYy0vlpthi3tjmDZlcfbhN5mYW0evXUsBr2sUtuDANFtle410A9u/sd/4A==",
- "dev": true
+ "version": "1.3.772",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz",
+ "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA=="
},
"schema-utils": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
- "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
- "dev": true,
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.0.tgz",
+ "integrity": "sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w==",
"requires": {
- "@types/json-schema": "^7.0.6",
+ "@types/json-schema": "^7.0.7",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
@@ -16736,15 +38270,15 @@
}
},
"webpack-cli": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.0.tgz",
- "integrity": "sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==",
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.2.tgz",
+ "integrity": "sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw==",
"dev": true,
"requires": {
"@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^1.0.3",
- "@webpack-cli/info": "^1.2.4",
- "@webpack-cli/serve": "^1.4.0",
+ "@webpack-cli/configtest": "^1.0.4",
+ "@webpack-cli/info": "^1.3.0",
+ "@webpack-cli/serve": "^1.5.1",
"colorette": "^1.2.1",
"commander": "^7.0.0",
"execa": "^5.0.0",
@@ -16765,9 +38299,9 @@
}
},
"webpack-merge": {
- "version": "5.7.3",
- "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz",
- "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
+ "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==",
"dev": true,
"requires": {
"clone-deep": "^4.0.1",
@@ -16778,7 +38312,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.0.tgz",
"integrity": "sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==",
- "dev": true,
"requires": {
"source-list-map": "^2.0.1",
"source-map": "^0.6.1"
@@ -16805,13 +38338,13 @@
"dev": true
},
"whatwg-url": {
- "version": "8.5.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.5.0.tgz",
- "integrity": "sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==",
+ "version": "8.7.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
+ "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
"dev": true,
"requires": {
"lodash": "^4.7.0",
- "tr46": "^2.0.2",
+ "tr46": "^2.1.0",
"webidl-conversions": "^6.1.0"
}
},
@@ -16861,7 +38394,6 @@
"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",
@@ -16872,7 +38404,6 @@
"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"
}
@@ -16881,7 +38412,6 @@
"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"
}
@@ -16889,8 +38419,7 @@
"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
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}
}
},
@@ -16912,9 +38441,10 @@
}
},
"ws": {
- "version": "7.4.6",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
- "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
+ "version": "7.5.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz",
+ "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==",
+ "requires": {}
},
"xdg-basedir": {
"version": "4.0.0",
@@ -16937,8 +38467,7 @@
"y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
},
"yallist": {
"version": "4.0.0",
@@ -16956,7 +38485,6 @@
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "dev": true,
"requires": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
@@ -16968,16 +38496,14 @@
}
},
"yargs-parser": {
- "version": "20.2.7",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz",
- "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==",
- "dev": true
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="
},
"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
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
}
}
}
diff --git a/package.json b/package.json
index 1f769cf2..a825aaf1 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,10 @@
"test": "cross-env NODE_ENV=test jest --coverage --detectOpenHandles",
"docker:build": "docker build . --build-arg PACKAGE_VERSION=$(node -p \"require('./package.json').version\") --build-arg GIT_HASH=$(git rev-parse --short HEAD) --build-arg NODE_ENV=production --target production-stage -t chrisleekr/binance-trading-bot:latest",
"docker:build:dev": "docker build . --build-arg PACKAGE_VERSION=$(node -p \"require('./package.json').version\") --build-arg GIT_HASH=$(git rev-parse --short HEAD) --build-arg NODE_ENV=development --target dev-stage -t chrisleekr/binance-trading-bot:latest",
- "docker:build:win": "powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./scripts/docker-build.ps1"
+ "docker:build:win": "powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./scripts/docker-build.ps1",
+ "migrate:create": "./node_modules/.bin/migrate create",
+ "migrate:up": "./node_modules/.bin/migrate up --store=/srv/mongo-state-storage.js",
+ "migrate:down": "./node_modules/.bin/migrate down --store=/srv/mongo-state-storage.js"
},
"repository": {
"type": "git",
@@ -29,41 +32,42 @@
"homepage": "https://github.com/chrisleekr/binance-traiding-bot#readme",
"dependencies": {
"axios": "^0.21.1",
- "binance-api-node": "^0.10.47",
+ "binance-api-node": "^0.11.5",
"bunyan": "^1.8.15",
"clean-webpack-plugin": "^3.0.0",
"config": "^3.3.6",
"cron": "^1.8.2",
"cross-env": "^7.0.3",
"express": "^4.17.1",
- "ioredis": "^4.27.4",
+ "ioredis": "^4.27.6",
"localtunnel": "^2.0.1",
"lodash": "^4.17.21",
"lodash-webpack-plugin": "^0.11.6",
+ "migrate": "^1.7.0",
"moment": "^2.29.1",
"moment-timezone": "^0.5.33",
- "mongodb": "3.6.9",
+ "mongodb": "3.6.10",
"pubsub-js": "^1.9.3",
"redlock": "^4.2.0",
"uuid": "^8.3.2",
- "ws": "^7.4.6"
+ "ws": "^7.5.3"
},
"devDependencies": {
- "@babel/cli": "^7.14.3",
- "@babel/preset-env": "^7.14.4",
- "@types/express": "^4.17.12",
- "@types/jest": "^26.0.23",
- "@types/node": "^15.12.1",
+ "@babel/cli": "^7.14.5",
+ "@babel/preset-env": "^7.14.7",
+ "@types/express": "^4.17.13",
+ "@types/jest": "^26.0.24",
+ "@types/node": "^16.3.1",
"babel-core": "^6.26.3",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.2",
"babel-plugin-lodash": "^3.3.4",
"babel-preset-env": "^1.7.0",
- "eslint": "^7.28.0",
+ "eslint": "^7.30.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-config-react-app": "^6.0.0",
- "eslint-plugin-flowtype": "^5.7.2",
+ "eslint-plugin-flowtype": "^5.8.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jest": "^24.3.6",
"eslint-plugin-jsx-a11y": "^6.4.1",
@@ -72,13 +76,13 @@
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
- "husky": "^6.0.0",
- "jest": "^27.0.4",
+ "husky": "^7.0.1",
+ "jest": "^27.0.6",
"lint-staged": "^11.0.0",
- "nodemon": "^2.0.7",
- "prettier": "^2.3.1",
- "webpack": "^5.38.1",
- "webpack-cli": "^4.7.0"
+ "nodemon": "^2.0.11",
+ "prettier": "^2.3.2",
+ "webpack": "^5.44.0",
+ "webpack-cli": "^4.7.2"
},
"jest": {
"testEnvironment": "node",
diff --git a/public/css/App.css b/public/css/App.css
index 2a44cce2..1356e546 100644
--- a/public/css/App.css
+++ b/public/css/App.css
@@ -384,6 +384,7 @@ input[type='number'] {
width: 100%;
padding-top: 5px;
margin-top: 5px;
+ background-color: #212529;
}
.coin-info-column-title-setting .coin-info-label {
@@ -392,13 +393,24 @@ input[type='number'] {
}
.coin-info-sub-label {
- border-bottom: 1px dotted #cfcfcf;
+ display: block;
+ width: 100%;
+ font-weight: bold;
+ border-bottom: 1px dashed #585858;
}
.coin-info-label,
.coin-info-value {
- width: 50%;
flex: 1 auto;
+ line-height: 23px;
+}
+
+.coin-info-label {
+ width: 65%;
+}
+
+.coin-info-value {
+ width: 35%;
}
.coin-info-column-title .coin-info-label {
@@ -520,6 +532,20 @@ input[type='number'] {
text-decoration: none;
}
+.btn-trigger-grid-trade {
+ padding: 0 0.5rem;
+ font-size: 0.8rem;
+ line-height: 1.5;
+ background-color: rgba(40, 167, 69, 0.95);
+ color: #fff;
+}
+
+.btn-trigger-grid-trade:hover {
+ background-color: rgba(40, 167, 69, 0.85);
+ color: #fff;
+ text-decoration: none;
+}
+
.btn-manual-buy {
background-color: rgb(2, 192, 118);
}
@@ -698,3 +724,48 @@ input[type='number'] {
/**
End: Dust Transfer
*/
+
+/**
+ Start: Grid Trade
+*/
+.btn-add-new-grid-trade-buy {
+ background-color: #02c076;
+ color: white;
+}
+
+.btn-add-new-grid-trade-buy:hover {
+ box-shadow: none;
+ color: white;
+ background-color: #2ed191;
+}
+
+.btn-add-new-grid-trade-sell {
+ background-color: #f84960;
+ color: white;
+}
+
+.btn-add-new-grid-trade-sell:hover {
+ box-shadow: none;
+ color: white;
+ background-color: #ff4265;
+}
+
+.coin-info-column-grid {
+ flex: 1 100%;
+ display: flex;
+ flex-direction: column;
+ border: 1px solid #444546;
+ padding: 3px;
+ margin-bottom: -1px;
+}
+
+.coin-info-column-grid:last-child {
+ margin-bottom: 0;
+}
+
+.coin-info-grid-label {
+ width: 100%;
+}
+/**
+ End: Grid Trade
+*/
diff --git a/public/index.html b/public/index.html
index 10438e97..645563a9 100644
--- a/public/index.html
+++ b/public/index.html
@@ -114,7 +114,8 @@
Col,
InputGroup,
FormControl,
- useAccordionToggle
+ useAccordionToggle,
+ Table
} = ReactBootstrap;
const { Typeahead } = ReactBootstrapTypeahead;
@@ -139,15 +140,16 @@
+
+
+
-
+
+
+
+