From c3c585bd6ee1218e1748280c6399e00101ea0a2e Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 17 May 2021 21:00:30 +0800 Subject: [PATCH 001/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/crontab/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 4263a981..7e0e4464 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -196,7 +196,7 @@ const Crontab = () => { setValue( data.data.sort((a: any, b: any) => { if (a.status === b.status && a.status === CrontabStatus.idle) { - return a.isDisabled - b.isDisable; + return a.isDisabled - b.isDisabled; } return CrontabSort[a.status] - CrontabSort[b.status]; }), From e1c04bb7fbbca635054fdc7d83170266babc628b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 19 May 2021 23:33:13 +0800 Subject: [PATCH 002/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/crontab/index.tsx | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 7e0e4464..c881cb60 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -42,7 +42,7 @@ enum CrontabStatus { 'queued', } -const CrontabSort = [0, 3, 1]; +const CrontabSort: any = { 0: 0, 3: 1, 1: 2, 4: 3 }; enum OperationName { '启用', @@ -188,33 +188,20 @@ const Crontab = () => { const [logCron, setLogCron] = useState(); const [selectedRowIds, setSelectedRowIds] = useState([]); - const getCrons = (needLoading: boolean = true) => { - needLoading && setLoading(true); + const getCrons = () => { + setLoading(true); request .get(`${config.apiPrefix}crons?searchValue=${searchText}`) .then((data: any) => { setValue( data.data.sort((a: any, b: any) => { - if (a.status === b.status && a.status === CrontabStatus.idle) { - return a.isDisabled - b.isDisabled; - } - return CrontabSort[a.status] - CrontabSort[b.status]; + const sortA = a.isDisabled ? 4 : a.status; + const sortB = b.isDisabled ? 4 : b.status; + return CrontabSort[sortA] - CrontabSort[sortB]; }), ); - const runningTasks = data.data.filter( - (x: any) => x.status !== CrontabStatus.idle, - ); - if ( - runningTasks.length > 0 && - !logCron && - location.pathname === '/crontab' - ) { - setTimeout(() => { - getCrons(false); - }, 5000); - } }) - .finally(() => needLoading && setLoading(false)); + .finally(() => setLoading(false)); }; const addCron = () => { From 421b9b8fb9b238b5566725ccab0c393d888bbd3f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 19 May 2021 23:43:06 +0800 Subject: [PATCH 003/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbuild=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 40cbcdfd..8169fd13 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -23,11 +23,12 @@ jobs: env: GITHUB_REPO: gitee.com/whyour/qinglong-static run: | + git config --global http.postBuffer 1048576000 + git config --global user.email "imwhyour@gmail.com" + git config --global user.name "whyour" git clone https://gitee.com/whyour/qinglong-static.git static cd ./static cp -rf ../dist ./ && cp -rf ../build ./ - git config user.name "whyour" - git config user.email "imwhyour@gmail.com" git add . git commit --allow-empty -m "copy static at $(date +'%Y-%m-%d %H:%M:%S')" git push --quiet "https://whyour:${{ secrets.API_TOKEN }}@${GITHUB_REPO}.git" master:master \ No newline at end of file From 05358ed1a442348f127e9869f297c8353310afdc Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 19 May 2021 23:48:38 +0800 Subject: [PATCH 004/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbuild=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 8169fd13..9fe7c834 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -23,7 +23,7 @@ jobs: env: GITHUB_REPO: gitee.com/whyour/qinglong-static run: | - git config --global http.postBuffer 1048576000 + git config --global http.postBuffer 524288000 git config --global user.email "imwhyour@gmail.com" git config --global user.name "whyour" git clone https://gitee.com/whyour/qinglong-static.git static From ab35901ca66bd9c94b2a23cf99039f6325a13be3 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 00:02:33 +0800 Subject: [PATCH 005/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbuild=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 9fe7c834..da3c25b1 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -25,8 +25,9 @@ jobs: run: | git config --global http.postBuffer 524288000 git config --global user.email "imwhyour@gmail.com" + git config --global core.compression 0 git config --global user.name "whyour" - git clone https://gitee.com/whyour/qinglong-static.git static + git clone --depth 1 https://gitee.com/whyour/qinglong-static.git static cd ./static cp -rf ../dist ./ && cp -rf ../build ./ git add . From 78726ab832e1317bfdbcc4286701ab94dff33d5b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 00:32:18 +0800 Subject: [PATCH 006/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95build=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index da3c25b1..33195827 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -23,9 +23,8 @@ jobs: env: GITHUB_REPO: gitee.com/whyour/qinglong-static run: | - git config --global http.postBuffer 524288000 + ifconfig eth0 mtu 14000 git config --global user.email "imwhyour@gmail.com" - git config --global core.compression 0 git config --global user.name "whyour" git clone --depth 1 https://gitee.com/whyour/qinglong-static.git static cd ./static From 87be858220cf4096dec1032d4bb44f2ba517621e Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 00:50:01 +0800 Subject: [PATCH 007/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0build=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 2 +- static | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 160000 static diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 33195827..a543e716 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -23,11 +23,11 @@ jobs: env: GITHUB_REPO: gitee.com/whyour/qinglong-static run: | - ifconfig eth0 mtu 14000 git config --global user.email "imwhyour@gmail.com" git config --global user.name "whyour" git clone --depth 1 https://gitee.com/whyour/qinglong-static.git static cd ./static + rm -rf dist/* && rm -rf build/* cp -rf ../dist ./ && cp -rf ../build ./ git add . git commit --allow-empty -m "copy static at $(date +'%Y-%m-%d %H:%M:%S')" diff --git a/static b/static new file mode 160000 index 00000000..43854dc7 --- /dev/null +++ b/static @@ -0,0 +1 @@ +Subproject commit 43854dc7458590ff62c277eda26020f576b0970a From a6c2a99c14fb855bf62a689c6836809d8119841d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 14:42:15 +0800 Subject: [PATCH 008/247] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static | 1 - 1 file changed, 1 deletion(-) delete mode 160000 static diff --git a/static b/static deleted file mode 160000 index 43854dc7..00000000 --- a/static +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 43854dc7458590ff62c277eda26020f576b0970a From 177150cb754f6d6710d628d12ccf78dfa9c76cc8 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 15:12:54 +0800 Subject: [PATCH 009/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbuild=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 11 +++++------ shell/update.sh | 5 +++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index a543e716..8211d374 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -23,12 +23,11 @@ jobs: env: GITHUB_REPO: gitee.com/whyour/qinglong-static run: | - git config --global user.email "imwhyour@gmail.com" - git config --global user.name "whyour" - git clone --depth 1 https://gitee.com/whyour/qinglong-static.git static + mkdir -p static cd ./static - rm -rf dist/* && rm -rf build/* cp -rf ../dist ./ && cp -rf ../build ./ - git add . + git init && git add . + git config user.name "whyour" + git config user.email "imwhyour@gmail.com" git commit --allow-empty -m "copy static at $(date +'%Y-%m-%d %H:%M:%S')" - git push --quiet "https://whyour:${{ secrets.API_TOKEN }}@${GITHUB_REPO}.git" master:master \ No newline at end of file + git push --force --quiet "https://whyour:${{ secrets.API_TOKEN }}@${GITHUB_REPO}.git" master \ No newline at end of file diff --git a/shell/update.sh b/shell/update.sh index cec93cc2..2da28b57 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -166,7 +166,8 @@ update_repo() { local repo_path="${dir_repo}/${author}_${repo}" if [ -d ${repo_path}/.git ]; then reset_romote_url ${repo_path} ${url} - git_pull_scripts ${repo_path} + git fetch + git reset --hard origin/master >/dev/null 2>&1 else git_clone_scripts ${url} ${repo_path} fi @@ -253,7 +254,7 @@ update_qinglong() { cp -f $file_config_sample $dir_config/config.sample.sh detect_config_version update_depend - + [ -f $dir_root/package.json ] && ql_depend_new=$(cat $dir_root/package.json) [[ "$ql_depend_old" != "$ql_depend_new" ]] && npm_install_2 $dir_root else From 95f8e9953a009bdb4ba5a0bb4820cdb1366c092b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 15:17:32 +0800 Subject: [PATCH 010/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95build=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 8211d374..08771856 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -29,5 +29,6 @@ jobs: git init && git add . git config user.name "whyour" git config user.email "imwhyour@gmail.com" + git config http.postBuffer 524288000 git commit --allow-empty -m "copy static at $(date +'%Y-%m-%d %H:%M:%S')" - git push --force --quiet "https://whyour:${{ secrets.API_TOKEN }}@${GITHUB_REPO}.git" master \ No newline at end of file + git push --force --quiet "https://whyour:${{ secrets.API_TOKEN }}@${GITHUB_REPO}.git" master:master \ No newline at end of file From 65bc4c40e9bcebd0e7ef157d05909d35ee8111eb Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 17:49:54 +0800 Subject: [PATCH 011/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9static=E4=BB=93?= =?UTF-8?q?=E5=82=A8=E5=88=B0github?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 4 ++-- shell/update.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 08771856..1a4d9bf8 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -21,7 +21,8 @@ jobs: - name: copy to static repo env: - GITHUB_REPO: gitee.com/whyour/qinglong-static + # GITHUB_REPO: gitee.com/whyour/qinglong-static + GITHUB_REPO: github.com/whyour/qinglong-static run: | mkdir -p static cd ./static @@ -29,6 +30,5 @@ jobs: git init && git add . git config user.name "whyour" git config user.email "imwhyour@gmail.com" - git config http.postBuffer 524288000 git commit --allow-empty -m "copy static at $(date +'%Y-%m-%d %H:%M:%S')" git push --force --quiet "https://whyour:${{ secrets.API_TOKEN }}@${GITHUB_REPO}.git" master:master \ No newline at end of file diff --git a/shell/update.sh b/shell/update.sh index 2da28b57..af9523b9 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -261,7 +261,7 @@ update_qinglong() { echo -e "\n更新$dir_root失败,请检查原因...\n" fi - local url="https://gitee.com/whyour/qinglong-static.git" + local url="https://ghproxy.com/https://github.com/whyour/qinglong-static.git" if [ -d ${ql_static_repo}/.git ]; then reset_romote_url ${ql_static_repo} ${url} git_pull_scripts ${ql_static_repo} From 1cf40624dae4b80cb2a5cf8efe2068c6cbc6be59 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 18:57:45 +0800 Subject: [PATCH 012/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20update=20?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index af9523b9..844a5279 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -166,8 +166,7 @@ update_repo() { local repo_path="${dir_repo}/${author}_${repo}" if [ -d ${repo_path}/.git ]; then reset_romote_url ${repo_path} ${url} - git fetch - git reset --hard origin/master >/dev/null 2>&1 + git_pull_scripts ${repo_path} else git_clone_scripts ${url} ${repo_path} fi @@ -264,7 +263,8 @@ update_qinglong() { local url="https://ghproxy.com/https://github.com/whyour/qinglong-static.git" if [ -d ${ql_static_repo}/.git ]; then reset_romote_url ${ql_static_repo} ${url} - git_pull_scripts ${ql_static_repo} + git fetch + git reset --hard origin/master >/dev/null 2>&1 else git_clone_scripts ${url} ${ql_static_repo} fi From a10d33adc7777a178740e3b9d88bd53a05f3e498 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 20:56:05 +0800 Subject: [PATCH 013/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=AF=E7=94=A8ck?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E6=9C=AA=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cookie.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/back/services/cookie.ts b/back/services/cookie.ts index 34f0f575..fb84b6df 100644 --- a/back/services/cookie.ts +++ b/back/services/cookie.ts @@ -290,6 +290,7 @@ export default class CookieService { public async enabled(_id: string) { this.cronDb.update({ _id }, { $set: { status: CookieStatus.noacquired } }); + await this.set_cookies(); } public async set_cookies() { From bb469d48477eecacca25ef9462afc644c982e8c0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 21:37:12 +0800 Subject: [PATCH 014/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dck=E5=90=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cookie.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/back/services/cookie.ts b/back/services/cookie.ts index fb84b6df..5ecce83f 100644 --- a/back/services/cookie.ts +++ b/back/services/cookie.ts @@ -284,13 +284,31 @@ export default class CookieService { } public async disabled(_id: string) { - this.cronDb.update({ _id }, { $set: { status: CookieStatus.disabled } }); - await this.set_cookies(); + return new Promise((resolve) => { + this.cronDb.update( + { _id }, + { $set: { status: CookieStatus.disabled } }, + {}, + async (err) => { + await this.set_cookies(); + resolve(true); + }, + ); + }); } public async enabled(_id: string) { - this.cronDb.update({ _id }, { $set: { status: CookieStatus.noacquired } }); - await this.set_cookies(); + return new Promise((resolve) => { + this.cronDb.update( + { _id }, + { $set: { status: CookieStatus.noacquired } }, + {}, + async (err, num) => { + await this.set_cookies(); + resolve(true); + }, + ); + }); } public async set_cookies() { From 189184832eb7b6ad26c07214a240ddda8e5254fe Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 22:04:12 +0800 Subject: [PATCH 015/247] =?UTF-8?q?session=20api=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cookie.ts | 28 ++++++-------- back/services/cookie.ts | 26 +++++++------ back/services/cron.ts | 75 ++++++++++++++++++++++++------------- src/pages/cookie/index.tsx | 42 +++------------------ src/pages/crontab/index.tsx | 4 +- 5 files changed, 83 insertions(+), 92 deletions(-) diff --git a/back/api/cookie.ts b/back/api/cookie.ts index 37d3f2e0..bf75c20f 100644 --- a/back/api/cookie.ts +++ b/back/api/cookie.ts @@ -62,17 +62,15 @@ export default (app: Router) => { ); route.delete( - '/cookies/:id', + '/cookies', celebrate({ - params: Joi.object({ - id: Joi.string().required(), - }), + body: Joi.array().items(Joi.string().required()), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { const cookieService = Container.get(CookieService); - const data = await cookieService.remove(req.params.id); + const data = await cookieService.remove(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -125,18 +123,16 @@ export default (app: Router) => { }, ); - route.get( - '/cookies/:id/disable', + route.put( + '/cookies/disable', celebrate({ - params: Joi.object({ - id: Joi.string().required(), - }), + body: Joi.array().items(Joi.string().required()), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { const cookieService = Container.get(CookieService); - const data = await cookieService.disabled(req.params.id); + const data = await cookieService.disabled(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -145,18 +141,16 @@ export default (app: Router) => { }, ); - route.get( - '/cookies/:id/enable', + route.put( + '/cookies/enable', celebrate({ - params: Joi.object({ - id: Joi.string().required(), - }), + body: Joi.array().items(Joi.string().required()), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { const cookieService = Container.get(CookieService); - const data = await cookieService.enabled(req.params.id); + const data = await cookieService.enabled(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); diff --git a/back/services/cookie.ts b/back/services/cookie.ts index 5ecce83f..802ec192 100644 --- a/back/services/cookie.ts +++ b/back/services/cookie.ts @@ -191,9 +191,13 @@ export default class CookieService { }); } - public async remove(_id: string) { - this.cronDb.remove({ _id }, {}); - await this.set_cookies(); + public async remove(ids: string[]) { + return new Promise((resolve: any) => { + this.cronDb.remove({ _id: { $in: ids } }, {}, async (err) => { + await this.set_cookies(); + resolve(); + }); + }); } public async move( @@ -283,29 +287,29 @@ export default class CookieService { }); } - public async disabled(_id: string) { - return new Promise((resolve) => { + public async disabled(ids: string) { + return new Promise((resolve: any) => { this.cronDb.update( - { _id }, + { _id: { $in: ids } }, { $set: { status: CookieStatus.disabled } }, {}, async (err) => { await this.set_cookies(); - resolve(true); + resolve(); }, ); }); } - public async enabled(_id: string) { - return new Promise((resolve) => { + public async enabled(ids: string) { + return new Promise((resolve: any) => { this.cronDb.update( - { _id }, + { _id: { $in: ids } }, { $set: { status: CookieStatus.noacquired } }, {}, async (err, num) => { await this.set_cookies(); - resolve(true); + resolve(); }, ); }); diff --git a/back/services/cron.ts b/back/services/cron.ts index 3b6b0ef2..b6a9fb64 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -88,8 +88,16 @@ export default class CronService { } public async remove(ids: string[]) { - this.cronDb.remove({ _id: { $in: ids } }, { multi: true }); - await this.set_crontab(true); + return new Promise((resolve: any) => { + this.cronDb.remove( + { _id: { $in: ids } }, + { multi: true }, + async (err) => { + await this.set_crontab(true); + resolve(); + }, + ); + }); } public async crontabs(searchText?: string): Promise { @@ -141,17 +149,21 @@ export default class CronService { } public async stop(ids: string[]) { - this.cronDb.find({ _id: { $in: ids } }).exec((err, docs: Crontab[]) => { - this.cronDb.update( - { _id: { $in: ids } }, - { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, - ); - const pids = docs - .map((x) => x.pid) - .filter((x) => !!x) - .join('\n'); - console.log(pids); - exec(`echo - e "${pids}" | xargs kill - 9`); + return new Promise((resolve: any) => { + this.cronDb.find({ _id: { $in: ids } }).exec((err, docs: Crontab[]) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, + ); + const pids = docs + .map((x) => x.pid) + .filter((x) => !!x) + .join('\n'); + console.log(pids); + exec(`echo - e "${pids}" | xargs kill - 9`, (err) => { + resolve(); + }); + }); }); } @@ -222,21 +234,31 @@ export default class CronService { } public async disabled(ids: string[]) { - this.cronDb.update( - { _id: { $in: ids } }, - { $set: { isDisabled: 1 } }, - { multi: true }, - ); - await this.set_crontab(true); + return new Promise((resolve: any) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { isDisabled: 1 } }, + { multi: true }, + async (err) => { + await this.set_crontab(true); + resolve(); + }, + ); + }); } public async enabled(ids: string[]) { - this.cronDb.update( - { _id: { $in: ids } }, - { $set: { isDisabled: 0 } }, - { multi: true }, - ); - await this.set_crontab(true); + return new Promise((resolve: any) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { isDisabled: 0 } }, + { multi: true }, + async (err) => { + await this.set_crontab(true); + resolve(); + }, + ); + }); } public async log(_id: string) { @@ -289,7 +311,8 @@ export default class CronService { lines.reverse().forEach((line, index) => { line = line.replace(/\t+/g, ' '); - var regex = /^((\@[a-zA-Z]+\s+)|(([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+))/; + var regex = + /^((\@[a-zA-Z]+\s+)|(([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+))/; var command = line.replace(regex, '').trim(); var schedule = line.replace(command, '').trim(); diff --git a/src/pages/cookie/index.tsx b/src/pages/cookie/index.tsx index 00e85337..70e7a5fc 100644 --- a/src/pages/cookie/index.tsx +++ b/src/pages/cookie/index.tsx @@ -187,7 +187,7 @@ const Config = () => { - enabledOrDisabledCron(record, index)}> + enabledOrDisabledCookie(record, index)}> {record.status === Status.已禁用 ? ( ) : ( @@ -222,36 +222,6 @@ const Config = () => { .finally(() => setLoading(false)); }; - const decodeUrl = (val: string) => { - try { - const newUrl = decodeURIComponent(val); - return newUrl; - } catch (error) { - return val; - } - }; - - // useEffect(() => { - // if (value && loading) { - // asyncUpdateStatus(); - // } - // }, [value]); - - const asyncUpdateStatus = async () => { - for (let i = 0; i < value.length; i++) { - const cookie = value[i]; - if (cookie.status === Status.已禁用) { - continue; - } - await sleep(1000); - location.pathname === '/cookie' && refreshStatus(cookie, i); - } - }; - - const sleep = (time: number) => { - return new Promise((resolve) => setTimeout(resolve, time)); - }; - const refreshStatus = (record: any, index: number) => { request .get(`${config.apiPrefix}cookies/${record._id}/refresh`) @@ -265,7 +235,7 @@ const Config = () => { }); }; - const enabledOrDisabledCron = (record: any, index: number) => { + const enabledOrDisabledCookie = (record: any, index: number) => { Modal.confirm({ title: `确认${record.status === Status.已禁用 ? '启用' : '禁用'}`, content: ( @@ -280,12 +250,12 @@ const Config = () => { ), onOk() { request - .get( - `${config.apiPrefix}cookies/${record._id}/${ + .put( + `${config.apiPrefix}cookies/${ record.status === Status.已禁用 ? 'enable' : 'disable' }`, { - data: { _id: record._id }, + data: [record._id], }, ) .then((data: any) => { @@ -340,7 +310,7 @@ const Config = () => { ), onOk() { request - .delete(`${config.apiPrefix}cookies/${record._id}`) + .delete(`${config.apiPrefix}cookies`, { data: [record._id] }) .then((data: any) => { if (data.code === 200) { notification.success({ diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index c881cb60..c89059b3 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -103,7 +103,7 @@ const Crontab = () => { align: 'center' as const, render: (text: string, record: any) => ( <> - {(!record.isDisabled || record.status !== CrontabStatus.idle) && ( + {!record.isDisabled && ( <> {record.status === CrontabStatus.idle && ( } color="default"> @@ -125,7 +125,7 @@ const Crontab = () => { )} )} - {record.isDisabled === 1 && record.status === CrontabStatus.idle && ( + {record.isDisabled === 1 && ( } color="error"> 已禁用 From f70c16be5243d305eae7aa92b8f6cba25917b52e Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 22:17:27 +0800 Subject: [PATCH 016/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dck=E5=90=AF=E7=94=A8?= =?UTF-8?q?=E7=A6=81=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cookie.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/back/services/cookie.ts b/back/services/cookie.ts index 802ec192..016b4052 100644 --- a/back/services/cookie.ts +++ b/back/services/cookie.ts @@ -193,10 +193,14 @@ export default class CookieService { public async remove(ids: string[]) { return new Promise((resolve: any) => { - this.cronDb.remove({ _id: { $in: ids } }, {}, async (err) => { - await this.set_cookies(); - resolve(); - }); + this.cronDb.remove( + { _id: { $in: ids } }, + { multi: true }, + async (err) => { + await this.set_cookies(); + resolve(); + }, + ); }); } @@ -287,12 +291,12 @@ export default class CookieService { }); } - public async disabled(ids: string) { + public async disabled(ids: string[]) { return new Promise((resolve: any) => { this.cronDb.update( { _id: { $in: ids } }, { $set: { status: CookieStatus.disabled } }, - {}, + { multi: true }, async (err) => { await this.set_cookies(); resolve(); @@ -301,12 +305,12 @@ export default class CookieService { }); } - public async enabled(ids: string) { + public async enabled(ids: string[]) { return new Promise((resolve: any) => { this.cronDb.update( { _id: { $in: ids } }, { $set: { status: CookieStatus.noacquired } }, - {}, + { multi: true }, async (err, num) => { await this.set_cookies(); resolve(); From 989bc51f0d85026a873f47db2a346d4e942b7cd0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 20 May 2021 22:39:23 +0800 Subject: [PATCH 017/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgit=20fetch=E9=80=80?= =?UTF-8?q?=E5=87=BA=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/update.sh b/shell/update.sh index 844a5279..9af43ce1 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -263,7 +263,8 @@ update_qinglong() { local url="https://ghproxy.com/https://github.com/whyour/qinglong-static.git" if [ -d ${ql_static_repo}/.git ]; then reset_romote_url ${ql_static_repo} ${url} - git fetch + git fetch --all + exit_status=$? git reset --hard origin/master >/dev/null 2>&1 else git_clone_scripts ${url} ${ql_static_repo} From 703707c480ddbcf67ade062dbff7be6d12e7688e Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 21 May 2021 17:09:59 +0800 Subject: [PATCH 018/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=87=8D=E5=90=AF?= =?UTF-8?q?=E6=97=B6=E9=9D=99=E6=80=81=E8=B5=84=E6=BA=90=E6=B8=85=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/update.sh b/shell/update.sh index 9af43ce1..c938c909 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -271,6 +271,7 @@ update_qinglong() { fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新$ql_static_repo成功...\n" + rm -rf $dir_root/build && rm -rf $dir_root/dist cp -rf $ql_static_repo/* $dir_root echo -e "重启面板中..." nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf From e6869fefa4031faf4ff3af07f5facdd098c43eee Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 21 May 2021 17:14:44 +0800 Subject: [PATCH 019/247] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9D=99=E6=80=81?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E7=89=88=E6=9C=AC=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shell/update.sh b/shell/update.sh index c938c909..2495adf0 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -271,6 +271,10 @@ update_qinglong() { fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新$ql_static_repo成功...\n" + cd $ql_static_repo + commit_id=$(git rev-parse --short HEAD) + echo -e "\n当前静态资源版本 $commit_id...\n" + cd $dir_root rm -rf $dir_root/build && rm -rf $dir_root/dist cp -rf $ql_static_repo/* $dir_root echo -e "重启面板中..." From 12216abcff97ef055a4524445de2485870f0324e Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 21 May 2021 18:43:52 +0800 Subject: [PATCH 020/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20update=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index b6a9fb64..cccda88e 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -168,10 +168,10 @@ export default class CronService { } private async runSingle(id: string): Promise { - return new Promise(async (resolve) => { + return new Promise(async (resolve: any) => { const cron = await this.get(id); if (cron.status !== CrontabStatus.queued) { - resolve(0); + resolve(); return; } @@ -228,7 +228,12 @@ export default class CronService { { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, ); fs.appendFileSync(logFile, `\n执行结束...`); - resolve(code); + resolve(); + }); + + process.on('SIGINT', function () { + fs.appendFileSync(logFile, `\n执行结束...`); + resolve(); }); }); } From 4958d700de2fe4dc707f2e569c77424472d23f0c Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 21 May 2021 18:54:15 +0800 Subject: [PATCH 021/247] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=A2=9D=E5=A4=96?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 8 ++++---- shell/update.sh | 3 ++- src/pages/crontab/index.tsx | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index cccda88e..f9135418 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -199,17 +199,17 @@ export default class CronService { ); cmd.stdout.on('data', (data) => { - this.logger.info(`stdout: ${data}`); + this.logger.silly(`stdout: ${data}`); fs.appendFileSync(logFile, data); }); cmd.stderr.on('data', (data) => { - this.logger.info(`stderr: ${data}`); + this.logger.silly(`stderr: ${data}`); fs.appendFileSync(logFile, data); }); cmd.on('close', (code) => { - this.logger.info(`child process exited with code ${code}`); + this.logger.silly(`child process exited with code ${code}`); this.cronDb.update( { _id }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, @@ -222,7 +222,7 @@ export default class CronService { }); cmd.on('exit', (code: number, signal: any) => { - this.logger.info(`cmd exit ${code}`); + this.logger.silly(`cmd exit ${code}`); this.cronDb.update( { _id }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, diff --git a/shell/update.sh b/shell/update.sh index 2495adf0..f8f90689 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -265,7 +265,7 @@ update_qinglong() { reset_romote_url ${ql_static_repo} ${url} git fetch --all exit_status=$? - git reset --hard origin/master >/dev/null 2>&1 + git reset --hard origin/master else git_clone_scripts ${url} ${ql_static_repo} fi @@ -279,6 +279,7 @@ update_qinglong() { cp -rf $ql_static_repo/* $dir_root echo -e "重启面板中..." nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf + sleep 1 pm2 reload all >/dev/null 2>&1 else echo -e "\n更新$dir_root失败,请检查原因...\n" diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index c89059b3..c881cb60 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -103,7 +103,7 @@ const Crontab = () => { align: 'center' as const, render: (text: string, record: any) => ( <> - {!record.isDisabled && ( + {(!record.isDisabled || record.status !== CrontabStatus.idle) && ( <> {record.status === CrontabStatus.idle && ( } color="default"> @@ -125,7 +125,7 @@ const Crontab = () => { )} )} - {record.isDisabled === 1 && ( + {record.isDisabled === 1 && record.status === CrontabStatus.idle && ( } color="error"> 已禁用 From 91e4905a3f2ca0429dbac4da38c6bb85dc3af8df Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 24 May 2021 20:27:25 +0800 Subject: [PATCH 022/247] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=92=E5=BA=8F=EF=BC=8C=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=80=BB=E6=9D=A1=E6=95=B0=EF=BC=8C#22=20#23?= =?UTF-8?q?=20#173=20#175?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cron.ts | 9 ++++++--- back/services/cron.ts | 2 +- package.json | 1 + sample/config.sample.sh | 3 +++ shell/api.sh | 32 ++++++++++++++++++++++++++++++++ shell/bot.sh | 4 +++- shell/update.sh | 10 +++++++--- src/pages/crontab/index.tsx | 2 ++ src/pages/crontab/logModal.tsx | 17 ++++++++++++++--- 9 files changed, 69 insertions(+), 11 deletions(-) diff --git a/back/api/cron.ts b/back/api/cron.ts index 702ebbeb..ee3f6e4e 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -147,8 +147,8 @@ export default (app: Router) => { '/crons', celebrate({ body: Joi.object({ - command: Joi.string().required(), - schedule: Joi.string().required(), + command: Joi.string().optional(), + schedule: Joi.string().optional(), name: Joi.string().optional(), _id: Joi.string().required(), }), @@ -156,7 +156,10 @@ export default (app: Router) => { async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - if (cron_parser.parseExpression(req.body.schedule).hasNext()) { + if ( + !req.body.schedule || + cron_parser.parseExpression(req.body.schedule).hasNext() + ) { const cronService = Container.get(CronService); const data = await cronService.update(req.body); return res.send({ code: 200, data }); diff --git a/back/services/cron.ts b/back/services/cron.ts index f9135418..85bad819 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -121,7 +121,7 @@ export default class CronService { return new Promise((resolve) => { this.cronDb .find(query) - .sort({ created: 1 }) + .sort({ created: -1 }) .exec((err, docs) => { resolve(docs); }); diff --git a/package.json b/package.json index f4c7760d..f07b5b22 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ }, "devDependencies": { "@ant-design/pro-layout": "^6.5.0", + "@ant-design/icons": "^4.6.2", "@types/cors": "^2.8.10", "@types/express": "^4.17.8", "@types/express-jwt": "^6.0.1", diff --git a/sample/config.sample.sh b/sample/config.sample.sh index dc30b081..abec652d 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -36,6 +36,9 @@ HelpType="" ## 是否自动启动bot,默认不启动,设置为true时自动启动 AutoStartBot="" +## 安装bot依赖时指定pip源,默认使用清华源,如不需要源,设置此参数为空 +PipMirror="https://pypi.tuna.tsinghua.edu.cn/simple" + ## 需组合的环境变量列表,env_name需要和var_name一一对应,如何有新活动按照格式添加(不懂勿动) env_name=( JD_COOKIE diff --git a/shell/api.sh b/shell/api.sh index cd3be60a..af92af55 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -73,6 +73,38 @@ update_cron_api() { fi } +update_cron_command_api() { + local currentTimeStamp=$(date +%s) + if [ $# -eq 1 ]; then + local command=$(echo "$1" | awk -F ":" '{print $1}') + local id=$(echo "$1" | awk -F ":" '{print $2}') + else + local command=$1 + local id=$2 + fi + + local api=$( + curl -s "http://localhost:5600/api/crons?t=$currentTimeStamp" \ + -X 'PUT' \ + -H "Accept: application/json" \ + -H "Authorization: Bearer $token" \ + -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \ + -H "Content-Type: application/json;charset=UTF-8" \ + -H "Origin: http://localhost:5700" \ + -H "Referer: http://localhost:5700/crontab" \ + -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \ + --data-raw "{\"command\":\"$command\",\"_id\":\"$id\"}" \ + --compressed + ) + code=$(echo $api | jq -r .code) + message=$(echo $api | jq -r .message) + if [[ $code == 200 ]]; then + echo -e "$name -> 更新成功" + else + echo -e "$name -> 更新失败(${message})" + fi +} + del_cron_api() { local ids=$1 local currentTimeStamp=$(date +%s) diff --git a/shell/bot.sh b/shell/bot.sh index 3bef23de..3f40121c 100644 --- a/shell/bot.sh +++ b/shell/bot.sh @@ -25,7 +25,9 @@ fi echo -e "\nbot文件下载成功...\n" echo -e "3、安装python3依赖...\n" -pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple +if [[ $PipMirror ]]; then + pip3 config set global.index-url $PipMirror +fi cp -f "$repo_path/jbot/requirements.txt" "$dir_root" pip3 --default-timeout=100 install -r requirements.txt --no-cache-dir echo -e "\npython3依赖安装成功...\n" diff --git a/shell/update.sh b/shell/update.sh index f8f90689..bc57e6ba 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -343,10 +343,14 @@ gen_list_repo() { fi for file in ${files}; do filename=$(basename $file) - cp -f $file $dir_scripts/${author}_${filename} - echo ${author}_${filename} >>"$dir_list_tmp/${repo}_scripts.list" + cp -f $file $dir_scripts/${repo}_${filename} + echo ${repo}_${filename} >>"$dir_list_tmp/${repo}_scripts.list" + cron_id=$(grep -E "$cmd_task ${author}_${filename}" $list_crontab_user | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|") + if [[ $cron_id ]]; then + result=$(update_cron_command_api "$cmd_task ${repo}_${filename}:$cron_id") + fi done - grep -E "$cmd_task $author" $list_crontab_user | perl -pe "s|.*ID=(.*) $cmd_task ($author_.*)\.*|\2|" | awk -F " " '{print $1}' | sort -u >"$dir_list_tmp/${repo}_user.list" + grep -E "$cmd_task $repo" $list_crontab_user | perl -pe "s|.*ID=(.*) $cmd_task ($repo_.*)\.*|\2|" | awk -F " " '{print $1}' | sort -u >"$dir_list_tmp/${repo}_user.list" cd $dir_current } diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index c881cb60..df841b03 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -620,6 +620,8 @@ const Crontab = () => { hideOnSinglePage: true, showSizeChanger: true, defaultPageSize: 20, + showTotal: (total: number, range: number[]) => + `第 ${range[0]}-${range[1]} 条/总共 ${total} 条`, }} dataSource={value} rowKey="_id" diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 6d990176..8ba42d73 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -6,6 +6,7 @@ import { Loading3QuartersOutlined, CheckCircleOutlined, } from '@ant-design/icons'; +import { Controlled as CodeMirror } from 'react-codemirror2'; enum CrontabStatus { 'running', @@ -98,9 +99,19 @@ const CronLogModal = ({ onOk={() => cancel()} onCancel={() => cancel()} > -
-        {!loading && value}
-      
+ {!loading && value && ( + { + setValue(value); + }} + onChange={(editor, data, value) => {}} + /> + )} ); }; From 92056d66b5671aeca50ed601e64414ae3d2023d5 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 24 May 2021 20:52:53 +0800 Subject: [PATCH 023/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcron=20id=E8=8E=B7?= =?UTF-8?q?=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 4 ++-- shell/update.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index af92af55..12b3a0ef 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -99,9 +99,9 @@ update_cron_command_api() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "$name -> 更新成功" + echo -e "$command -> 更新成功" else - echo -e "$name -> 更新失败(${message})" + echo -e "$command -> 更新失败(${message})" fi } diff --git a/shell/update.sh b/shell/update.sh index bc57e6ba..6e105948 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -345,7 +345,7 @@ gen_list_repo() { filename=$(basename $file) cp -f $file $dir_scripts/${repo}_${filename} echo ${repo}_${filename} >>"$dir_list_tmp/${repo}_scripts.list" - cron_id=$(grep -E "$cmd_task ${author}_${filename}" $list_crontab_user | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|") + cron_id=$(cat $list_crontab_user | grep -E "$cmd_task ${author}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|") if [[ $cron_id ]]; then result=$(update_cron_command_api "$cmd_task ${repo}_${filename}:$cron_id") fi From a4c79dfe3b8c798f41adb0130639c535028b04f0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 24 May 2021 22:35:41 +0800 Subject: [PATCH 024/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9D=99=E6=80=81?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E6=8B=89=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/update.sh b/shell/update.sh index 6e105948..86c85d33 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -263,9 +263,11 @@ update_qinglong() { local url="https://ghproxy.com/https://github.com/whyour/qinglong-static.git" if [ -d ${ql_static_repo}/.git ]; then reset_romote_url ${ql_static_repo} ${url} + cd ${ql_static_repo} git fetch --all exit_status=$? git reset --hard origin/master + cd $dir_root else git_clone_scripts ${url} ${ql_static_repo} fi From 09162d503a0e243a7a2d3c07aced98eb28679121 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 24 May 2021 23:04:26 +0800 Subject: [PATCH 025/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E8=AF=BB=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 86c85d33..f7f820a5 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -83,7 +83,7 @@ output_list_add_drop() { ## $1:失效任务清单文件路径 del_cron() { local list_drop=$1 - local author=$2 + local path=$2 local detail="" local ids="" echo -e "开始尝试自动删除失效的定时任务...\n" @@ -117,12 +117,12 @@ del_cron() { ## $1:新任务清单文件路径 add_cron() { local list_add=$1 - local author=$2 + local path=$2 echo -e "开始尝试自动添加定时任务...\n" local detail="" cd $dir_scripts for file in $(cat $list_add); do - local file_name=${file/${author}\_/} + local file_name=${file/${path}\_/} if [ -f $file ]; then cron_line=$( perl -ne "{ @@ -308,13 +308,13 @@ diff_scripts() { if [ -s $list_drop ]; then output_list_add_drop $list_drop "失效" if [[ ${AutoDelCron} == true ]]; then - del_cron $list_drop $2 + del_cron $list_drop $repo fi fi if [ -s $list_add ]; then output_list_add_drop $list_add "新" if [[ ${AutoAddCron} == true ]]; then - add_cron $list_add $2 + add_cron $list_add $repo fi fi cd $dir_current From e28d84dc6b2f5413f0170c0aa06b0077ad562c9a Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 24 May 2021 23:29:35 +0800 Subject: [PATCH 026/247] =?UTF-8?q?antd=20notification=E6=94=B9=E4=B8=BAme?= =?UTF-8?q?ssage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/initData.ts | 2 +- src/layouts/index.less | 10 ++++++++++ src/pages/config/index.tsx | 10 ++++------ src/pages/cookie/index.tsx | 28 +++++++++------------------- src/pages/cookie/modal.tsx | 12 ++++-------- src/pages/crontab/index.tsx | 34 +++++++++------------------------- src/pages/crontab/modal.tsx | 10 +++------- src/pages/diff/index.tsx | 2 +- src/pages/diy/index.tsx | 6 ++---- src/pages/log/index.tsx | 2 +- src/pages/login/index.tsx | 10 +++------- src/utils/http.ts | 8 ++++---- 12 files changed, 51 insertions(+), 83 deletions(-) diff --git a/back/loaders/initData.ts b/back/loaders/initData.ts index 99485edf..927df7f5 100644 --- a/back/loaders/initData.ts +++ b/back/loaders/initData.ts @@ -12,7 +12,7 @@ const initData = [ 6, 1, ).toString()} * * *`, - status: CrontabStatus.idle, + status: CrontabStatus.disabled, }, { name: '删除日志', diff --git a/src/layouts/index.less b/src/layouts/index.less index 01730bfa..d9cc761e 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -6,6 +6,16 @@ body { @import '~codemirror/lib/codemirror.css'; +.CodeMirror { + height: auto; +} + +.CodeMirror-scroll { + height: auto; + overflow-y: hidden; + overflow-x: auto; +} + .ql-container-wrapper { .CodeMirror { position: absolute; diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 763d59f3..0b2ad1c9 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -1,5 +1,5 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, notification, Modal } from 'antd'; +import { Button, message, Modal } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { Controlled as CodeMirror } from 'react-codemirror2'; @@ -16,7 +16,7 @@ const Config = () => { setLoading(true); request .get(`${config.apiPrefix}config/config`) - .then((data) => { + .then((data: any) => { setValue(data.data); }) .finally(() => setLoading(false)); @@ -27,10 +27,8 @@ const Config = () => { .post(`${config.apiPrefix}save`, { data: { content: value, name: 'config.sh' }, }) - .then((data) => { - notification.success({ - message: data.msg, - }); + .then((data: any) => { + message.success(data.msg); }); }; diff --git a/src/pages/cookie/index.tsx b/src/pages/cookie/index.tsx index 70e7a5fc..0624aae8 100644 --- a/src/pages/cookie/index.tsx +++ b/src/pages/cookie/index.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useRef, useState, useEffect } from 'react'; import { Button, - notification, + message, Modal, Table, Tag, @@ -230,7 +230,7 @@ const Config = () => { (value as any).splice(index, 1, data.data); setValue([...(value as any)] as any); } else { - notification.error({ message: '更新状态失败' }); + message.error('更新状态失败'); } }); }; @@ -260,11 +260,9 @@ const Config = () => { ) .then((data: any) => { if (data.code === 200) { - notification.success({ - message: `${ - record.status === Status.已禁用 ? '启用' : '禁用' - }成功`, - }); + message.success( + `${record.status === Status.已禁用 ? '启用' : '禁用'}成功`, + ); const newStatus = record.status === Status.已禁用 ? Status.未获取 : Status.已禁用; const result = [...value]; @@ -274,9 +272,7 @@ const Config = () => { }); setValue(result); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, @@ -313,16 +309,12 @@ const Config = () => { .delete(`${config.apiPrefix}cookies`, { data: [record._id] }) .then((data: any) => { if (data.code === 200) { - notification.success({ - message: '删除成功', - }); + message.success('删除成功'); const result = [...value]; result.splice(index, 1); setValue(result); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, @@ -377,9 +369,7 @@ const Config = () => { }) .then((data: any) => { if (data.code !== 200) { - notification.error({ - message: data, - }); + message.error(data); } }); }, diff --git a/src/pages/cookie/modal.tsx b/src/pages/cookie/modal.tsx index a735e0ee..5459d5de 100644 --- a/src/pages/cookie/modal.tsx +++ b/src/pages/cookie/modal.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { Modal, notification, Input, Form } from 'antd'; +import { Modal, message, Input, Form } from 'antd'; import { request } from '@/utils/http'; import config from '@/utils/config'; @@ -22,7 +22,7 @@ const CookieModal = ({ let flag = false; for (const coo of cookies) { if (!/pt_key=\S*;\s*pt_pin=\S*;\s*/.test(coo)) { - notification.error({ message: `${coo}格式有误` }); + message.error(`${coo}格式有误`); flag = true; break; } @@ -37,13 +37,9 @@ const CookieModal = ({ data: payload, }); if (code === 200) { - notification.success({ - message: cookie ? '更新Cookie成功' : '添加Cookie成功', - }); + message.success(cookie ? '更新Cookie成功' : '添加Cookie成功'); } else { - notification.error({ - message: data, - }); + message.error(data); } setLoading(false); handleCancel(cookie ? [data] : data); diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index df841b03..4baad979 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -1,7 +1,7 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; import { Button, - notification, + message, Modal, Table, Tag, @@ -231,16 +231,12 @@ const Crontab = () => { .delete(`${config.apiPrefix}crons`, { data: [record._id] }) .then((data: any) => { if (data.code === 200) { - notification.success({ - message: '删除成功', - }); + message.success('删除成功'); const result = [...value]; result.splice(index, 1); setValue(result); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, @@ -274,9 +270,7 @@ const Crontab = () => { }); setValue(result); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, @@ -311,9 +305,7 @@ const Crontab = () => { }); setValue(result); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, @@ -356,9 +348,7 @@ const Crontab = () => { }); setValue(result); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, @@ -484,15 +474,11 @@ const Crontab = () => { .delete(`${config.apiPrefix}crons`, { data: selectedRowIds }) .then((data: any) => { if (data.code === 200) { - notification.success({ - message: '批量删除成功', - }); + message.success('批量删除成功'); setSelectedRowIds([]); getCrons(); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, @@ -515,9 +501,7 @@ const Crontab = () => { if (data.code === 200) { getCrons(); } else { - notification.error({ - message: data, - }); + message.error(data); } }); }, diff --git a/src/pages/crontab/modal.tsx b/src/pages/crontab/modal.tsx index 6163afb7..f365ee3e 100644 --- a/src/pages/crontab/modal.tsx +++ b/src/pages/crontab/modal.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { Modal, notification, Input, Form } from 'antd'; +import { Modal, message, Input, Form } from 'antd'; import { request } from '@/utils/http'; import config from '@/utils/config'; import cronParse from 'cron-parser'; @@ -27,13 +27,9 @@ const CronModal = ({ data: payload, }); if (code === 200) { - notification.success({ - message: cron ? '更新Cron成功' : '添加Cron成功', - }); + message.success(cron ? '更新Cron成功' : '添加Cron成功'); } else { - notification.error({ - message: data, - }); + message.error(data); } setLoading(false); handleCancel(data); diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index 43ff3d28..e5d79a0c 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -1,5 +1,5 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, notification, Modal } from 'antd'; +import { Button, message, Modal } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; diff --git a/src/pages/diy/index.tsx b/src/pages/diy/index.tsx index 21879f03..92440e79 100644 --- a/src/pages/diy/index.tsx +++ b/src/pages/diy/index.tsx @@ -1,5 +1,5 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, notification, Modal } from 'antd'; +import { Button, message, Modal } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { Controlled as CodeMirror } from 'react-codemirror2'; @@ -28,9 +28,7 @@ const Crontab = () => { data: { content: value, name: 'extra.sh' }, }) .then((data) => { - notification.success({ - message: data.msg, - }); + message.success(data.msg); }); }; diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index ff65a8a2..9bc8b238 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -1,5 +1,5 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, notification, Modal, TreeSelect } from 'antd'; +import { Button, message, Modal, TreeSelect } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { Controlled as CodeMirror } from 'react-codemirror2'; diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index fe4cf969..ca67de21 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -1,5 +1,5 @@ import React, { Fragment, useEffect } from 'react'; -import { Button, Row, Input, Form, notification } from 'antd'; +import { Button, Row, Input, Form, message } from 'antd'; import config from '@/utils/config'; import { history, Link } from 'umi'; import styles from './index.less'; @@ -21,13 +21,9 @@ const Login = () => { localStorage.setItem(config.authKey, data.token); history.push('/crontab'); } else if (data.code === 100) { - notification.warn({ - message: data.msg, - }); + message.warn(data.msg); } else { - notification.error({ - message: data.msg, - }); + message.error(data.msg); } }) .catch(function (error) { diff --git a/src/utils/http.ts b/src/utils/http.ts index a2aa0024..7c473e6e 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -1,9 +1,9 @@ import { extend } from 'umi-request'; -import { notification } from 'antd'; +import { message } from 'antd'; import config from './config'; -notification.config({ - duration: 2, +message.config({ + duration: 1.5, }); const time = Date.now(); @@ -13,7 +13,7 @@ const errorHandler = function (error: any) { ? error.data.message || error.data : error.response.statusText; if (error.response.status !== 401 && error.response.status !== 502) { - notification.error({ message }); + message.error(message); } else { console.log(error.response); } From 6256acbfca275001d8eca97f57bf734b5bfd19bc Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 24 May 2021 23:39:31 +0800 Subject: [PATCH 027/247] =?UTF-8?q?=E8=B7=9F=E6=96=B0sample=20config?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index abec652d..b10ed4a0 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,6 +1,6 @@ -## Version: v2.0.0 -## Date: 2021-05-16 -## Update Content: 添加并发执行任务数 MaxConcurrentNum +## Version: v2.0.0-05242340 +## Date: 2021-05-24 +## Update Content: 增加pip自定义源\n显示定时任务总条数\n修复同一个作者多仓库定时任务异常删除\n其他bug修复 ## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新 From 630ced445170f7f8ae7a4bfb416addf942f851e8 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 25 May 2021 08:07:40 +0800 Subject: [PATCH 028/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E9=A1=B5=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 16 +++++++++------- src/pages/crontab/logModal.tsx | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index d9cc761e..365661d9 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -6,14 +6,16 @@ body { @import '~codemirror/lib/codemirror.css'; -.CodeMirror { - height: auto; -} +.log-modal-code { + .CodeMirror { + height: auto; + } -.CodeMirror-scroll { - height: auto; - overflow-y: hidden; - overflow-x: auto; + .CodeMirror-scroll { + height: auto; + overflow-y: hidden; + overflow-x: auto; + } } .ql-container-wrapper { diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 8ba42d73..11e92bdb 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -102,6 +102,7 @@ const CronLogModal = ({ {!loading && value && ( Date: Tue, 25 May 2021 11:27:00 +0800 Subject: [PATCH 029/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=8B=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E6=97=A5=E5=BF=97=E6=A0=B7=E5=BC=8F=EF=BC=8C=E5=BF=BD?= =?UTF-8?q?=E7=95=A5cron=E6=90=9C=E7=B4=A2=E5=A4=A7=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 2 +- src/layouts/index.less | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 85bad819..95eb6f44 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -103,7 +103,7 @@ export default class CronService { public async crontabs(searchText?: string): Promise { let query = {}; if (searchText) { - const reg = new RegExp(searchText); + const reg = new RegExp(searchText, 'i'); query = { $or: [ { diff --git a/src/layouts/index.less b/src/layouts/index.less index 365661d9..878beed0 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -16,6 +16,13 @@ body { overflow-y: hidden; overflow-x: auto; } + + .CodeMirror-sizer { + width: 500px; + transform: scale(0.95); + transform-origin: top left; + min-height: auto; + } } .ql-container-wrapper { @@ -78,4 +85,13 @@ body { height: calc(100vh - var(--vh-offset, 0px) - 176px); } } + + .log-modal-code { + .CodeMirror-sizer { + width: 500px; + transform: scale(0.95); + transform-origin: top left; + min-height: auto; + } + } } From fefe7782a938d47bc9fc5108d14085ba216e33e1 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 25 May 2021 17:56:30 +0800 Subject: [PATCH 030/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index 878beed0..95f7be9a 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -16,13 +16,6 @@ body { overflow-y: hidden; overflow-x: auto; } - - .CodeMirror-sizer { - width: 500px; - transform: scale(0.95); - transform-origin: top left; - min-height: auto; - } } .ql-container-wrapper { @@ -89,7 +82,7 @@ body { .log-modal-code { .CodeMirror-sizer { width: 500px; - transform: scale(0.95); + transform: scale(0.9); transform-origin: top left; min-height: auto; } From 99085e5c954922484ea48c2b22c9be52e47cfaee Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 25 May 2021 18:16:53 +0800 Subject: [PATCH 031/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E6=97=A5=E5=BF=97=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index 95f7be9a..5b79677a 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -81,8 +81,8 @@ body { .log-modal-code { .CodeMirror-sizer { - width: 500px; - transform: scale(0.9); + width: 380px; + transform: scale(0.83); transform-origin: top left; min-height: auto; } From 6d32c8653541c579da07de63d0acc282da91323d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 25 May 2021 21:12:56 +0800 Subject: [PATCH 032/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E4=B8=BA=E5=85=A8=E8=B7=AF=E5=BE=84=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=97=A5=E5=BF=97=E7=9B=AE=E5=BD=95=E6=88=AA=E5=8F=96?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/task.sh b/shell/task.sh index 3c938606..11b7a05a 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -113,7 +113,8 @@ run_normal() { fi combine_all log_time=$(date "+%Y-%m-%d-%H-%M-%S") - log_dir="$dir_log/${p1%%.*}" + log_dir_tmp="${p1##*/}" + log_dir="$dir_log/${log_dir_tmp%%.*}" log_path="$log_dir/$log_time.log" make_dir "$log_dir" timeout $command_timeout_time $which_program $p1 2>&1 | tee $log_path From dc0225f1006ed4599a5e46d8490dac87e1320e31 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 27 May 2021 19:45:11 +0800 Subject: [PATCH 033/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/notify.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sample/notify.js b/sample/notify.js index 6711e8f0..b16cb60f 100644 --- a/sample/notify.js +++ b/sample/notify.js @@ -7,7 +7,7 @@ * @param text 通知头 * @param desp 通知体 * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } - * @param author 作者仓库等信息 例:`本脚本免费使用 By:https://github.com/whyour/qinglong` + * @param author 作者仓库等信息 例:`本通知 By:https://github.com/whyour/qinglong` */ const querystring = require('querystring'); @@ -151,14 +151,14 @@ if (process.env.PUSH_PLUS_USER) { * @param text 通知头 * @param desp 通知体 * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' } - * @param author 作者仓库等信息 例:`本脚本免费使用 By:https://github.com/whyour/qinglong` + * @param author 作者仓库等信息 例:`本通知 By:https://github.com/whyour/qinglong` * @returns {Promise} */ async function sendNotify( text, desp, params = {}, - author = '\n\n本脚本免费使用 By:https://github.com/whyour/qinglong', + author = '\n\n本通知 By:https://github.com/whyour/qinglong', ) { //提供6种通知 desp += author; //增加作者信息,防止被贩卖等 From cf52721639f649c10b24dc2944579bbfebd2ca34 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 28 May 2021 17:02:25 +0800 Subject: [PATCH 034/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dentrypoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index ef2b8083..bb6faa13 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -19,7 +19,7 @@ echo -e "nginx启动成功...\n" echo -e "======================4. 启动控制面板========================\n" cd $dir_root -if [[ $(pm2 info panel) ]]; then +if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel else pm2 start $dir_root/build/app.js -n panel @@ -47,6 +47,6 @@ echo -e "容器启动成功..." echo -e "\n请先访问5700端口,登录成功面板之后再执行添加定时任务..." echo -e "############################################################\n" -crond -f +crond -f >/dev/null 2>&1 exec "$@" From 54f03a044ece7702c07595d273218ef6d64f8457 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 28 May 2021 17:14:19 +0800 Subject: [PATCH 035/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dentrypoint=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=B0=E5=A2=9E=E4=BB=BB=E5=8A=A1=E9=80=9A?= =?UTF-8?q?=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 2 +- shell/api.sh | 4 ++-- shell/update.sh | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index bb6faa13..c7529514 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -28,7 +28,7 @@ echo -e "控制面板启动成功...\n" echo -e "======================5. 启动定时任务========================\n" cd $dir_root -if [[ $(pm2 info schedule) ]]; then +if [[ $(pm2 info schedule 2>/dev/null) ]]; then pm2 reload schedule else pm2 start $dir_root/build/schedule.js -n schedule diff --git a/shell/api.sh b/shell/api.sh index 12b3a0ef..2e3b7d81 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -124,9 +124,9 @@ del_cron_api() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "删除成功" + echo -e "成功" else - echo -e "删除失败(${message})" + echo -e "失败(${message})" fi } diff --git a/shell/update.sh b/shell/update.sh index f7f820a5..26114787 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -108,8 +108,7 @@ del_cron() { done if [[ $ids ]]; then result=$(del_cron_api "$ids") - detail="${result}\n\n${detail}" - notify "删除失效任务通知" "$detail" + notify "$path 删除任务${result}" "$detail" fi } @@ -145,7 +144,7 @@ add_cron() { fi fi done - notify "新增任务通知" "$detail" + notify "$path 新增任务" "$detail" } ## 更新仓库 From 68884b37a2a01a1a0918b1616c017b51ad8ffab7 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 28 May 2021 18:02:30 +0800 Subject: [PATCH 036/247] =?UTF-8?q?=E5=88=A0=E9=99=A4bot=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index c7529514..f2389a18 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -39,7 +39,6 @@ if [[ $AutoStartBot == true ]]; then echo -e "======================6. 启动bot========================\n" cd $dir_root ql bot - echo -e "bot启动成功...\n" fi echo -e "############################################################\n" From bcdca5084cee86ac24ae0d03d61ceb104e417bda Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 28 May 2021 23:40:25 +0800 Subject: [PATCH 037/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9log=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 5 ++++- src/layouts/index.less | 21 --------------------- src/pages/crontab/logModal.tsx | 15 +-------------- 3 files changed, 5 insertions(+), 36 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 95eb6f44..0b32e99f 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -182,7 +182,10 @@ export default class CronService { this.logger.silly('Original command: ' + command); let logFile = `${config.manualLogPath}${_id}.log`; - fs.writeFileSync(logFile, `开始执行...\n${new Date().toString()}\n`); + fs.writeFileSync( + logFile, + `开始执行... ${new Date().toLocaleString()}\n\n`, + ); let cmdStr = command; if (!cmdStr.includes('task ') && !cmdStr.includes('ql ')) { diff --git a/src/layouts/index.less b/src/layouts/index.less index 5b79677a..01730bfa 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -6,18 +6,6 @@ body { @import '~codemirror/lib/codemirror.css'; -.log-modal-code { - .CodeMirror { - height: auto; - } - - .CodeMirror-scroll { - height: auto; - overflow-y: hidden; - overflow-x: auto; - } -} - .ql-container-wrapper { .CodeMirror { position: absolute; @@ -78,13 +66,4 @@ body { height: calc(100vh - var(--vh-offset, 0px) - 176px); } } - - .log-modal-code { - .CodeMirror-sizer { - width: 380px; - transform: scale(0.83); - transform-origin: top left; - min-height: auto; - } - } } diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 11e92bdb..e83a153b 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -99,20 +99,7 @@ const CronLogModal = ({ onOk={() => cancel()} onCancel={() => cancel()} > - {!loading && value && ( - { - setValue(value); - }} - onChange={(editor, data, value) => {}} - /> - )} + {!loading && value &&
{value}
} ); }; From 2f894941853131f3bc8c396556a53893361b99fa Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 28 May 2021 23:59:14 +0800 Subject: [PATCH 038/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dlog=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/crontab/logModal.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index e83a153b..3632a148 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -99,7 +99,9 @@ const CronLogModal = ({ onOk={() => cancel()} onCancel={() => cancel()} > - {!loading && value &&
{value}
} + {!loading && value && ( +
{value}
+ )} ); }; From e5ec982891dbc5fdbc0dd81dd7b016d82cfc6c49 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 29 May 2021 11:04:25 +0800 Subject: [PATCH 039/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9reload=20pm2=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/shell/update.sh b/shell/update.sh index 26114787..8dd6427d 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -281,13 +281,27 @@ update_qinglong() { echo -e "重启面板中..." nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf sleep 1 - pm2 reload all >/dev/null 2>&1 + reload_pm2 else echo -e "\n更新$dir_root失败,请检查原因...\n" fi } +reload_pm2() { + if [[ $(pm2 info panel 2>/dev/null) ]]; then + pm2 reload panel >/dev/null 2>&1 + else + pm2 start $dir_root/build/app.js -n panel >/dev/null 2>&1 + fi + + if [[ $(pm2 info schedule 2>/dev/null) ]]; then + pm2 reload schedule >/dev/null 2>&1 + else + pm2 start $dir_root/build/schedule.js -n schedule >/dev/null 2>&1 + fi +} + ## 对比脚本 diff_scripts() { local dir_current=$(pwd) From 06595021cd74944726b30ebd13b8aba3124db66d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 29 May 2021 12:05:36 +0800 Subject: [PATCH 040/247] =?UTF-8?q?=E7=A7=BB=E9=99=A4console.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 1 - src/pages/log/index.tsx | 1 - src/pages/setting/index.tsx | 5 +++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 0b32e99f..c5c718ec 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -159,7 +159,6 @@ export default class CronService { .map((x) => x.pid) .filter((x) => !!x) .join('\n'); - console.log(pids); exec(`echo - e "${pids}" | xargs kill - 9`, (err) => { resolve(); }); diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index 9bc8b238..efa2f9da 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -35,7 +35,6 @@ const Log = () => { }; const getLog = (node: any) => { - console.log(node); setLoading(true); request .get(`${config.apiPrefix}logs/${node.value}`) diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx index fd71edde..a65314c6 100644 --- a/src/pages/setting/index.tsx +++ b/src/pages/setting/index.tsx @@ -104,7 +104,8 @@ const Password = () => { > @@ -116,7 +117,7 @@ const Password = () => { hasFeedback style={{ maxWidth: 300 }} > - + Date: Sat, 29 May 2021 17:44:13 +0800 Subject: [PATCH 041/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=93=E5=BA=93?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=A4=B1=E8=B4=A5=20=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AE=9A=E6=97=B6=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 仓库更新失败时,没找到对应仓库目录,会把其他仓库的脚本添加前缀重复添加到定时。 --- shell/update.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 8dd6427d..830a5cce 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -171,11 +171,10 @@ update_repo() { fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新${repo_path}成功...\n" + diff_scripts $repo_path $author $path $blackword $dependence else echo -e "\n更新${repo_path}失败,请检查原因...\n" fi - - diff_scripts $repo_path $author $path $blackword $dependence } ## 更新所有 raw 文件 From 9eb614b17e43072437059c123166133c012232c6 Mon Sep 17 00:00:00 2001 From: arho Date: Sat, 29 May 2021 17:53:29 +0800 Subject: [PATCH 042/247] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20openssh=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8=E5=AF=86=E9=92=A5=E5=85=8B?= =?UTF-8?q?=E9=9A=86=E7=A7=81=E5=BA=93=20(#207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index d16cfb05..6bc8a2e4 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -22,6 +22,7 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories nginx \ python3 \ jq \ + openssh \ && rm -rf /var/cache/apk/* \ && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo "Asia/Shanghai" > /etc/timezone \ @@ -37,4 +38,4 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && rm -rf /root/.npm \ && pnpm install --prod \ && rm -rf /root/.pnpm-store -ENTRYPOINT ["./docker/docker-entrypoint.sh"] \ No newline at end of file +ENTRYPOINT ["./docker/docker-entrypoint.sh"] From ea56e44669c8650c19aa7b2a3df31b9e12f4501d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 30 May 2021 15:10:44 +0800 Subject: [PATCH 043/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dentrypoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index f2389a18..f448e0cb 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -46,6 +46,6 @@ echo -e "容器启动成功..." echo -e "\n请先访问5700端口,登录成功面板之后再执行添加定时任务..." echo -e "############################################################\n" -crond -f >/dev/null 2>&1 +crond -f exec "$@" From 307207dddd78442b4adbfda0405a32f1c59da860 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 30 May 2021 20:44:40 +0800 Subject: [PATCH 044/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbot=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E6=96=87=E4=BB=B6=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 8 ++++---- shell/bot.sh | 10 +--------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index b10ed4a0..362714d5 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,6 +1,6 @@ -## Version: v2.0.0-05242340 -## Date: 2021-05-24 -## Update Content: 增加pip自定义源\n显示定时任务总条数\n修复同一个作者多仓库定时任务异常删除\n其他bug修复 +## Version: v2.0.0-05302045 +## Date: 2021-05-30 +## Update Content: 增加ql bot命令所需文件提示 ## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新 @@ -33,7 +33,7 @@ AutoHelpOther="" ## 填 2 使用“随机顺序助力模板”,本套脚本内账号间随机顺序助力,每次生成的顺序都不一致。 HelpType="" -## 是否自动启动bot,默认不启动,设置为true时自动启动 +## 是否自动启动bot,默认不启动,设置为true时自动启动,目前需要自行克隆bot仓库所需代码,存到ql目录下,文件夹命名为dockerbot AutoStartBot="" ## 安装bot依赖时指定pip源,默认使用清华源,如不需要源,设置此参数为空 diff --git a/shell/bot.sh b/shell/bot.sh index 3f40121c..e047721f 100644 --- a/shell/bot.sh +++ b/shell/bot.sh @@ -3,21 +3,13 @@ ## 导入通用变量与函数 dir_shell=/ql/shell . $dir_shell/share.sh -repo_path="${dir_repo}/SuMaiKaDe_jddockerbot" -url="https://ghproxy.com/https://github.com/SuMaiKaDe/jddockerbot.git" +repo_path="${dir_repo}/dockerbot" echo -e "\n1、安装bot依赖...\n" apk --no-cache add -f zlib-dev gcc jpeg-dev python3-dev musl-dev freetype-dev echo -e "\nbot依赖安装成功...\n" echo -e "2、下载bot所需文件...\n" -if [ -d ${repo_path}/.git ]; then - reset_romote_url ${repo_path} ${url} - git_pull_scripts ${repo_path} -else - git_clone_scripts ${url} ${repo_path} "master" -fi - cp -rf "$repo_path/jbot" $dir_root if [[ ! -f "$dir_root/config/bot.json" ]]; then cp -f "$repo_path/config/bot.json" "$dir_root/config" From ea2c08be120a98abdaa3b36ffa113bfc17d100cb Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 30 May 2021 20:49:08 +0800 Subject: [PATCH 045/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dconfig=20sample?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 362714d5..354b14fb 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -33,7 +33,7 @@ AutoHelpOther="" ## 填 2 使用“随机顺序助力模板”,本套脚本内账号间随机顺序助力,每次生成的顺序都不一致。 HelpType="" -## 是否自动启动bot,默认不启动,设置为true时自动启动,目前需要自行克隆bot仓库所需代码,存到ql目录下,文件夹命名为dockerbot +## 是否自动启动bot,默认不启动,设置为true时自动启动,目前需要自行克隆bot仓库所需代码,存到ql/repo目录下,文件夹命名为dockerbot AutoStartBot="" ## 安装bot依赖时指定pip源,默认使用清华源,如不需要源,设置此参数为空 From ee4528a8efd3e66dc534d06dce37cc61fbfac92f Mon Sep 17 00:00:00 2001 From: arho Date: Mon, 31 May 2021 20:59:00 +0800 Subject: [PATCH 046/247] =?UTF-8?q?=E8=84=9A=E6=9C=AC=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BC=A0=E5=85=A5=20config.sh=20(#213)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/share.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/share.sh b/shell/share.sh index 7b49c9e6..aaeaec99 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -288,4 +288,4 @@ git_pull_scripts() { detect_termux detect_macos define_cmd -import_config +import_config $1 From b601a3fdbfe0c90881ed2c2a622709fd3cf18ef4 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 3 Jun 2021 23:10:22 +0800 Subject: [PATCH 047/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ghproxy=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=8C=E9=95=9C=E5=83=8F=E6=B7=BB=E5=8A=A0wget?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 3 ++- sample/config.sample.sh | 5 ++++- shell/share.sh | 1 + shell/update.sh | 21 ++++++++++++--------- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 6bc8a2e4..599379c2 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,6 +1,6 @@ FROM node:lts-alpine LABEL maintainer="whyour" -ARG QL_URL=https://ghproxy.com/https://github.com/whyour/qinglong.git +ARG QL_URL=https://github.com/whyour/qinglong.git ARG QL_BRANCH=master ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ LANG=zh_CN.UTF-8 \ @@ -16,6 +16,7 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories moreutils \ git \ curl \ + wget \ tzdata \ perl \ openssl \ diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 354b14fb..9c040605 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,6 +1,6 @@ ## Version: v2.0.0-05302045 ## Date: 2021-05-30 -## Update Content: 增加ql bot命令所需文件提示 +## Update Content: 增加GithubProxyUrl参数,访问github链接不需要代理时,可移除此参数 ## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新 @@ -10,6 +10,9 @@ AutoDelCron="true" ## 在运行 ql repo 命令时,是否自动增加新的本地定时任务 AutoAddCron="true" +## 由于github仓库拉取较慢,所以会默认添加代理前缀,如不需要请移除 +GithubProxyUrl="https://ghproxy.com/" + ## 设置定时任务执行的超时时间,默认1h,后缀"s"代表秒(默认值), "m"代表分, "h"代表小时, "d"代表天 CommandTimeoutTime="1h" diff --git a/shell/share.sh b/shell/share.sh index aaeaec99..9df6d354 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -60,6 +60,7 @@ import_config() { done command_timeout_time=${CommandTimeoutTime:-"1h"} + github_proxy_url=${GithubProxyUrl:-""} } ## 创建目录,$1:目录的绝对路径 diff --git a/shell/update.sh b/shell/update.sh index 830a5cce..d3362409 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -125,12 +125,13 @@ add_cron() { if [ -f $file ]; then cron_line=$( perl -ne "{ - print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*$file_name/ - }" $file | + print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*/ + }" $file | perl -pe "{ - s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*/?$file_name.*|\1|g; - s| | |g - }" | sort -u | head -1 + s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*|\1|g; + s|\*([\d\*])(.*)|\1\2|g; + s| | |g; + }" | sort -u | head -1 ) cron_name=$(grep "new Env" $file | awk -F "'|\"" '{print $2}' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" @@ -193,11 +194,12 @@ update_raw() { cp -f $raw_file_name $dir_scripts/${filename} cron_line=$( perl -ne "{ - print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*$raw_file_name/ + print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*/ }" $raw_file_name | perl -pe "{ - s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*/?$raw_file_name.*|\1|g; - s| | |g + s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*|\1|g; + s|\*([\d\*])(.*)|\1\2|g; + s| | |g; }" | sort -u | head -1 ) cron_name=$(grep "new Env" $raw_file_name | awk -F "'|\"" '{print $2}' | head -1) @@ -244,6 +246,7 @@ usage() { update_qinglong() { echo -e "--------------------------------------------------------------\n" [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) + reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" git_pull_scripts $dir_root if [[ $exit_status -eq 0 ]]; then @@ -258,7 +261,7 @@ update_qinglong() { echo -e "\n更新$dir_root失败,请检查原因...\n" fi - local url="https://ghproxy.com/https://github.com/whyour/qinglong-static.git" + local url="${github_proxy_url}https://github.com/whyour/qinglong-static.git" if [ -d ${ql_static_repo}/.git ]; then reset_romote_url ${ql_static_repo} ${url} cd ${ql_static_repo} From 9c1addae69c86ae9622c6fb6d12d3f6746363a47 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 3 Jun 2021 23:28:36 +0800 Subject: [PATCH 048/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Denv=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index d3362409..bdf636c2 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -96,7 +96,7 @@ del_cron() { fi cron_file="$dir_scripts/${cron}" if [[ -f $cron_file ]]; then - cron_name=$(grep "new Env" $cron_file | awk -F "'|\"" '{print $2}' | head -1) + cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) rm -f $cron_file fi [[ -z $cron_name ]] && cron_name="$cron" @@ -133,7 +133,7 @@ add_cron() { s| | |g; }" | sort -u | head -1 ) - cron_name=$(grep "new Env" $file | awk -F "'|\"" '{print $2}' | head -1) + cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" [[ -z $cron_line ]] && cron_line="0 6 * * *" result=$(add_cron_api "$cron_line:$cmd_task $file:$cron_name") @@ -202,7 +202,7 @@ update_raw() { s| | |g; }" | sort -u | head -1 ) - cron_name=$(grep "new Env" $raw_file_name | awk -F "'|\"" '{print $2}' | head -1) + cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$raw_file_name" [[ -z $cron_line ]] && cron_line="0 6 * * *" if [[ -z $cron_id ]]; then From e4f8c58eab0330642ba1af7ed9c47fef568d6805 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 3 Jun 2021 23:41:40 +0800 Subject: [PATCH 049/247] =?UTF-8?q?github=E4=BB=93=E5=BA=93=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=B7=BB=E5=8A=A0=E9=BB=98=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/test.sh | 3 +++ shell/update.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 shell/test.sh diff --git a/shell/test.sh b/shell/test.sh new file mode 100644 index 00000000..817ae298 --- /dev/null +++ b/shell/test.sh @@ -0,0 +1,3 @@ +url="https://ghproxy.com/https://github.com/zooPanda/zoo.git" +github_proxy_url="https://ghproxy.com/" +echo "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" \ No newline at end of file diff --git a/shell/update.sh b/shell/update.sh index bdf636c2..e6fc219c 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -165,7 +165,7 @@ update_repo() { local repo_path="${dir_repo}/${author}_${repo}" if [ -d ${repo_path}/.git ]; then - reset_romote_url ${repo_path} ${url} + reset_romote_url ${repo_path} "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" git_pull_scripts ${repo_path} else git_clone_scripts ${url} ${repo_path} From 94c2c407d860912dd435f9cfa595f39c4ae0dfde Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 4 Jun 2021 00:02:12 +0800 Subject: [PATCH 050/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcron=20name=E5=8C=B9?= =?UTF-8?q?=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index e6fc219c..ccc51c9b 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -96,7 +96,7 @@ del_cron() { fi cron_file="$dir_scripts/${cron}" if [[ -f $cron_file ]]; then - cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) + cron_name=$(grep "new Env" $cron_file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) rm -f $cron_file fi [[ -z $cron_name ]] && cron_name="$cron" @@ -133,7 +133,7 @@ add_cron() { s| | |g; }" | sort -u | head -1 ) - cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) + cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" [[ -z $cron_line ]] && cron_line="0 6 * * *" result=$(add_cron_api "$cron_line:$cmd_task $file:$cron_name") From 8ebe049d82e9d434eb940e3bd015fd0df2c104e8 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 4 Jun 2021 19:14:56 +0800 Subject: [PATCH 051/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcron=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index ccc51c9b..344c5688 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -125,13 +125,13 @@ add_cron() { if [ -f $file ]; then cron_line=$( perl -ne "{ - print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*/ - }" $file | + print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*$file_name/ + }" $file | perl -pe "{ - s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*|\1|g; - s|\*([\d\*])(.*)|\1\2|g; - s| | |g; - }" | sort -u | head -1 + s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*/?$file_name.*|\1|g; + s|\*([\d\*])(.*)|\1\2|g; + s| | |g; + }" | sort -u | head -1 ) cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" @@ -194,10 +194,10 @@ update_raw() { cp -f $raw_file_name $dir_scripts/${filename} cron_line=$( perl -ne "{ - print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*/ + print if /.*([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*]( |,|\").*$raw_file_name/ }" $raw_file_name | perl -pe "{ - s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*|\1|g; + s|[^\d\*]*(([\d\*]*[\*-\/,\d]*[\d\*] ){4,5}[\d\*]*[\*-\/,\d]*[\d\*])( \|,\|\").*/?$raw_file_name.*|\1|g; s|\*([\d\*])(.*)|\1\2|g; s| | |g; }" | sort -u | head -1 From 73642ba11d6c07b48818930bfd688dcca0eb206d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 4 Jun 2021 20:49:10 +0800 Subject: [PATCH 052/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcron=E6=AD=A3?= =?UTF-8?q?=E5=88=99=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/update.sh b/shell/update.sh index 344c5688..5eba4e96 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -135,6 +135,7 @@ add_cron() { ) cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" + [[ -z $cron_line ]] && cron_line=$(grep "cron:" $file | awk -F ":" '{print $2}' | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" result=$(add_cron_api "$cron_line:$cmd_task $file:$cron_name") echo -e "$result" From 42c71f4b8ba870d580815376269f8df95f26f614 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 5 Jun 2021 11:27:51 +0800 Subject: [PATCH 053/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E4=BA=8C=E7=BB=B4=E7=A0=81=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=EF=BC=8Cpushplus=E4=BD=BF=E7=94=A8https?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/notify.js | 2 +- src/pages/crontab/logModal.tsx | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sample/notify.js b/sample/notify.js index b16cb60f..1f5adcb1 100644 --- a/sample/notify.js +++ b/sample/notify.js @@ -689,7 +689,7 @@ function pushPlusNotify(text, desp) { topic: `${PUSH_PLUS_USER}`, }; const options = { - url: `http://www.pushplus.plus/send`, + url: `https://www.pushplus.plus/send`, body: JSON.stringify(body), headers: { 'Content-Type': ' application/json', diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 3632a148..f7e4904a 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -100,7 +100,9 @@ const CronLogModal = ({ onCancel={() => cancel()} > {!loading && value && ( -
{value}
+
+          {value}
+        
)} ); From e61f2e3ace7abb45a417ce85559bfe511b6b8a95 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 5 Jun 2021 12:33:29 +0800 Subject: [PATCH 054/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/crontab/logModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index f7e4904a..a6fa3117 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -100,7 +100,7 @@ const CronLogModal = ({ onCancel={() => cancel()} > {!loading && value && ( -
+        
           {value}
         
)} From ce323d07032a21d7b082a0800e9d780c947599e9 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 5 Jun 2021 17:08:08 +0800 Subject: [PATCH 055/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20repo=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 5eba4e96..abbc8907 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -173,7 +173,7 @@ update_repo() { fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新${repo_path}成功...\n" - diff_scripts $repo_path $author $path $blackword $dependence + diff_scripts "$repo_path" "$author" "$path" "$blackword" "$dependence" else echo -e "\n更新${repo_path}失败,请检查原因...\n" fi @@ -314,7 +314,7 @@ diff_scripts() { local blackword="$4" local dependence="$5" - gen_list_repo $repo_path $author $path $blackword $dependence + gen_list_repo "$repo_path" "$author" "$path" "$blackword" "$dependence" local repo="${repo_path##*/}" local list_add="$dir_list_tmp/${repo}_add.list" @@ -351,10 +351,10 @@ gen_list_repo() { cd ${repo_path} files=$(find . -name "*.js" | sed 's/^..//') if [[ $path ]]; then - files=$(find . -name "*.js" | sed 's/^..//' | egrep $path) + files=$(echo "$files" | egrep $path) fi if [[ $blackword ]]; then - files=$(find . -name "*.js" | sed 's/^..//' | egrep -v $blackword | egrep $path) + files=$(echo "$files" | egrep -v $blackword) fi if [[ $dependence ]]; then find . -name "*.js" | sed 's/^..//' | egrep $dependence | xargs -i cp {} $dir_scripts From 6549eeaf103e94533c8e78bc417fdcd5eb9793da Mon Sep 17 00:00:00 2001 From: zt8989 <251027705@qq.com> Date: Sun, 6 Jun 2021 15:28:03 +0800 Subject: [PATCH 056/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B7=A6=E4=BE=A7?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E7=AD=9B=E9=80=89=20(#241)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 增加左侧日志筛选 Co-authored-by: 周腾 --- src/layouts/index.less | 4 + src/pages/log/index.less | 0 src/pages/log/index.module.less | 38 +++++++++ src/pages/log/index.tsx | 134 ++++++++++++++++++++++++-------- src/styles/variable.less | 1 + 5 files changed, 146 insertions(+), 31 deletions(-) delete mode 100644 src/pages/log/index.less create mode 100644 src/pages/log/index.module.less create mode 100644 src/styles/variable.less diff --git a/src/layouts/index.less b/src/layouts/index.less index 01730bfa..1fd3fb67 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -1,3 +1,4 @@ +@import '~@/styles/variable.less'; body { height: 100%; overflow-y: hidden; @@ -55,10 +56,13 @@ body { .ant-pro-grid-content.wide .ant-pro-page-container-children-content { height: calc(100vh - 184px); height: calc(100vh - var(--vh-offset, 0px) - 184px); + margin-left: 0; + margin-right: 0; } .CodeMirror { height: calc(100vh - 216px); height: calc(100vh - var(--vh-offset, 0px) - 216px); + width: calc(100vw - 32px); } } .CodeMirror { diff --git a/src/pages/log/index.less b/src/pages/log/index.less deleted file mode 100644 index e69de29b..00000000 diff --git a/src/pages/log/index.module.less b/src/pages/log/index.module.less new file mode 100644 index 00000000..6eed1ad4 --- /dev/null +++ b/src/pages/log/index.module.less @@ -0,0 +1,38 @@ +@import '~@/styles/variable.less'; + +.left-tree { + &-container { + overflow: hidden; + position: relative; + background-color: #fff; + height: calc(100vh - 128px); + height: calc(100vh - var(--vh-offset, 0px) - 128px); + width: @tree-width; + display: flex; + flex-direction: column; + } + &-scroller { + flex: 1; + overflow: auto; + } + &-search { + margin-bottom: 16px; + } +} + +.log-container { + display: flex; +} + +:global { + .log-wrapper { + .ant-pro-grid-content.wide .ant-pro-page-container-children-content { + padding: 0; + background-color: #f8f8f8; + } + + .CodeMirror { + width: calc(100% - 32px - @tree-width); + } + } +} diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index efa2f9da..a18840d8 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -1,9 +1,40 @@ -import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, message, Modal, TreeSelect } from 'antd'; +import { useState, useEffect, useCallback, Key } from 'react'; +import { TreeSelect, Tree, Input } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { Controlled as CodeMirror } from 'react-codemirror2'; import { request } from '@/utils/http'; +import styles from './index.module.less'; + +function getFilterData(keyword: string, data: any) { + const expandedKeys: string[] = []; + if (keyword) { + const tree: any = []; + data.forEach((item: any) => { + if (item.title.includes(keyword)) { + tree.push(item); + expandedKeys.push(...item.children.map((x: any) => x.key)); + } else { + const children: any[] = []; + (item.children || []).forEach((subItem: any) => { + if (subItem.title.includes(keyword)) { + children.push(subItem); + } + }); + if (children.length > 0) { + tree.push({ + ...item, + children, + }); + expandedKeys.push(...children.map((x) => x.key)); + } + } + }); + return { tree, expandedKeys }; + } + return { tree: data, expandedKeys }; +} + const Log = () => { const [width, setWdith] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); @@ -11,12 +42,16 @@ const Log = () => { const [title, setTitle] = useState('请选择日志文件'); const [value, setValue] = useState('请选择日志文件'); const [select, setSelect] = useState(); - const [data, setData] = useState(); + const [data, setData] = useState([]); + const [filterData, setFilterData] = useState([]); const [loading, setLoading] = useState(false); + const [isPhone, setIsPhone] = useState(false); const getConfig = () => { request.get(`${config.apiPrefix}logs`).then((data) => { - setData(formatData(data.dirs) as any); + const result = formatData(data.dirs) as any; + setData(result); + setFilterData(result); }); }; @@ -25,10 +60,13 @@ const Log = () => { x.title = x.name; x.value = x.name; x.disabled = x.isDir; + x.key = x.name; x.children = x.files.map((y: string) => ({ title: y, value: `${x.name}/${y}`, + key: `${x.name}/${y}`, parent: x.name, + isLeaf: true, })); return x; }); @@ -50,15 +88,30 @@ const Log = () => { getLog(node); }; + const onTreeSelect = useCallback((keys: Key[], e: any) => { + onSelect(keys[0], e.node); + }, []); + + const onSearch = useCallback( + (e) => { + const keyword = e.target.value; + const { tree } = getFilterData(keyword, data); + setFilterData(tree); + }, + [data, setFilterData], + ); + useEffect(() => { if (document.body.clientWidth < 768) { setWdith('auto'); setMarginLeft(0); setMarginTop(0); + setIsPhone(true); } else { setWdith('100%'); setMarginLeft(0); setMarginTop(-72); + setIsPhone(false); } getConfig(); }, []); @@ -67,18 +120,20 @@ const Log = () => { , - ]} + extra={ + isPhone && [ + , + ] + } header={{ style: { padding: '4px 16px 4px 15px', @@ -92,21 +147,38 @@ const Log = () => { }, }} > - { - setValue(value); - }} - onChange={(editor, data, value) => {}} - /> +
+ {!isPhone && ( +
+ +
+ +
+
+ )} + { + setValue(value); + }} + onChange={(editor, data, value) => {}} + /> +
); }; diff --git a/src/styles/variable.less b/src/styles/variable.less new file mode 100644 index 00000000..4362a4ae --- /dev/null +++ b/src/styles/variable.less @@ -0,0 +1 @@ +@tree-width: 300px; From a4b2d8444389314f0af1e704afeacc466739283a Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 6 Jun 2021 15:30:14 +0800 Subject: [PATCH 057/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 1 + src/layouts/index.tsx | 12 +++++++++++- src/version.ts | 2 ++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/version.ts diff --git a/shell/update.sh b/shell/update.sh index abbc8907..64301d4c 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -205,6 +205,7 @@ update_raw() { ) cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$raw_file_name" + [[ -z $cron_line ]] && cron_line=$(grep "cron:" $raw_file_name | awk -F ":" '{print $2}' | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" if [[ -z $cron_id ]]; then result=$(add_cron_api "$cron_line:$cmd_task $filename:$cron_name") diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index c855ba92..a8853dd1 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -14,6 +14,7 @@ import 'codemirror/mode/shell/shell.js'; import { request } from '@/utils/http'; import './index.less'; import vhCheck from 'vh-check'; +import { version, changeLog } from '../version'; export default function (props: any) { const logout = () => { @@ -63,7 +64,16 @@ export default function (props: any) { return ( + 控制面板 +
+ + {version} + + + + } menuItemRender={(menuItemProps: any, defaultDom: any) => { if ( menuItemProps.isUrl || diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 00000000..6c551271 --- /dev/null +++ b/src/version.ts @@ -0,0 +1,2 @@ +export const version = 'v2.0.0-111'; +export const changeLog = 'https://t.me/jiaolongwang/101'; From a975166656fa21fec0c7f969a5cc7ae8895fdcc5 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 6 Jun 2021 15:37:00 +0800 Subject: [PATCH 058/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/log/index.module.less | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/log/index.module.less b/src/pages/log/index.module.less index 6eed1ad4..b1f98948 100644 --- a/src/pages/log/index.module.less +++ b/src/pages/log/index.module.less @@ -27,7 +27,6 @@ :global { .log-wrapper { .ant-pro-grid-content.wide .ant-pro-page-container-children-content { - padding: 0; background-color: #f8f8f8; } From a8707e5422e1bff2e9afc1e86a045123dfc0035d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 6 Jun 2021 15:54:54 +0800 Subject: [PATCH 059/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.ts b/src/version.ts index 6c551271..8c1ea99e 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.0.0-111'; +export const version = 'v2.1.0'; export const changeLog = 'https://t.me/jiaolongwang/101'; From 7f1c55c40acc76c17c46c26c4ecf9def2b32dbcd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 7 Jun 2021 00:57:57 +0800 Subject: [PATCH 060/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=A0=87=E9=A2=98=20fix=20256,=20=E4=BF=AE=E6=94=B9=20ql=20upd?= =?UTF-8?q?ate=20=E4=BE=9D=E8=B5=96=E5=AE=89=E8=A3=85=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - pnpm-lock.yaml | 9826 ++++++++++++++++++++++++++++++++++ shell/share.sh | 8 +- shell/update.sh | 4 +- src/app.tsx | 19 + src/assets/logo.png | Bin 65119 -> 0 bytes src/layouts/defaultProps.tsx | 2 +- src/layouts/index.tsx | 1 + 8 files changed, 9851 insertions(+), 10 deletions(-) create mode 100644 pnpm-lock.yaml delete mode 100644 src/assets/logo.png diff --git a/.gitignore b/.gitignore index 43f51e40..5cb8f362 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,6 @@ /yarn-error.log /yarn.lock /package-lock.json -/pnpm-lock.yaml # production /dist diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..e8559c4c --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,9826 @@ +lockfileVersion: 5.3 + +specifiers: + '@ant-design/icons': ^4.6.2 + '@ant-design/pro-layout': ^6.5.0 + '@types/cors': ^2.8.10 + '@types/express': ^4.17.8 + '@types/express-jwt': ^6.0.1 + '@types/jsonwebtoken': ^8.5.0 + '@types/nedb': ^1.8.11 + '@types/node': ^14.11.2 + '@types/node-fetch': ^2.5.8 + '@types/qrcode.react': ^1.0.1 + '@types/react': ^17.0.0 + '@types/react-dom': ^17.0.0 + '@umijs/plugin-antd': ^0.9.1 + '@umijs/test': ^3.3.9 + body-parser: ^1.19.0 + celebrate: ^13.0.3 + codemirror: ^5.59.4 + compression-webpack-plugin: 6.1.1 + cors: ^2.8.5 + cron-parser: ^3.5.0 + darkreader: ^4.9.27 + dotenv: ^8.2.0 + express: ^4.17.1 + express-jwt: ^6.0.0 + got: ^11.8.2 + jsonwebtoken: ^8.5.1 + lint-staged: ^10.0.7 + nedb: ^1.8.0 + node-fetch: ^2.6.1 + node-schedule: ^2.0.0 + nodemon: ^2.0.4 + p-queue: 6.6.2 + prettier: ^2.2.0 + qrcode.react: ^1.0.1 + react: 17.x + react-codemirror2: ^7.2.1 + react-diff-viewer: ^3.1.1 + react-dnd: ^14.0.2 + react-dnd-html5-backend: ^14.0.0 + react-dom: 17.x + reflect-metadata: ^0.1.13 + ts-node: ^9.0.0 + typedi: ^0.8.0 + typescript: ^4.1.2 + umi: ^3.3.9 + umi-request: ^1.3.5 + vh-check: ^2.0.5 + webpack: ^5.28.0 + winston: ^3.3.3 + yorkie: ^2.0.0 + +dependencies: + body-parser: 1.19.0 + celebrate: 13.0.4 + cors: 2.8.5 + cron-parser: 3.5.0 + dotenv: 8.6.0 + express: 4.17.1 + express-jwt: 6.0.0 + got: 11.8.2 + jsonwebtoken: 8.5.1 + nedb: 1.8.0 + node-fetch: 2.6.1 + node-schedule: 2.0.0 + p-queue: 6.6.2 + reflect-metadata: 0.1.13 + typedi: 0.8.0 + winston: 3.3.3 + +devDependencies: + '@ant-design/icons': 4.6.2_react-dom@17.0.2+react@17.0.2 + '@ant-design/pro-layout': 6.18.0_react-dom@17.0.2+react@17.0.2 + '@types/cors': 2.8.10 + '@types/express': 4.17.11 + '@types/express-jwt': 6.0.1 + '@types/jsonwebtoken': 8.5.1 + '@types/nedb': 1.8.11 + '@types/node': 14.14.45 + '@types/node-fetch': 2.5.10 + '@types/qrcode.react': 1.0.1 + '@types/react': 17.0.5 + '@types/react-dom': 17.0.5 + '@umijs/plugin-antd': 0.9.1_5ccfec03b6e15849b3687a64fe975f75 + '@umijs/test': 3.4.20_ts-node@9.1.1 + codemirror: 5.61.0 + compression-webpack-plugin: 6.1.1_webpack@5.37.0 + darkreader: 4.9.32 + lint-staged: 10.5.4 + nodemon: 2.0.7 + prettier: 2.3.0 + qrcode.react: 1.0.1_react@17.0.2 + react: 17.0.2 + react-codemirror2: 7.2.1_codemirror@5.61.0+react@17.0.2 + react-diff-viewer: 3.1.1_react-dom@17.0.2+react@17.0.2 + react-dnd: 14.0.2_695545ed68ea337339babea285839fc0 + react-dnd-html5-backend: 14.0.0 + react-dom: 17.0.2_react@17.0.2 + ts-node: 9.1.1_typescript@4.2.4 + typescript: 4.2.4 + umi: 3.4.20 + umi-request: 1.3.5 + vh-check: 2.0.5 + webpack: 5.37.0 + yorkie: 2.0.0 + +packages: + + /@ant-design/colors/6.0.0: + resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==} + dependencies: + '@ctrl/tinycolor': 3.4.0 + dev: true + + /@ant-design/icons-svg/4.1.0: + resolution: {integrity: sha512-Fi03PfuUqRs76aI3UWYpP864lkrfPo0hluwGqh7NJdLhvH4iRDc3jbJqZIvRDLHKbXrvAfPPV3+zjUccfFvWOQ==} + dev: true + + /@ant-design/icons/4.6.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-QsBG2BxBYU/rxr2eb8b2cZ4rPKAPBpzAR+0v6rrZLp/lnyvflLH3tw1vregK+M7aJauGWjIGNdFmUfpAOtw25A==} + engines: {node: '>=8'} + peerDependencies: + react: '>=16.0.0' + dependencies: + '@ant-design/colors': 6.0.0 + '@ant-design/icons-svg': 4.1.0 + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + transitivePeerDependencies: + - react-dom + dev: true + + /@ant-design/pro-layout/6.18.0_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-w0Va3XpI01pNi6I+wxBn7xtGCVAPeUkGVmeKXLUOykqSBGZWFZPKtYwGg7xOX7cETgJN8QBWTjwtmHfO5Hx/UA==} + peerDependencies: + antd: ^4.x + react: '>=16.9.0' + dependencies: + '@ant-design/icons': 4.6.2_react-dom@17.0.2+react@17.0.2 + '@ant-design/pro-provider': 1.4.12_react-dom@17.0.2+react@17.0.2 + '@ant-design/pro-utils': 1.16.5_react-dom@17.0.2+react@17.0.2 + '@umijs/route-utils': 1.0.37 + '@umijs/use-params': 1.0.3_react@17.0.2 + classnames: 2.3.1 + omit.js: 2.0.2 + path-to-regexp: 2.4.0 + rc-resize-observer: 0.2.6_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + swr: 0.5.6_react@17.0.2 + unstated-next: 1.1.0 + use-json-comparison: 1.0.5_react@17.0.2 + use-media-antd-query: 1.0.7_react@17.0.2 + warning: 4.0.3 + transitivePeerDependencies: + - react-dom + dev: true + + /@ant-design/pro-provider/1.4.12_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-KgdM8H1zQHKFrcWWLVCOU85PhbuyLvedhj6RX3iEtyHQsYrcP8vDNuxzzVW5o5Isqxrz4VxHG9kL0DdIKDp2Ng==} + peerDependencies: + antd: 4.x + react: '>=16.9.0' + dependencies: + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + transitivePeerDependencies: + - react-dom + dev: true + + /@ant-design/pro-utils/1.16.5_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-u8l8sfmTxR2bX9L/+WRFJa65D9MVr4PzOY8HtLxwiGurWWp3nPV+hsg9n48jRsztOxs5EcruInO8j4jLinYjKA==} + peerDependencies: + antd: 4.x + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@ant-design/icons': 4.6.2_react-dom@17.0.2+react@17.0.2 + '@ant-design/pro-provider': 1.4.12_react-dom@17.0.2+react@17.0.2 + classnames: 2.3.1 + fast-deep-equal: 3.1.3 + moment: 2.29.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /@ant-design/react-slick/0.28.3: + resolution: {integrity: sha512-u3onF2VevGRbkGbgpldVX/nzd7LFtLeZJE0x2xIFT2qYHKkJZ6QT/jQ7KqYK4UpeTndoyrbMqLN4DiJza4BVBg==} + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + json2mq: 0.2.0 + lodash: 4.17.21 + resize-observer-polyfill: 1.5.1 + dev: true + + /@babel/code-frame/7.12.13: + resolution: {integrity: sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==} + dependencies: + '@babel/highlight': 7.14.0 + dev: true + + /@babel/core/7.12.10: + resolution: {integrity: sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.12.13 + '@babel/generator': 7.14.2 + '@babel/helper-module-transforms': 7.14.2 + '@babel/helpers': 7.14.0 + '@babel/parser': 7.14.2 + '@babel/template': 7.12.13 + '@babel/traverse': 7.14.2 + '@babel/types': 7.14.2 + convert-source-map: 1.7.0 + debug: 4.3.1 + gensync: 1.0.0-beta.2 + json5: 2.2.0 + lodash: 4.17.21 + semver: 5.7.1 + source-map: 0.5.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator/7.14.2: + resolution: {integrity: sha512-OnADYbKrffDVai5qcpkMxQ7caomHOoEwjkouqnN2QhydAjowFAZcsdecFIRUBdb+ZcruwYE4ythYmF1UBZU5xQ==} + dependencies: + '@babel/types': 7.14.2 + jsesc: 2.5.2 + source-map: 0.5.7 + dev: true + + /@babel/helper-function-name/7.14.2: + resolution: {integrity: sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==} + dependencies: + '@babel/helper-get-function-arity': 7.12.13 + '@babel/template': 7.12.13 + '@babel/types': 7.14.2 + dev: true + + /@babel/helper-get-function-arity/7.12.13: + resolution: {integrity: sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@babel/helper-member-expression-to-functions/7.13.12: + resolution: {integrity: sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@babel/helper-module-imports/7.13.12: + resolution: {integrity: sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@babel/helper-module-transforms/7.14.2: + resolution: {integrity: sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==} + dependencies: + '@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 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-optimise-call-expression/7.12.13: + resolution: {integrity: sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@babel/helper-plugin-utils/7.13.0: + resolution: {integrity: sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==} + dev: true + + /@babel/helper-replace-supers/7.13.12: + resolution: {integrity: sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==} + dependencies: + '@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.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access/7.13.12: + resolution: {integrity: sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@babel/helper-split-export-declaration/7.12.13: + resolution: {integrity: sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@babel/helper-validator-identifier/7.14.0: + resolution: {integrity: sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==} + dev: true + + /@babel/helpers/7.14.0: + resolution: {integrity: sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==} + dependencies: + '@babel/template': 7.12.13 + '@babel/traverse': 7.14.2 + '@babel/types': 7.14.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight/7.14.0: + resolution: {integrity: sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==} + dependencies: + '@babel/helper-validator-identifier': 7.14.0 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser/7.14.2: + resolution: {integrity: sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dev: true + + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.12.10: + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.12.10: + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.12.10: + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.12.10: + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.12.10: + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.12.10: + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.12.10: + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.12.10: + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.12.10: + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.12.10: + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.12.10: + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/plugin-syntax-top-level-await/7.12.13_@babel+core@7.12.10: + resolution: {integrity: sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + '@babel/helper-plugin-utils': 7.13.0 + dev: true + + /@babel/runtime/7.12.5: + resolution: {integrity: sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==} + dependencies: + regenerator-runtime: 0.13.7 + dev: true + + /@babel/runtime/7.14.0: + resolution: {integrity: sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==} + dependencies: + regenerator-runtime: 0.13.7 + dev: true + + /@babel/template/7.12.13: + resolution: {integrity: sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==} + dependencies: + '@babel/code-frame': 7.12.13 + '@babel/parser': 7.14.2 + '@babel/types': 7.14.2 + dev: true + + /@babel/traverse/7.14.2: + resolution: {integrity: sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==} + dependencies: + '@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.3.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types/7.14.2: + resolution: {integrity: sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==} + dependencies: + '@babel/helper-validator-identifier': 7.14.0 + to-fast-properties: 2.0.0 + dev: true + + /@bcoe/v8-coverage/0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@bloomberg/record-tuple-polyfill/0.0.3: + resolution: {integrity: sha512-sBnCqW0nqofE47mxFnw+lvx6kzsQstwaQMVkh66qm/A6IlsnH7WsyGuVXTou8RF2wL4W7ybOoHPvP2WgIo6rhQ==} + dev: true + + /@cnakazawa/watch/1.0.4: + resolution: {integrity: sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==} + engines: {node: '>=0.1.95'} + hasBin: true + dependencies: + exec-sh: 0.3.6 + minimist: 1.2.5 + dev: true + + /@csstools/convert-colors/1.4.0: + resolution: {integrity: sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw==} + engines: {node: '>=4.0.0'} + dev: true + + /@ctrl/tinycolor/3.4.0: + resolution: {integrity: sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==} + engines: {node: '>=10'} + dev: true + + /@dabh/diagnostics/2.0.2: + resolution: {integrity: sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==} + dependencies: + colorspace: 1.1.2 + enabled: 2.0.0 + kuler: 2.0.0 + dev: false + + /@emotion/cache/10.0.29: + resolution: {integrity: sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==} + dependencies: + '@emotion/sheet': 0.9.4 + '@emotion/stylis': 0.8.5 + '@emotion/utils': 0.11.3 + '@emotion/weak-memoize': 0.2.5 + dev: true + + /@emotion/hash/0.8.0: + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + dev: true + + /@emotion/memoize/0.7.4: + resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} + dev: true + + /@emotion/serialize/0.11.16: + resolution: {integrity: sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==} + dependencies: + '@emotion/hash': 0.8.0 + '@emotion/memoize': 0.7.4 + '@emotion/unitless': 0.7.5 + '@emotion/utils': 0.11.3 + csstype: 2.6.17 + dev: true + + /@emotion/sheet/0.9.4: + resolution: {integrity: sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==} + dev: true + + /@emotion/stylis/0.8.5: + resolution: {integrity: sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==} + dev: true + + /@emotion/unitless/0.7.5: + resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} + dev: true + + /@emotion/utils/0.11.3: + resolution: {integrity: sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==} + dev: true + + /@emotion/weak-memoize/0.2.5: + resolution: {integrity: sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==} + dev: true + + /@hapi/hoek/9.2.0: + resolution: {integrity: sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==} + dev: false + + /@hapi/topo/5.0.0: + resolution: {integrity: sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==} + dependencies: + '@hapi/hoek': 9.2.0 + dev: false + + /@istanbuljs/load-nyc-config/1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema/0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console/24.9.0: + resolution: {integrity: sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==} + engines: {node: '>= 6'} + dependencies: + '@jest/source-map': 24.9.0 + chalk: 2.4.2 + slash: 2.0.0 + dev: true + + /@jest/console/26.6.2: + resolution: {integrity: sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + chalk: 4.1.1 + jest-message-util: 26.6.2 + jest-util: 26.6.2 + slash: 3.0.0 + dev: true + + /@jest/core/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/console': 26.6.2 + '@jest/reporters': 26.6.2 + '@jest/test-result': 26.6.2 + '@jest/transform': 26.6.2 + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + ansi-escapes: 4.3.2 + chalk: 4.1.1 + exit: 0.1.2 + graceful-fs: 4.2.6 + jest-changed-files: 26.6.2 + jest-config: 26.6.3_ts-node@9.1.1 + jest-haste-map: 26.6.2 + jest-message-util: 26.6.2 + jest-regex-util: 26.0.0 + jest-resolve: 26.6.2 + jest-resolve-dependencies: 26.6.3 + jest-runner: 26.6.3_ts-node@9.1.1 + jest-runtime: 26.6.3_ts-node@9.1.1 + jest-snapshot: 26.6.2 + jest-util: 26.6.2 + jest-validate: 26.6.2 + jest-watcher: 26.6.2 + micromatch: 4.0.4 + p-each-series: 2.2.0 + rimraf: 3.0.2 + slash: 3.0.0 + strip-ansi: 6.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /@jest/environment/24.9.0: + resolution: {integrity: sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==} + engines: {node: '>= 6'} + dependencies: + '@jest/fake-timers': 24.9.0 + '@jest/transform': 24.9.0 + '@jest/types': 24.9.0 + jest-mock: 24.9.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/environment/26.6.2: + resolution: {integrity: sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/fake-timers': 26.6.2 + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + jest-mock: 26.6.2 + dev: true + + /@jest/fake-timers/24.9.0: + resolution: {integrity: sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==} + engines: {node: '>= 6'} + dependencies: + '@jest/types': 24.9.0 + jest-message-util: 24.9.0 + jest-mock: 24.9.0 + dev: true + + /@jest/fake-timers/26.6.2: + resolution: {integrity: sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + '@sinonjs/fake-timers': 6.0.1 + '@types/node': 14.14.45 + jest-message-util: 26.6.2 + jest-mock: 26.6.2 + jest-util: 26.6.2 + dev: true + + /@jest/globals/26.6.2: + resolution: {integrity: sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/environment': 26.6.2 + '@jest/types': 26.6.2 + expect: 26.6.2 + dev: true + + /@jest/reporters/26.6.2: + resolution: {integrity: sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==} + engines: {node: '>= 10.14.2'} + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 26.6.2 + '@jest/test-result': 26.6.2 + '@jest/transform': 26.6.2 + '@jest/types': 26.6.2 + chalk: 4.1.1 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.1.7 + graceful-fs: 4.2.6 + 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: 26.6.2 + jest-resolve: 26.6.2 + jest-util: 26.6.2 + jest-worker: 26.6.2 + slash: 3.0.0 + source-map: 0.6.1 + string-length: 4.0.2 + terminal-link: 2.1.1 + v8-to-istanbul: 7.1.2 + optionalDependencies: + node-notifier: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/source-map/24.9.0: + resolution: {integrity: sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==} + engines: {node: '>= 6'} + dependencies: + callsites: 3.1.0 + graceful-fs: 4.2.6 + source-map: 0.6.1 + dev: true + + /@jest/source-map/26.6.2: + resolution: {integrity: sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==} + engines: {node: '>= 10.14.2'} + dependencies: + callsites: 3.1.0 + graceful-fs: 4.2.6 + source-map: 0.6.1 + dev: true + + /@jest/test-result/24.9.0: + resolution: {integrity: sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==} + engines: {node: '>= 6'} + dependencies: + '@jest/console': 24.9.0 + '@jest/types': 24.9.0 + '@types/istanbul-lib-coverage': 2.0.3 + dev: true + + /@jest/test-result/26.6.2: + resolution: {integrity: sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/console': 26.6.2 + '@jest/types': 26.6.2 + '@types/istanbul-lib-coverage': 2.0.3 + collect-v8-coverage: 1.0.1 + dev: true + + /@jest/test-sequencer/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/test-result': 26.6.2 + graceful-fs: 4.2.6 + jest-haste-map: 26.6.2 + jest-runner: 26.6.3_ts-node@9.1.1 + jest-runtime: 26.6.3_ts-node@9.1.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /@jest/transform/24.9.0: + resolution: {integrity: sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==} + engines: {node: '>= 6'} + dependencies: + '@babel/core': 7.12.10 + '@jest/types': 24.9.0 + babel-plugin-istanbul: 5.2.0 + chalk: 2.4.2 + convert-source-map: 1.7.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.6 + jest-haste-map: 24.9.0 + jest-regex-util: 24.9.0 + jest-util: 24.9.0 + micromatch: 3.1.10 + pirates: 4.0.1 + realpath-native: 1.1.0 + slash: 2.0.0 + source-map: 0.6.1 + write-file-atomic: 2.4.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/transform/26.6.2: + resolution: {integrity: sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==} + engines: {node: '>= 10.14.2'} + dependencies: + '@babel/core': 7.12.10 + '@jest/types': 26.6.2 + babel-plugin-istanbul: 6.0.0 + chalk: 4.1.1 + convert-source-map: 1.7.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.6 + jest-haste-map: 26.6.2 + jest-regex-util: 26.0.0 + jest-util: 26.6.2 + micromatch: 4.0.4 + pirates: 4.0.1 + slash: 3.0.0 + source-map: 0.6.1 + write-file-atomic: 3.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types/24.9.0: + resolution: {integrity: sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==} + engines: {node: '>= 6'} + dependencies: + '@types/istanbul-lib-coverage': 2.0.3 + '@types/istanbul-reports': 1.1.2 + '@types/yargs': 13.0.11 + dev: true + + /@jest/types/26.6.2: + resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@types/istanbul-lib-coverage': 2.0.3 + '@types/istanbul-reports': 3.0.0 + '@types/node': 14.14.45 + '@types/yargs': 15.0.13 + chalk: 4.1.1 + dev: true + + /@npmcli/move-file/1.1.2: + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + dev: true + + /@qixian.cs/path-to-regexp/6.1.0: + resolution: {integrity: sha512-2jIiLiVZB1jnY7IIRQKtoV8Gnr7XIhk4mC88ONGunZE3hYt5IHUG4BE/6+JiTBjjEWQLBeWnZB8hGpppkufiVw==} + dev: true + + /@react-dnd/asap/4.0.0: + resolution: {integrity: sha512-0XhqJSc6pPoNnf8DhdsPHtUhRzZALVzYMTzRwV4VI6DJNJ/5xxfL9OQUwb8IH5/2x7lSf7nAZrnzUD+16VyOVQ==} + dev: true + + /@react-dnd/invariant/2.0.0: + resolution: {integrity: sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==} + dev: true + + /@react-dnd/shallowequal/2.0.0: + resolution: {integrity: sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==} + dev: true + + /@sideway/address/4.1.2: + resolution: {integrity: sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==} + dependencies: + '@hapi/hoek': 9.2.0 + dev: false + + /@sideway/formula/3.0.0: + resolution: {integrity: sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==} + dev: false + + /@sideway/pinpoint/2.0.0: + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + dev: false + + /@sindresorhus/is/0.14.0: + resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} + engines: {node: '>=6'} + dev: true + + /@sindresorhus/is/4.0.1: + resolution: {integrity: sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==} + engines: {node: '>=10'} + dev: false + + /@sinonjs/commons/1.8.3: + resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers/6.0.1: + resolution: {integrity: sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==} + dependencies: + '@sinonjs/commons': 1.8.3 + dev: true + + /@szmarczak/http-timer/1.1.2: + resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} + engines: {node: '>=6'} + dependencies: + defer-to-connect: 1.1.3 + dev: true + + /@szmarczak/http-timer/4.0.5: + resolution: {integrity: sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==} + engines: {node: '>=10'} + dependencies: + defer-to-connect: 2.0.1 + dev: false + + /@types/babel__core/7.1.14: + resolution: {integrity: sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==} + dependencies: + '@babel/parser': 7.14.2 + '@babel/types': 7.14.2 + '@types/babel__generator': 7.6.2 + '@types/babel__template': 7.4.0 + '@types/babel__traverse': 7.11.1 + dev: true + + /@types/babel__generator/7.6.2: + resolution: {integrity: sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@types/babel__template/7.4.0: + resolution: {integrity: sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==} + dependencies: + '@babel/parser': 7.14.2 + '@babel/types': 7.14.2 + dev: true + + /@types/babel__traverse/7.11.1: + resolution: {integrity: sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw==} + dependencies: + '@babel/types': 7.14.2 + dev: true + + /@types/body-parser/1.19.0: + resolution: {integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==} + dependencies: + '@types/connect': 3.4.34 + '@types/node': 14.14.45 + dev: true + + /@types/cacheable-request/6.0.1: + resolution: {integrity: sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==} + dependencies: + '@types/http-cache-semantics': 4.0.0 + '@types/keyv': 3.1.1 + '@types/node': 14.14.45 + '@types/responselike': 1.0.0 + dev: false + + /@types/connect/3.4.34: + resolution: {integrity: sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==} + dependencies: + '@types/node': 14.14.45 + dev: true + + /@types/cors/2.8.10: + resolution: {integrity: sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==} + dev: true + + /@types/eslint-scope/3.7.0: + resolution: {integrity: sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==} + dependencies: + '@types/eslint': 7.2.10 + '@types/estree': 0.0.47 + dev: true + + /@types/eslint/7.2.10: + resolution: {integrity: sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==} + dependencies: + '@types/estree': 0.0.47 + '@types/json-schema': 7.0.7 + dev: true + + /@types/estree/0.0.47: + resolution: {integrity: sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==} + dev: true + + /@types/express-jwt/6.0.1: + resolution: {integrity: sha512-zB/oXzS8/NTWUzAG343frlqUrsygHPeyYMVcbJ8YYk7rF1G15eUapPgWh0HdeFi51ajFkkUOU+Q540z1Eu4hJQ==} + dependencies: + '@types/express': 4.17.11 + '@types/express-unless': 0.5.1 + dev: true + + /@types/express-serve-static-core/4.17.19: + resolution: {integrity: sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==} + dependencies: + '@types/node': 14.14.45 + '@types/qs': 6.9.6 + '@types/range-parser': 1.2.3 + dev: true + + /@types/express-unless/0.5.1: + resolution: {integrity: sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==} + dependencies: + '@types/express': 4.17.11 + dev: true + + /@types/express/4.17.11: + resolution: {integrity: sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==} + dependencies: + '@types/body-parser': 1.19.0 + '@types/express-serve-static-core': 4.17.19 + '@types/qs': 6.9.6 + '@types/serve-static': 1.13.9 + dev: true + + /@types/graceful-fs/4.1.5: + resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + dependencies: + '@types/node': 14.14.45 + dev: true + + /@types/history/4.7.8: + resolution: {integrity: sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==} + dev: true + + /@types/http-cache-semantics/4.0.0: + resolution: {integrity: sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==} + dev: false + + /@types/istanbul-lib-coverage/2.0.3: + resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==} + dev: true + + /@types/istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.3 + dev: true + + /@types/istanbul-reports/1.1.2: + resolution: {integrity: sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.3 + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/istanbul-reports/3.0.0: + resolution: {integrity: sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/json-schema/7.0.7: + resolution: {integrity: sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==} + dev: true + + /@types/jsonwebtoken/8.5.1: + resolution: {integrity: sha512-rNAPdomlIUX0i0cg2+I+Q1wOUr531zHBQ+cV/28PJ39bSPKjahatZZ2LMuhiguETkCgLVzfruw/ZvNMNkKoSzw==} + dependencies: + '@types/node': 14.14.45 + dev: true + + /@types/keyv/3.1.1: + resolution: {integrity: sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==} + dependencies: + '@types/node': 14.14.45 + dev: false + + /@types/mime/1.3.2: + resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + dev: true + + /@types/nedb/1.8.11: + resolution: {integrity: sha512-qHQRLZ0e6l/XK/2Qb2v5N1ujmdttYkUvnRI4nPIifMy6vYwoAnER10xhX13isWjjQtNsrjNLinZgDDguzPmEKw==} + dependencies: + '@types/node': 14.14.45 + dev: true + + /@types/node-fetch/2.5.10: + resolution: {integrity: sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==} + dependencies: + '@types/node': 14.14.45 + form-data: 3.0.1 + dev: true + + /@types/node/14.14.45: + resolution: {integrity: sha512-DssMqTV9UnnoxDWu959sDLZzfvqCF0qDNRjaWeYSui9xkFe61kKo4l1TWNTQONpuXEm+gLMRvdlzvNHBamzmEw==} + + /@types/normalize-package-data/2.4.0: + resolution: {integrity: sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==} + dev: true + + /@types/parse-json/4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + dev: true + + /@types/prettier/2.2.3: + resolution: {integrity: sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==} + dev: true + + /@types/prop-types/15.7.3: + resolution: {integrity: sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==} + dev: true + + /@types/qrcode.react/1.0.1: + resolution: {integrity: sha512-PcVCjpsiT2KFKfJibOgTQtkt0QQT/6GbQUp1Np/hMPhwUzMJ2DRUkR9j7tXN9Q8X06qukw+RbaJ8lJ22SBod+Q==} + dependencies: + '@types/react': 17.0.5 + dev: true + + /@types/qs/6.9.6: + resolution: {integrity: sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==} + dev: true + + /@types/range-parser/1.2.3: + resolution: {integrity: sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==} + dev: true + + /@types/react-dom/16.9.13: + resolution: {integrity: sha512-34Hr3XnmUSJbUVDxIw/e7dhQn2BJZhJmlAaPyPwfTQyuVS9mV/CeyghFcXyvkJXxI7notQJz8mF8FeCVvloJrA==} + dependencies: + '@types/react': 16.14.6 + dev: true + + /@types/react-dom/17.0.5: + resolution: {integrity: sha512-ikqukEhH4H9gr4iJCmQVNzTB307kROe3XFfHAOTxOXPOw7lAoEXnM5KWTkzeANGL5Ce6ABfiMl/zJBYNi7ObmQ==} + dependencies: + '@types/react': 17.0.5 + dev: true + + /@types/react-router-config/5.0.2: + resolution: {integrity: sha512-WOSetDV3YPxbkVJAdv/bqExJjmcdCi/vpCJh3NfQOy1X15vHMSiMioXIcGekXDJJYhqGUMDo9e337mh508foAA==} + dependencies: + '@types/history': 4.7.8 + '@types/react': 17.0.5 + '@types/react-router': 5.1.14 + dev: true + + /@types/react-router-dom/5.1.7: + resolution: {integrity: sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==} + dependencies: + '@types/history': 4.7.8 + '@types/react': 17.0.5 + '@types/react-router': 5.1.12 + dev: true + + /@types/react-router/5.1.12: + resolution: {integrity: sha512-0bhXQwHYfMeJlCh7mGhc0VJTRm0Gk+Z8T00aiP4702mDUuLs9SMhnd2DitpjWFjdOecx2UXtICK14H9iMnziGA==} + dependencies: + '@types/history': 4.7.8 + '@types/react': 17.0.5 + dev: true + + /@types/react-router/5.1.14: + resolution: {integrity: sha512-LAJpqYUaCTMT2anZheoidiIymt8MuX286zoVFPM3DVb23aQBH0mAkFvzpd4LKqiolV8bBtZWT5Qp7hClCNDENw==} + dependencies: + '@types/history': 4.7.8 + '@types/react': 17.0.5 + dev: true + + /@types/react/16.14.6: + resolution: {integrity: sha512-Ol/aFKune+P0FSFKIgf+XbhGzYGyz0p7g5befSt4rmbzfGLaZR0q7jPew9k7d3bvrcuaL8dPy9Oz3XGZmf9n+w==} + dependencies: + '@types/prop-types': 15.7.3 + '@types/scheduler': 0.16.1 + csstype: 3.0.8 + dev: true + + /@types/react/17.0.5: + resolution: {integrity: sha512-bj4biDB9ZJmGAYTWSKJly6bMr4BLUiBrx9ujiJEoP9XIDY9CTaPGxE5QWN/1WjpPLzYF7/jRNnV2nNxNe970sw==} + dependencies: + '@types/prop-types': 15.7.3 + '@types/scheduler': 0.16.1 + csstype: 3.0.8 + dev: true + + /@types/responselike/1.0.0: + resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + dependencies: + '@types/node': 14.14.45 + dev: false + + /@types/scheduler/0.16.1: + resolution: {integrity: sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==} + dev: true + + /@types/serve-static/1.13.9: + resolution: {integrity: sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==} + dependencies: + '@types/mime': 1.3.2 + '@types/node': 14.14.45 + dev: true + + /@types/stack-utils/1.0.1: + resolution: {integrity: sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==} + dev: true + + /@types/stack-utils/2.0.0: + resolution: {integrity: sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==} + dev: true + + /@types/yargs-parser/20.2.0: + resolution: {integrity: sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==} + dev: true + + /@types/yargs/13.0.11: + resolution: {integrity: sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ==} + dependencies: + '@types/yargs-parser': 20.2.0 + dev: true + + /@types/yargs/15.0.13: + resolution: {integrity: sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==} + dependencies: + '@types/yargs-parser': 20.2.0 + dev: true + + /@umijs/ast/3.4.20: + resolution: {integrity: sha512-yluYEr4styP2hV16el2aHtc3lX2ZKz/Q05S9sehFr0+YfxaHsT7b5QerEb+vbqH9UGSvVUjet/eT/Ch0hyrq8w==} + dependencies: + '@umijs/utils': 3.4.20 + dev: true + + /@umijs/babel-plugin-auto-css-modules/3.4.20: + resolution: {integrity: sha512-kEjK7pnJtsTlzoHSZgmP+Hlx/6lUdYMdP9Lfu3haU9J6XTnMiibRFsy38uS+A1spl8/oD4RduUvPjGxCXM5W6Q==} + dev: true + + /@umijs/babel-plugin-import-to-await-require/3.4.20: + resolution: {integrity: sha512-z4fQA0jOKF/6DLcNUIIGxK3JoSsUjG74MayErQmeosKO2Wq3IprKshrbnMlJHovKCSvOEaZia34yeR9Le7lNRQ==} + dependencies: + '@umijs/utils': 3.4.20 + dev: true + + /@umijs/babel-plugin-lock-core-js-3/3.4.20: + resolution: {integrity: sha512-mJGMwuHb0Y54n6s99CuLYGW2FGrF8PnnB3ynOscC3keQvttmkXlZ/JhjCyM0hpTqo8doi6QhqgTtJ+Iszz3bCw==} + dependencies: + '@umijs/utils': 3.4.20 + core-js: 3.6.5 + dev: true + + /@umijs/babel-plugin-no-anonymous-default-export/3.4.20: + resolution: {integrity: sha512-CrN1TLiFydLgxLGVDahAWdzK0E4ujwiQBTBW5y2rnkkKH5f5G/FKZEjbG5H26VOnDH6uemE5i9su8cAzJ7Nw9A==} + dependencies: + '@umijs/utils': 3.4.20 + dev: true + + /@umijs/babel-preset-umi/3.4.20: + resolution: {integrity: sha512-YUwerpS4jhN1VUYDFQmWXxY8sINFNL9moJx4gLGn/ur6tiZRl/t2y+h/1gFniFkzTNJ0Km4H7QoR8X/POhTEcQ==} + dependencies: + '@babel/runtime': 7.12.5 + '@umijs/babel-plugin-auto-css-modules': 3.4.20 + '@umijs/babel-plugin-import-to-await-require': 3.4.20 + '@umijs/babel-plugin-lock-core-js-3': 3.4.20 + '@umijs/babel-plugin-no-anonymous-default-export': 3.4.20 + dev: true + + /@umijs/bundler-utils/3.4.20: + resolution: {integrity: sha512-xqyfjVHlMUKrfQq0C7apRuMRUgWkVya1ra+XatvsEwyNjgT4+z+Hp8K6iI0dk2j8UWjFaLX8gdEMWMTBOKTrvw==} + dependencies: + '@umijs/babel-preset-umi': 3.4.20 + '@umijs/types': 3.4.20 + '@umijs/utils': 3.4.20 + dev: true + + /@umijs/bundler-webpack/3.4.20: + resolution: {integrity: sha512-FwmvYgzNs29VUieqa/tOGgznLX2o8vpqr3GKgbeJDnXF83masXUrS1t/v9NjhJXR00DJ8n2qk1SJ8WyTRoRlWw==} + hasBin: true + dependencies: + '@umijs/bundler-utils': 3.4.20 + '@umijs/deps': 3.4.20 + '@umijs/types': 3.4.20 + '@umijs/utils': 3.4.20 + jest-worker: 26.6.2 + node-libs-browser: 2.2.1 + normalize-url: 1.9.1 + postcss: 7.0.32 + postcss-flexbugs-fixes: 4.2.1 + postcss-loader: 3.0.0 + postcss-preset-env: 6.7.0 + postcss-safe-parser: 4.0.2 + terser: 5.6.0 + webpack-chain: 6.5.1 + dev: true + + /@umijs/core/3.4.20: + resolution: {integrity: sha512-K4IWjYdmhZmlMIVICUmCIb7p2vugANEIXIBJ6nO2aSwbqTPzlx0NlNhbmzaxKCJrmrwJ9Y4JWp+g09XiIqKwbg==} + dependencies: + '@umijs/ast': 3.4.20 + '@umijs/babel-preset-umi': 3.4.20 + '@umijs/deps': 3.4.20 + '@umijs/utils': 3.4.20 + dev: true + + /@umijs/deps/3.4.20: + resolution: {integrity: sha512-eANA/O/4Bx5xjDhZ0DZAdWdpLNYJWV9S+udUgMvAs1FdxNK0EPY/+yg5VE8Lah57qukj8EYH6mtBoukO97+8Xg==} + dependencies: + '@bloomberg/record-tuple-polyfill': 0.0.3 + chokidar: 3.5.1 + clipboardy: 2.3.0 + jest-worker: 24.9.0 + prettier: 2.2.1 + dev: true + + /@umijs/plugin-antd/0.9.1_5ccfec03b6e15849b3687a64fe975f75: + resolution: {integrity: sha512-MG+RifLIovPRvf5qPUfTIRqkiq1QBaKCE/pP3mM72DwAkDh6ZXn8oql/8tqFR3k1+m3XUbDEiOCH+Zx+eNiFew==} + peerDependencies: + umi: 3.x + dependencies: + antd: 4.15.5_react-dom@17.0.2+react@17.0.2 + antd-mobile: 2.3.4 + umi: 3.4.20 + transitivePeerDependencies: + - dayjs + - react + - react-dom + dev: true + + /@umijs/preset-built-in/3.4.20_react-dom@16.14.0+react@16.14.0: + resolution: {integrity: sha512-Qvgcct4XY73p7nJaAnUl14SVv6IBixt9SLH/q0aMI+4ZyICgUXqKp3uibR+uXeo6OgtyStcdhp2uyThXoeJC9A==} + peerDependencies: + react: 16.x || 17.x + dependencies: + '@types/react-router-config': 5.0.2 + '@umijs/babel-preset-umi': 3.4.20 + '@umijs/bundler-webpack': 3.4.20 + '@umijs/deps': 3.4.20 + '@umijs/renderer-mpa': 3.4.20_react-dom@16.14.0+react@16.14.0 + '@umijs/renderer-react': 3.4.20_39566ec7cc5fe716a59f91f7330320ef + '@umijs/runtime': 3.4.20_react@16.14.0 + '@umijs/server': 3.4.20 + '@umijs/types': 3.4.20 + '@umijs/utils': 3.4.20 + es5-imcompatible-versions: 0.1.69 + history-with-query: 4.10.4 + react: 16.14.0 + react-refresh: 0.9.0 + react-router: 5.2.0_react@16.14.0 + react-router-config: 5.1.1_react-router@5.2.0+react@16.14.0 + react-router-dom: 5.2.0_react@16.14.0 + regenerator-runtime: 0.13.5 + transitivePeerDependencies: + - react-dom + dev: true + + /@umijs/renderer-mpa/3.4.20_react-dom@16.14.0+react@16.14.0: + resolution: {integrity: sha512-bp71yrHiIogv2kFsU37iRWw1zH+9bXD+7F1JO8JiOLPr0xlyRxqDcOrZdQdlbLNARHtWbi8KVAtpGvLSa9V+aw==} + peerDependencies: + react: 16.x || 17.x + react-dom: 16.x || 17.x + dependencies: + '@types/react': 16.14.6 + '@types/react-dom': 16.9.13 + '@umijs/runtime': 3.4.20_react@16.14.0 + react: 16.14.0 + react-dom: 16.14.0_react@16.14.0 + dev: true + + /@umijs/renderer-react/3.4.20_39566ec7cc5fe716a59f91f7330320ef: + resolution: {integrity: sha512-Z8rkeG4Fh3t8SBd6eIMuRHFTVZX+1Hv+GmvD9UaEbeIy+uOr/OWuPIMkKt+ZqTv1GTHACgaSjiYLUymz2hgVEw==} + peerDependencies: + react: 16.x || 17.x + react-dom: 16.x || 17.x + dependencies: + '@types/react': 16.14.6 + '@types/react-dom': 16.9.13 + '@types/react-router-config': 5.0.2 + '@umijs/runtime': 3.4.20_react@16.14.0 + react: 16.14.0 + react-dom: 16.14.0_react@16.14.0 + react-router-config: 5.1.1_react-router@5.2.0+react@16.14.0 + transitivePeerDependencies: + - react-router + dev: true + + /@umijs/route-utils/1.0.37: + resolution: {integrity: sha512-RQYMYd0w3mKWlCvhUqYN2/dcCD8LxQWsr46DXpaLtqe2Y/8662qXA3E6moaFpyfokKJK6UHt2VxNGhkKPNJIgQ==} + dependencies: + '@qixian.cs/path-to-regexp': 6.1.0 + fast-deep-equal: 3.1.3 + lodash.isequal: 4.5.0 + memoize-one: 5.2.1 + dev: true + + /@umijs/runtime/3.4.20_react@16.14.0: + resolution: {integrity: sha512-nQwDxDGmJIxMo/9vnNGQk2TVOpNokUf0cel/ROZvvWAvz5UqYUMmh80OpAW+C72qnZazKEqn4IzNUXf4K+LWWg==} + peerDependencies: + react: 16.x || 17.x + dependencies: + '@types/react-router': 5.1.12 + '@types/react-router-dom': 5.1.7 + history-with-query: 4.10.4 + react: 16.14.0 + react-router: 5.2.0_react@16.14.0 + react-router-dom: 5.2.0_react@16.14.0 + use-subscription: 1.5.1_react@16.14.0 + dev: true + + /@umijs/server/3.4.20: + resolution: {integrity: sha512-W3NMKW1oIuQOKYDfaHE+XEOzRa/tvcj9amT85R2RNZafNdk/uDBhf6tuXnKPKo3s6UQzQ3c2TnSrjRT4TiKgNg==} + dependencies: + '@umijs/deps': 3.4.20 + '@umijs/utils': 3.4.20 + dev: true + + /@umijs/test/3.4.20_ts-node@9.1.1: + resolution: {integrity: sha512-SZ6p5liWzYowpvRFufPxMSQ6KKjOz27lNFqn4xq5H5SwsKxsxiNxmsu4OaQIprGs1jQ76XWCfq5vpkmy4D+Jtg==} + hasBin: true + dependencies: + '@babel/core': 7.12.10 + '@umijs/babel-preset-umi': 3.4.20 + '@umijs/utils': 3.4.20 + babel-core: 7.0.0-bridge.0_@babel+core@7.12.10 + babel-jest: 26.6.3_@babel+core@7.12.10 + core-js: 3.8.2 + identity-obj-proxy: 3.0.0 + jest: 26.6.3_ts-node@9.1.1 + jest-cli: 26.6.3_ts-node@9.1.1 + jest-environment-jsdom-fourteen: 1.0.1 + regenerator-runtime: 0.13.7 + whatwg-fetch: 3.6.2 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /@umijs/types/3.4.20: + resolution: {integrity: sha512-NknuWFeiNLZrUFbSxzuMzco4+xtu/g852T8zemK/qU1P94RhcgZ4/3BdcS8UgYoi7QUyjI6vKaL3KLzCT7dGFg==} + dependencies: + '@umijs/babel-preset-umi': 3.4.20 + '@umijs/core': 3.4.20 + '@umijs/deps': 3.4.20 + '@umijs/server': 3.4.20 + '@umijs/utils': 3.4.20 + webpack-chain: 6.5.1 + dev: true + + /@umijs/use-params/1.0.3_react@17.0.2: + resolution: {integrity: sha512-gob94yiBsyFNeRKG+zK2nAKxqVsEkYh4vWM3sSyqwidHoUR+C7MmZUHXBBtB1/9C0dpRAi9arkUYvzuNla6q7Q==} + peerDependencies: + react: '*' + dependencies: + react: 17.0.2 + dev: true + + /@umijs/utils/3.4.20: + resolution: {integrity: sha512-aWjmwd6EE0lzgJr3htHbzVeyh3o66wxtXnFjcAG5MC3rcMx6fv7UftrbpQJ5scgfKxv0nMu9g80XYLJBM6aI+g==} + dependencies: + '@umijs/deps': 3.4.20 + dev: true + + /@webassemblyjs/ast/1.11.0: + resolution: {integrity: sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.0 + '@webassemblyjs/helper-wasm-bytecode': 1.11.0 + dev: true + + /@webassemblyjs/floating-point-hex-parser/1.11.0: + resolution: {integrity: sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==} + dev: true + + /@webassemblyjs/helper-api-error/1.11.0: + resolution: {integrity: sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==} + dev: true + + /@webassemblyjs/helper-buffer/1.11.0: + resolution: {integrity: sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==} + dev: true + + /@webassemblyjs/helper-numbers/1.11.0: + resolution: {integrity: sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.0 + '@webassemblyjs/helper-api-error': 1.11.0 + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/helper-wasm-bytecode/1.11.0: + resolution: {integrity: sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==} + dev: true + + /@webassemblyjs/helper-wasm-section/1.11.0: + resolution: {integrity: sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==} + dependencies: + '@webassemblyjs/ast': 1.11.0 + '@webassemblyjs/helper-buffer': 1.11.0 + '@webassemblyjs/helper-wasm-bytecode': 1.11.0 + '@webassemblyjs/wasm-gen': 1.11.0 + dev: true + + /@webassemblyjs/ieee754/1.11.0: + resolution: {integrity: sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==} + dependencies: + '@xtuc/ieee754': 1.2.0 + dev: true + + /@webassemblyjs/leb128/1.11.0: + resolution: {integrity: sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==} + dependencies: + '@xtuc/long': 4.2.2 + dev: true + + /@webassemblyjs/utf8/1.11.0: + resolution: {integrity: sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==} + dev: true + + /@webassemblyjs/wasm-edit/1.11.0: + resolution: {integrity: sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==} + dependencies: + '@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 + dev: true + + /@webassemblyjs/wasm-gen/1.11.0: + resolution: {integrity: sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==} + dependencies: + '@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 + dev: true + + /@webassemblyjs/wasm-opt/1.11.0: + resolution: {integrity: sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==} + dependencies: + '@webassemblyjs/ast': 1.11.0 + '@webassemblyjs/helper-buffer': 1.11.0 + '@webassemblyjs/wasm-gen': 1.11.0 + '@webassemblyjs/wasm-parser': 1.11.0 + dev: true + + /@webassemblyjs/wasm-parser/1.11.0: + resolution: {integrity: sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==} + dependencies: + '@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 + dev: true + + /@webassemblyjs/wast-printer/1.11.0: + resolution: {integrity: sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==} + dependencies: + '@webassemblyjs/ast': 1.11.0 + '@xtuc/long': 4.2.2 + dev: true + + /@xtuc/ieee754/1.2.0: + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + dev: true + + /@xtuc/long/4.2.2: + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + dev: true + + /abab/2.0.5: + resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==} + dev: true + + /abbrev/1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /accepts/1.3.7: + resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.30 + negotiator: 0.6.2 + dev: false + + /acorn-globals/4.3.4: + resolution: {integrity: sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==} + dependencies: + acorn: 6.4.2 + acorn-walk: 6.2.0 + dev: true + + /acorn-globals/6.0.0: + resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + dev: true + + /acorn-walk/6.2.0: + resolution: {integrity: sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn-walk/7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn/6.4.2: + resolution: {integrity: sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn/7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn/8.2.4: + resolution: {integrity: sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /add-dom-event-listener/1.1.0: + resolution: {integrity: sha512-WCxx1ixHT0GQU9hb0KI/mhgRQhnU+U3GvwY6ZvVjYq8rsihIGoaIOUbY0yMPBxLH5MDtr0kz3fisWGNcbWW7Jw==} + dependencies: + object-assign: 4.1.1 + dev: true + + /aggregate-error/3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv-errors/1.0.1_ajv@6.12.6: + resolution: {integrity: sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==} + peerDependencies: + ajv: '>=5.0.0' + dependencies: + ajv: 6.12.6 + dev: true + + /ajv-keywords/3.5.2_ajv@6.12.6: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + dependencies: + ajv: 6.12.6 + dev: true + + /ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-align/3.0.0: + resolution: {integrity: sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==} + dependencies: + string-width: 3.1.0 + dev: true + + /ansi-colors/4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + dev: true + + /ansi-escapes/4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex/4.1.0: + resolution: {integrity: sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==} + engines: {node: '>=6'} + dev: true + + /ansi-regex/5.0.0: + resolution: {integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==} + engines: {node: '>=8'} + dev: true + + /ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /antd-mobile/2.3.4: + resolution: {integrity: sha512-Uw02Ghc+DPzaQceJQ+5p1ZnQFafvILA0chTTen7m7c89Uzbw6Ny3zsVZDE1gfteNEIsL4JpPe0I/+aI3Q/nPAA==} + dependencies: + array-tree-filter: 2.1.0 + babel-runtime: 6.26.0 + classnames: 2.3.1 + normalize.css: 7.0.0 + rc-checkbox: 2.0.3 + rc-collapse: 1.9.3 + rc-slider: 8.2.0 + rc-swipeout: 2.0.11 + rmc-calendar: 1.1.4 + rmc-cascader: 5.0.3 + rmc-date-picker: 6.0.10 + rmc-dialog: 1.1.1 + rmc-drawer: 0.4.11 + rmc-feedback: 2.0.0 + rmc-input-number: 1.0.5 + rmc-list-view: 0.11.5 + rmc-notification: 1.0.0 + rmc-nuka-carousel: 3.0.1 + rmc-picker: 5.0.10 + rmc-pull-to-refresh: 1.0.13 + rmc-steps: 1.0.1 + rmc-tabs: 1.2.29 + rmc-tooltip: 1.0.1 + dev: true + + /antd/4.15.5_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-zpdwZmdxZfSCVq6t329jXzq4oHZDDrMsD3L/bNilBJz9Y8yJZ0b4wGrWK7TSRipP2KcUB5Udm+bmfv2RBuzzNA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@ant-design/colors': 6.0.0 + '@ant-design/icons': 4.6.2_react-dom@17.0.2+react@17.0.2 + '@ant-design/react-slick': 0.28.3 + '@babel/runtime': 7.14.0 + array-tree-filter: 2.1.0 + classnames: 2.3.1 + copy-to-clipboard: 3.3.1 + lodash: 4.17.21 + moment: 2.29.1 + rc-cascader: 1.4.2_react-dom@17.0.2+react@17.0.2 + rc-checkbox: 2.3.2_react-dom@17.0.2+react@17.0.2 + rc-collapse: 3.1.0_react-dom@17.0.2+react@17.0.2 + rc-dialog: 8.5.2_react-dom@17.0.2+react@17.0.2 + rc-drawer: 4.3.1_react-dom@17.0.2+react@17.0.2 + rc-dropdown: 3.2.0_react-dom@17.0.2+react@17.0.2 + rc-field-form: 1.20.1_react-dom@17.0.2+react@17.0.2 + rc-image: 5.2.4_react-dom@17.0.2+react@17.0.2 + rc-input-number: 7.1.1_react-dom@17.0.2+react@17.0.2 + rc-mentions: 1.5.3_react-dom@17.0.2+react@17.0.2 + rc-menu: 8.10.7_react-dom@17.0.2+react@17.0.2 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-notification: 4.5.5_react-dom@17.0.2+react@17.0.2 + rc-pagination: 3.1.6_react-dom@17.0.2+react@17.0.2 + rc-picker: 2.5.10_react-dom@17.0.2+react@17.0.2 + rc-progress: 3.1.3_react-dom@17.0.2+react@17.0.2 + rc-rate: 2.9.1_react-dom@17.0.2+react@17.0.2 + rc-resize-observer: 1.0.0_react-dom@17.0.2+react@17.0.2 + rc-select: 12.1.10_react-dom@17.0.2+react@17.0.2 + rc-slider: 9.7.2_react-dom@17.0.2+react@17.0.2 + rc-steps: 4.1.3_react-dom@17.0.2+react@17.0.2 + rc-switch: 3.2.2_react-dom@17.0.2+react@17.0.2 + rc-table: 7.13.3_react-dom@17.0.2+react@17.0.2 + rc-tabs: 11.7.3_react-dom@17.0.2+react@17.0.2 + rc-textarea: 0.3.4_react-dom@17.0.2+react@17.0.2 + rc-tooltip: 5.1.1_react-dom@17.0.2+react@17.0.2 + rc-tree: 4.1.5_react-dom@17.0.2+react@17.0.2 + rc-tree-select: 4.3.2_react-dom@17.0.2+react@17.0.2 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + rc-upload: 4.2.1_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + scroll-into-view-if-needed: 2.2.28 + warning: 4.0.3 + transitivePeerDependencies: + - dayjs + dev: true + + /anymatch/2.0.0: + resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} + dependencies: + micromatch: 3.1.10 + normalize-path: 2.1.1 + dev: true + + /anymatch/3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.2.3 + dev: true + + /arch/2.2.0: + resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + dev: true + + /arg/4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /argparse/1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /arr-diff/4.0.0: + resolution: {integrity: sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=} + engines: {node: '>=0.10.0'} + dev: true + + /arr-flatten/1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + dev: true + + /arr-union/3.1.0: + resolution: {integrity: sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=} + engines: {node: '>=0.10.0'} + dev: true + + /array-equal/1.0.0: + resolution: {integrity: sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=} + dev: true + + /array-flatten/1.1.1: + resolution: {integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=} + dev: false + + /array-tree-filter/2.1.0: + resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==} + dev: true + + /array-unique/0.3.2: + resolution: {integrity: sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=} + engines: {node: '>=0.10.0'} + dev: true + + /asap/2.0.6: + resolution: {integrity: sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=} + dev: true + + /asn1.js/5.4.1: + resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} + dependencies: + bn.js: 4.12.0 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + safer-buffer: 2.1.2 + dev: true + + /asn1/0.2.4: + resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /assert-plus/1.0.0: + resolution: {integrity: sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=} + engines: {node: '>=0.8'} + dev: true + + /assert/1.5.0: + resolution: {integrity: sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==} + dependencies: + object-assign: 4.1.1 + util: 0.10.3 + dev: true + + /assign-symbols/1.0.0: + resolution: {integrity: sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=} + engines: {node: '>=0.10.0'} + dev: true + + /astral-regex/2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /async-limiter/1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + dev: true + + /async-validator/3.5.2: + resolution: {integrity: sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ==} + dev: true + + /async/0.2.10: + resolution: {integrity: sha1-trvgsGdLnXGXCMo43owjfLUmw9E=} + dev: false + + /async/1.5.2: + resolution: {integrity: sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=} + dev: false + + /async/3.2.0: + resolution: {integrity: sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==} + dev: false + + /asynckit/0.4.0: + resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} + dev: true + + /atob/2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + dev: true + + /autoprefixer/9.8.6: + resolution: {integrity: sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==} + hasBin: true + dependencies: + browserslist: 4.16.6 + caniuse-lite: 1.0.30001228 + colorette: 1.2.2 + normalize-range: 0.1.2 + num2fraction: 1.2.2 + postcss: 7.0.32 + postcss-value-parser: 4.1.0 + dev: true + + /aws-sign2/0.7.0: + resolution: {integrity: sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=} + dev: true + + /aws4/1.11.0: + resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} + dev: true + + /babel-core/7.0.0-bridge.0_@babel+core@7.12.10: + resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.12.10 + dev: true + + /babel-jest/26.6.3_@babel+core@7.12.10: + resolution: {integrity: sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==} + engines: {node: '>= 10.14.2'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.12.10 + '@jest/transform': 26.6.2 + '@jest/types': 26.6.2 + '@types/babel__core': 7.1.14 + babel-plugin-istanbul: 6.0.0 + babel-preset-jest: 26.6.2_@babel+core@7.12.10 + chalk: 4.1.1 + graceful-fs: 4.2.6 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-emotion/10.2.2: + resolution: {integrity: sha512-SMSkGoqTbTyUTDeuVuPIWifPdUGkTk1Kf9BWRiXIOIcuyMfsdp2EjeiiFvOzX8NOBvEh/ypKYvUh2rkgAJMCLA==} + dependencies: + '@babel/helper-module-imports': 7.13.12 + '@emotion/hash': 0.8.0 + '@emotion/memoize': 0.7.4 + '@emotion/serialize': 0.11.16 + babel-plugin-macros: 2.8.0 + babel-plugin-syntax-jsx: 6.18.0 + convert-source-map: 1.7.0 + escape-string-regexp: 1.0.5 + find-root: 1.1.0 + source-map: 0.5.7 + dev: true + + /babel-plugin-istanbul/5.2.0: + resolution: {integrity: sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==} + engines: {node: '>=6'} + dependencies: + '@babel/helper-plugin-utils': 7.13.0 + find-up: 3.0.0 + istanbul-lib-instrument: 3.3.0 + test-exclude: 5.2.3 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul/6.0.0: + resolution: {integrity: sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.13.0 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 4.0.3 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist/26.6.2: + resolution: {integrity: sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==} + engines: {node: '>= 10.14.2'} + dependencies: + '@babel/template': 7.12.13 + '@babel/types': 7.14.2 + '@types/babel__core': 7.1.14 + '@types/babel__traverse': 7.11.1 + dev: true + + /babel-plugin-macros/2.8.0: + resolution: {integrity: sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==} + dependencies: + '@babel/runtime': 7.14.0 + cosmiconfig: 6.0.0 + resolve: 1.20.0 + dev: true + + /babel-plugin-syntax-jsx/6.18.0: + resolution: {integrity: sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=} + dev: true + + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.12.10: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.12.10 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.12.10 + '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.12.10 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.12.10 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.12.10 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.12.10 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.12.10 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.12.10 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.12.10 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.12.10 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.12.10 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.12.10 + '@babel/plugin-syntax-top-level-await': 7.12.13_@babel+core@7.12.10 + dev: true + + /babel-preset-jest/26.6.2_@babel+core@7.12.10: + resolution: {integrity: sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==} + engines: {node: '>= 10.14.2'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.12.10 + babel-plugin-jest-hoist: 26.6.2 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.12.10 + dev: true + + /babel-runtime/6.26.0: + resolution: {integrity: sha1-llxwWGaOgrVde/4E/yM3vItWR/4=} + dependencies: + core-js: 2.6.12 + regenerator-runtime: 0.11.1 + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base/0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.0 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + dev: true + + /base64-js/1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /bcrypt-pbkdf/1.0.2: + resolution: {integrity: sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=} + dependencies: + tweetnacl: 0.14.5 + dev: true + + /big.js/5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /binary-search-tree/0.2.5: + resolution: {integrity: sha1-fbs7IQ/coIJFDa0jNMMErzm9x4Q=} + dependencies: + underscore: 1.4.4 + dev: false + + /bindings/1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + optional: true + + /bn.js/4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + dev: true + + /bn.js/5.2.0: + resolution: {integrity: sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==} + dev: true + + /body-parser/1.19.0: + resolution: {integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==} + engines: {node: '>= 0.8'} + 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.18 + dev: false + + /boxen/4.2.0: + resolution: {integrity: sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==} + engines: {node: '>=8'} + dependencies: + ansi-align: 3.0.0 + camelcase: 5.3.1 + chalk: 3.0.0 + cli-boxes: 2.2.1 + string-width: 4.2.2 + term-size: 2.2.1 + type-fest: 0.8.1 + widest-line: 3.1.0 + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces/2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + 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.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /brorand/1.1.0: + resolution: {integrity: sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=} + dev: true + + /browser-process-hrtime/1.0.0: + resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} + dev: true + + /browserify-aes/1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /browserify-cipher/1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + dev: true + + /browserify-des/1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + dependencies: + cipher-base: 1.0.4 + des.js: 1.0.1 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /browserify-rsa/4.1.0: + resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} + dependencies: + bn.js: 5.2.0 + randombytes: 2.1.0 + dev: true + + /browserify-sign/4.2.1: + resolution: {integrity: sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==} + dependencies: + bn.js: 5.2.0 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.5.4 + inherits: 2.0.4 + parse-asn1: 5.1.6 + readable-stream: 3.6.0 + safe-buffer: 5.2.1 + dev: true + + /browserify-zlib/0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + dependencies: + pako: 1.0.11 + dev: true + + /browserslist/4.16.6: + resolution: {integrity: sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001228 + colorette: 1.2.2 + electron-to-chromium: 1.3.728 + escalade: 3.1.1 + node-releases: 1.1.72 + dev: true + + /bser/2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-equal-constant-time/1.0.1: + resolution: {integrity: sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=} + dev: false + + /buffer-from/1.1.1: + resolution: {integrity: sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==} + dev: true + + /buffer-xor/1.0.3: + resolution: {integrity: sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=} + dev: true + + /buffer/4.9.2: + resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + isarray: 1.0.0 + dev: true + + /builtin-status-codes/3.0.0: + resolution: {integrity: sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=} + dev: true + + /bytes/3.1.0: + resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} + engines: {node: '>= 0.8'} + dev: false + + /cacache/15.0.6: + resolution: {integrity: sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w==} + engines: {node: '>= 10'} + dependencies: + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.1.7 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.1.3 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.1.0 + unique-filename: 1.1.1 + dev: true + + /cache-base/1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.0 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + dev: true + + /cacheable-lookup/5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + dev: false + + /cacheable-request/6.1.0: + resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} + engines: {node: '>=8'} + dependencies: + clone-response: 1.0.2 + get-stream: 5.2.0 + http-cache-semantics: 4.1.0 + keyv: 3.1.0 + lowercase-keys: 2.0.0 + normalize-url: 4.5.0 + responselike: 1.0.2 + dev: true + + /cacheable-request/7.0.1: + resolution: {integrity: sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==} + engines: {node: '>=8'} + dependencies: + clone-response: 1.0.2 + get-stream: 5.2.0 + http-cache-semantics: 4.1.0 + keyv: 4.0.3 + lowercase-keys: 2.0.0 + normalize-url: 4.5.0 + responselike: 2.0.0 + dev: false + + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.1 + + /caller-callsite/2.0.0: + resolution: {integrity: sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=} + engines: {node: '>=4'} + dependencies: + callsites: 2.0.0 + dev: true + + /caller-path/2.0.0: + resolution: {integrity: sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=} + engines: {node: '>=4'} + dependencies: + caller-callsite: 2.0.0 + dev: true + + /callsites/2.0.0: + resolution: {integrity: sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=} + engines: {node: '>=4'} + dev: true + + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase/5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase/6.2.0: + resolution: {integrity: sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite/1.0.30001228: + resolution: {integrity: sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==} + dev: true + + /capture-exit/2.0.0: + resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} + engines: {node: 6.* || 8.* || >= 10.*} + dependencies: + rsvp: 4.8.5 + dev: true + + /caseless/0.12.0: + resolution: {integrity: sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=} + dev: true + + /celebrate/13.0.4: + resolution: {integrity: sha512-gUtAjEtFyY9PvuuQJq1uyuF46gLetVZzyUKXBDBqqvgzCjTSfwXP8L+WcGt1NrLQvUxXdlzhFolW2Bt9DDEV+g==} + dependencies: + escape-html: 1.0.3 + joi: 17.4.0 + lodash: 4.17.21 + dev: false + + /chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk/3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk/4.1.1: + resolution: {integrity: sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /char-regex/1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /chokidar/3.5.1: + resolution: {integrity: sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==} + engines: {node: '>= 8.10.0'} + 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.5.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /chownr/2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: true + + /chrome-trace-event/1.0.3: + resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} + engines: {node: '>=6.0'} + dev: true + + /ci-info/1.6.0: + resolution: {integrity: sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==} + dev: true + + /ci-info/2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + dev: true + + /cipher-base/1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /cjs-module-lexer/0.6.0: + resolution: {integrity: sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==} + dev: true + + /class-utils/0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + dev: true + + /classnames/2.3.1: + resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} + dev: true + + /clean-stack/2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-boxes/2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + dev: true + + /cli-cursor/3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-truncate/2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.2 + dev: true + + /clipboardy/2.3.0: + resolution: {integrity: sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==} + engines: {node: '>=8'} + dependencies: + arch: 2.2.0 + execa: 1.0.0 + is-wsl: 2.2.0 + dev: true + + /cliui/6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.2 + strip-ansi: 6.0.0 + wrap-ansi: 6.2.0 + dev: true + + /clone-response/1.0.2: + resolution: {integrity: sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=} + dependencies: + mimic-response: 1.0.1 + + /co/4.6.0: + resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /codemirror/5.61.0: + resolution: {integrity: sha512-D3wYH90tYY1BsKlUe0oNj2JAhQ9TepkD51auk3N7q+4uz7A/cgJ5JsWHreT0PqieW1QhOuqxQ2reCXV1YXzecg==} + dev: true + + /collect-v8-coverage/1.0.1: + resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + dev: true + + /collection-visit/1.0.0: + resolution: {integrity: sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=} + engines: {node: '>=0.10.0'} + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + dev: true + + /color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.3: + resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + /color-string/1.5.5: + resolution: {integrity: sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false + + /color/3.0.0: + resolution: {integrity: sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==} + dependencies: + color-convert: 1.9.3 + color-string: 1.5.5 + dev: false + + /colorette/1.2.2: + resolution: {integrity: sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==} + dev: true + + /colors/1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + dev: false + + /colorspace/1.1.2: + resolution: {integrity: sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==} + dependencies: + color: 3.0.0 + text-hex: 1.0.0 + dev: false + + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander/6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + dev: true + + /commondir/1.0.1: + resolution: {integrity: sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=} + dev: true + + /component-classes/1.2.6: + resolution: {integrity: sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=} + dependencies: + component-indexof: 0.0.3 + dev: true + + /component-emitter/1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + dev: true + + /component-indexof/0.0.3: + resolution: {integrity: sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=} + dev: true + + /compression-webpack-plugin/6.1.1_webpack@5.37.0: + resolution: {integrity: sha512-BEHft9M6lwOqVIQFMS/YJGmeCYXVOakC5KzQk05TFpMBlODByh1qNsZCWjUBxCQhUP9x0WfGidxTbGkjbWO/TQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + dependencies: + cacache: 15.0.6 + find-cache-dir: 3.3.1 + schema-utils: 3.0.0 + serialize-javascript: 5.0.1 + webpack: 5.37.0 + webpack-sources: 1.4.3 + dev: true + + /compute-scroll-into-view/1.0.17: + resolution: {integrity: sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==} + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /configstore/5.0.1: + resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==} + engines: {node: '>=8'} + dependencies: + dot-prop: 5.3.0 + graceful-fs: 4.2.6 + make-dir: 3.1.0 + unique-string: 2.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 4.0.0 + dev: true + + /console-browserify/1.2.0: + resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} + dev: true + + /constants-browserify/1.0.0: + resolution: {integrity: sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=} + dev: true + + /content-disposition/0.5.3: + resolution: {integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.1.2 + dev: false + + /content-type/1.0.4: + resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} + engines: {node: '>= 0.6'} + dev: false + + /convert-source-map/1.7.0: + resolution: {integrity: sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /cookie-signature/1.0.6: + resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} + dev: false + + /cookie/0.4.0: + resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==} + engines: {node: '>= 0.6'} + dev: false + + /copy-descriptor/0.1.1: + resolution: {integrity: sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=} + engines: {node: '>=0.10.0'} + dev: true + + /copy-to-clipboard/3.3.1: + resolution: {integrity: sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==} + dependencies: + toggle-selection: 1.0.6 + dev: true + + /core-js/1.2.7: + resolution: {integrity: sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=} + 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 + + /core-js/2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + 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. + requiresBuild: true + dev: true + + /core-js/3.6.5: + resolution: {integrity: sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==} + requiresBuild: true + dev: true + + /core-js/3.8.2: + resolution: {integrity: sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==} + requiresBuild: true + dev: true + + /core-util-is/1.0.2: + resolution: {integrity: sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=} + + /cors/2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + dev: false + + /cosmiconfig/5.2.1: + resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} + engines: {node: '>=4'} + dependencies: + import-fresh: 2.0.0 + is-directory: 0.3.1 + js-yaml: 3.14.1 + parse-json: 4.0.0 + dev: true + + /cosmiconfig/6.0.0: + resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} + engines: {node: '>=8'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + + /cosmiconfig/7.0.0: + resolution: {integrity: sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + + /create-ecdh/4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.4 + dev: true + + /create-emotion/10.0.27: + resolution: {integrity: sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg==} + dependencies: + '@emotion/cache': 10.0.29 + '@emotion/serialize': 0.11.16 + '@emotion/sheet': 0.9.4 + '@emotion/utils': 0.11.3 + dev: true + + /create-hash/1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + dev: true + + /create-hmac/1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + dev: true + + /create-react-class/15.7.0: + resolution: {integrity: sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + dev: true + + /create-require/1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cron-parser/3.5.0: + resolution: {integrity: sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==} + engines: {node: '>=0.8'} + dependencies: + is-nan: 1.3.2 + luxon: 1.27.0 + dev: false + + /cross-spawn/5.1.0: + resolution: {integrity: sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=} + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /cross-spawn/6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.1 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /cross-spawn/7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypto-browserify/3.12.0: + resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.1 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + inherits: 2.0.4 + pbkdf2: 3.1.2 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + dev: true + + /crypto-random-string/2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: true + + /css-animation/1.6.1: + resolution: {integrity: sha512-/48+/BaEaHRY6kNQ2OIPzKf9A6g8WjZYjhiNDNuIVbsm5tXCGIAsHDjB4Xu1C4vXJtUWZo26O68OQkDpNBaPog==} + dependencies: + babel-runtime: 6.26.0 + component-classes: 1.2.6 + dev: true + + /css-blank-pseudo/0.1.4: + resolution: {integrity: sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + postcss: 7.0.32 + dev: true + + /css-has-pseudo/0.10.0: + resolution: {integrity: sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + postcss: 7.0.32 + postcss-selector-parser: 5.0.0 + dev: true + + /css-prefers-color-scheme/3.1.1: + resolution: {integrity: sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + postcss: 7.0.32 + dev: true + + /cssdb/4.4.0: + resolution: {integrity: sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==} + dev: true + + /cssesc/2.0.0: + resolution: {integrity: sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /cssesc/3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /cssom/0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + dev: true + + /cssom/0.4.4: + resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==} + dev: true + + /cssstyle/1.4.0: + resolution: {integrity: sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==} + dependencies: + cssom: 0.3.8 + dev: true + + /cssstyle/2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + dependencies: + cssom: 0.3.8 + dev: true + + /csstype/2.6.17: + resolution: {integrity: sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==} + dev: true + + /csstype/3.0.8: + resolution: {integrity: sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==} + dev: true + + /darkreader/4.9.32: + resolution: {integrity: sha512-llljeLTLLCXCyWAjNAH3i4+avMrOxJTZN3ASzAWhy78c3mt8w7DerwB/5Zq4NW/qmJbmuZ0RdIgj2nrlNZrv8A==} + dev: true + + /dashdash/1.14.1: + resolution: {integrity: sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: true + + /data-urls/1.1.0: + resolution: {integrity: sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==} + dependencies: + abab: 2.0.5 + whatwg-mimetype: 2.3.0 + whatwg-url: 7.1.0 + dev: true + + /data-urls/2.0.0: + resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} + engines: {node: '>=10'} + dependencies: + abab: 2.0.5 + whatwg-mimetype: 2.3.0 + whatwg-url: 8.5.0 + dev: true + + /date-fns/2.21.3: + resolution: {integrity: sha512-HeYdzCaFflc1i4tGbj7JKMjM4cKGYoyxwcIIkHzNgCkX8xXDNJDZXgDDVchIWpN4eQc3lH37WarduXFZJOtxfw==} + engines: {node: '>=0.11'} + dev: true + + /debug/2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + dependencies: + ms: 2.0.0 + + /debug/3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + dependencies: + ms: 2.1.3 + dev: true + + /debug/4.3.1: + resolution: {integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decamelize/1.2.0: + resolution: {integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=} + engines: {node: '>=0.10.0'} + dev: true + + /decimal.js/10.2.1: + resolution: {integrity: sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==} + dev: true + + /decode-uri-component/0.2.0: + resolution: {integrity: sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=} + engines: {node: '>=0.10'} + dev: true + + /decompress-response/3.3.0: + resolution: {integrity: sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=} + engines: {node: '>=4'} + dependencies: + mimic-response: 1.0.1 + dev: true + + /decompress-response/6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + + /dedent/0.7.0: + resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=} + dev: true + + /deep-extend/0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: true + + /deep-is/0.1.3: + resolution: {integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=} + dev: true + + /deepmerge/1.5.2: + resolution: {integrity: sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==} + engines: {node: '>=0.10.0'} + dev: true + + /deepmerge/4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: true + + /defer-to-connect/1.1.3: + resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} + dev: true + + /defer-to-connect/2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: false + + /define-properties/1.1.3: + resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} + engines: {node: '>= 0.4'} + dependencies: + object-keys: 1.1.1 + + /define-property/0.2.5: + resolution: {integrity: sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 0.1.6 + dev: true + + /define-property/1.0.0: + resolution: {integrity: sha1-dp66rz9KY6rTr56NMEybvnm/sOY=} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + dev: true + + /define-property/2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + isobject: 3.0.1 + dev: true + + /delayed-stream/1.0.0: + resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} + engines: {node: '>=0.4.0'} + dev: true + + /depd/1.1.2: + resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=} + engines: {node: '>= 0.6'} + dev: false + + /dequal/2.0.2: + resolution: {integrity: sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==} + engines: {node: '>=6'} + dev: true + + /des.js/1.0.1: + resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: true + + /destroy/1.0.4: + resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=} + dev: false + + /detect-newline/3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /diff-sequences/26.6.2: + resolution: {integrity: sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==} + engines: {node: '>= 10.14.2'} + dev: true + + /diff/4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /diffie-hellman/5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + dependencies: + bn.js: 4.12.0 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + dev: true + + /dnd-core/14.0.0: + resolution: {integrity: sha512-wTDYKyjSqWuYw3ZG0GJ7k+UIfzxTNoZLjDrut37PbcPGNfwhlKYlPUqjAKUjOOv80izshUiqusaKgJPItXSevA==} + dependencies: + '@react-dnd/asap': 4.0.0 + '@react-dnd/invariant': 2.0.0 + redux: 4.1.0 + dev: true + + /dom-align/1.12.1: + resolution: {integrity: sha512-CdTD9EdA5WviP8oO3n+okOm0Xt7dSuWxRTLcJiW0memwUr3Tvz66JDDCh9cb50IZFHXvBmLoyX454uJU/EVg+g==} + dev: true + + /domain-browser/1.2.0: + resolution: {integrity: sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==} + engines: {node: '>=0.4', npm: '>=1.2'} + dev: true + + /domexception/1.0.1: + resolution: {integrity: sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==} + dependencies: + webidl-conversions: 4.0.2 + dev: true + + /domexception/2.0.1: + resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} + engines: {node: '>=8'} + dependencies: + webidl-conversions: 5.0.0 + dev: true + + /dot-prop/5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + dependencies: + is-obj: 2.0.0 + dev: true + + /dotenv/8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} + dev: false + + /duplexer3/0.1.4: + resolution: {integrity: sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=} + dev: true + + /ecc-jsbn/0.1.2: + resolution: {integrity: sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + + /ecdsa-sig-formatter/1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dependencies: + safe-buffer: 5.2.1 + dev: false + + /ee-first/1.1.1: + resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + dev: false + + /electron-to-chromium/1.3.728: + resolution: {integrity: sha512-SHv4ziXruBpb1Nz4aTuqEHBYi/9GNCJMYIJgDEXrp/2V01nFXMNFUTli5Z85f5ivSkioLilQatqBYFB44wNJrA==} + dev: true + + /elliptic/6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: true + + /emittery/0.7.2: + resolution: {integrity: sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==} + engines: {node: '>=10'} + dev: true + + /emoji-regex/7.0.3: + resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emojis-list/3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + dev: true + + /emotion/10.0.27: + resolution: {integrity: sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g==} + dependencies: + babel-plugin-emotion: 10.2.2 + create-emotion: 10.0.27 + dev: true + + /enabled/2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + dev: false + + /encodeurl/1.0.2: + resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} + engines: {node: '>= 0.8'} + dev: false + + /encoding/0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + dependencies: + iconv-lite: 0.6.2 + dev: true + + /end-of-stream/1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + + /enhanced-resolve/5.8.2: + resolution: {integrity: sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.6 + tapable: 2.2.0 + dev: true + + /enquirer/2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.1 + dev: true + + /error-ex/1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract/1.18.0: + resolution: {integrity: sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==} + engines: {node: '>= 0.4'} + 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 + dev: true + + /es-module-lexer/0.4.1: + resolution: {integrity: sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==} + dev: true + + /es-to-primitive/1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.3 + is-date-object: 1.0.4 + is-symbol: 1.0.4 + dev: true + + /es5-imcompatible-versions/0.1.69: + resolution: {integrity: sha512-+QW+Q/HBO72pXHiRlWqGXwtxyM83iALRVPV0h/31UnAv5OJ75u1UCn32Kld67BoVMwaBHN2qBGi0SnNmKCkPZA==} + dev: true + + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-goat/2.1.1: + resolution: {integrity: sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==} + engines: {node: '>=8'} + dev: true + + /escape-html/1.0.3: + resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=} + dev: false + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp/2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escodegen/1.14.3: + resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} + engines: {node: '>=4.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /escodegen/2.0.0: + resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.2.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /esprima/4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.2.0 + dev: true + + /estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse/5.2.0: + resolution: {integrity: sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==} + engines: {node: '>=4.0'} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag/1.8.1: + resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=} + engines: {node: '>= 0.6'} + dev: false + + /eventemitter3/4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /events/3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: true + + /evp_bytestokey/1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + dev: true + + /exec-sh/0.3.6: + resolution: {integrity: sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==} + dev: true + + /execa/0.8.0: + resolution: {integrity: sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=} + engines: {node: '>=4'} + dependencies: + cross-spawn: 5.1.0 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.3 + strip-eof: 1.0.0 + dev: true + + /execa/1.0.0: + resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} + engines: {node: '>=6'} + dependencies: + cross-spawn: 6.0.5 + get-stream: 4.1.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.3 + strip-eof: 1.0.0 + dev: true + + /execa/4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + 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 + dev: true + + /exenv/1.2.2: + resolution: {integrity: sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=} + dev: true + + /exit/0.1.2: + resolution: {integrity: sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=} + engines: {node: '>= 0.8.0'} + dev: true + + /expand-brackets/2.1.4: + resolution: {integrity: sha1-t3c14xXOMPa27/D4OwQVGiJEliI=} + engines: {node: '>=0.10.0'} + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + dev: true + + /expect/26.6.2: + resolution: {integrity: sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + ansi-styles: 4.3.0 + jest-get-type: 26.3.0 + jest-matcher-utils: 26.6.2 + jest-message-util: 26.6.2 + jest-regex-util: 26.0.0 + dev: true + + /express-jwt/6.0.0: + resolution: {integrity: sha512-C26y9myRjx7CyhZ+BAT3p+gQyRCoDZ7qo8plCvLDaRT6je6ALIAQknT6XLVQGFKwIy/Ux7lvM2MNap5dt0T7gA==} + engines: {node: '>= 8.0.0'} + dependencies: + async: 1.5.2 + express-unless: 0.3.1 + jsonwebtoken: 8.5.1 + lodash.set: 4.3.2 + dev: false + + /express-unless/0.3.1: + resolution: {integrity: sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=} + dev: false + + /express/4.17.1: + resolution: {integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==} + engines: {node: '>= 0.10.0'} + 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.6 + 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 + dev: false + + /extend-shallow/2.0.1: + resolution: {integrity: sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=} + engines: {node: '>=0.10.0'} + dependencies: + is-extendable: 0.1.1 + dev: true + + /extend-shallow/3.0.2: + resolution: {integrity: sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=} + engines: {node: '>=0.10.0'} + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + dev: true + + /extend/3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /extglob/2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + 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.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + dev: true + + /extsprintf/1.3.0: + resolution: {integrity: sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=} + engines: {'0': node >=0.6.0} + dev: true + + /fast-deep-equal/3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein/2.0.6: + resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} + dev: true + + /fast-safe-stringify/2.0.7: + resolution: {integrity: sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==} + dev: false + + /fb-watchman/2.0.1: + resolution: {integrity: sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==} + dependencies: + bser: 2.1.1 + dev: true + + /fbjs/0.8.17: + resolution: {integrity: sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=} + dependencies: + core-js: 1.2.7 + isomorphic-fetch: 2.2.1 + loose-envify: 1.4.0 + object-assign: 4.1.1 + promise: 7.3.1 + setimmediate: 1.0.5 + ua-parser-js: 0.7.28 + dev: true + + /fecha/4.2.1: + resolution: {integrity: sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==} + dev: false + + /figures/3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /file-uri-to-path/1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + optional: true + + /fill-range/4.0.0: + resolution: {integrity: sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /filter-obj/1.1.0: + resolution: {integrity: sha1-mzERErxsYSehbgFsbF1/GeCAXFs=} + engines: {node: '>=0.10.0'} + dev: true + + /finalhandler/1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + 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 + dev: false + + /find-cache-dir/3.3.1: + resolution: {integrity: sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==} + engines: {node: '>=8'} + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + dev: true + + /find-root/1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + dev: true + + /find-up/3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + + /find-up/4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /flatten/1.0.3: + resolution: {integrity: sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==} + dev: true + + /fn.name/1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + dev: false + + /for-each/0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.3 + dev: true + + /for-in/1.0.2: + resolution: {integrity: sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=} + engines: {node: '>=0.10.0'} + dev: true + + /forever-agent/0.6.1: + resolution: {integrity: sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=} + dev: true + + /form-data/2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.30 + dev: true + + /form-data/3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.30 + dev: true + + /forwarded/0.1.2: + resolution: {integrity: sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=} + engines: {node: '>= 0.6'} + dev: false + + /fragment-cache/0.2.1: + resolution: {integrity: sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=} + engines: {node: '>=0.10.0'} + dependencies: + map-cache: 0.2.2 + dev: true + + /fresh/0.5.2: + resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} + engines: {node: '>= 0.6'} + dev: false + + /fs-minipass/2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.1.3 + dev: true + + /fs.realpath/1.0.0: + resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} + dev: true + + /fsevents/1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. + requiresBuild: true + dependencies: + bindings: 1.5.0 + nan: 2.14.2 + dev: true + optional: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + + /gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file/2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic/1.1.1: + resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.2 + + /get-own-enumerable-property-symbols/3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + dev: true + + /get-package-type/0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-stream/3.0.0: + resolution: {integrity: sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=} + engines: {node: '>=4'} + dev: true + + /get-stream/4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + dependencies: + pump: 3.0.0 + dev: true + + /get-stream/5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + + /get-value/2.0.6: + resolution: {integrity: sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=} + engines: {node: '>=0.10.0'} + dev: true + + /getpass/0.1.7: + resolution: {integrity: sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=} + dependencies: + assert-plus: 1.0.0 + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.1 + dev: true + + /glob-to-regexp/0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob/7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /global-dirs/2.1.0: + resolution: {integrity: sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==} + engines: {node: '>=8'} + dependencies: + ini: 1.3.7 + dev: true + + /globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /got/11.8.2: + resolution: {integrity: sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==} + engines: {node: '>=10.19.0'} + dependencies: + '@sindresorhus/is': 4.0.1 + '@szmarczak/http-timer': 4.0.5 + '@types/cacheable-request': 6.0.1 + '@types/responselike': 1.0.0 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.1 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.0 + dev: false + + /got/9.6.0: + resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} + engines: {node: '>=8.6'} + dependencies: + '@sindresorhus/is': 0.14.0 + '@szmarczak/http-timer': 1.1.2 + cacheable-request: 6.1.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.1.0 + to-readable-stream: 1.0.0 + url-parse-lax: 3.0.0 + dev: true + + /graceful-fs/4.2.6: + resolution: {integrity: sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==} + dev: true + + /growly/1.3.0: + resolution: {integrity: sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=} + dev: true + optional: true + + /har-schema/2.0.0: + resolution: {integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=} + engines: {node: '>=4'} + dev: true + + /har-validator/5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: true + + /harmony-reflect/1.6.2: + resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==} + dev: true + + /has-bigints/1.0.1: + resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==} + dev: true + + /has-flag/3.0.0: + resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} + engines: {node: '>=4'} + dev: true + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-symbols/1.0.2: + resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==} + engines: {node: '>= 0.4'} + + /has-value/0.3.1: + resolution: {integrity: sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + dev: true + + /has-value/1.0.0: + resolution: {integrity: sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + dev: true + + /has-values/0.1.4: + resolution: {integrity: sha1-bWHeldkd/Km5oCCJrThL/49it3E=} + engines: {node: '>=0.10.0'} + dev: true + + /has-values/1.0.0: + resolution: {integrity: sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + dev: true + + /has-yarn/2.1.0: + resolution: {integrity: sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==} + engines: {node: '>=8'} + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + + /hash-base/3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.0 + safe-buffer: 5.2.1 + dev: true + + /hash.js/1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: true + + /history-with-query/4.10.4: + resolution: {integrity: sha512-JnskQK8X+PbRFHSdDAExhoJyhLnlLZL+UuHQuQhys+Se9/ukRDRBWU4JVTjsiIfbv1fcEmR3oqKW56OYmk5M5w==} + dependencies: + '@babel/runtime': 7.14.0 + loose-envify: 1.4.0 + query-string: 6.14.1 + resolve-pathname: 3.0.0 + tiny-invariant: 1.1.0 + tiny-warning: 1.0.3 + value-equal: 1.0.1 + dev: true + + /history/4.10.1: + resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} + dependencies: + '@babel/runtime': 7.14.0 + loose-envify: 1.4.0 + resolve-pathname: 3.0.0 + tiny-invariant: 1.1.0 + tiny-warning: 1.0.3 + value-equal: 1.0.1 + dev: true + + /hmac-drbg/1.0.1: + resolution: {integrity: sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=} + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: true + + /hoist-non-react-statics/3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: true + + /hosted-git-info/2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /html-encoding-sniffer/1.0.2: + resolution: {integrity: sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==} + dependencies: + whatwg-encoding: 1.0.5 + dev: true + + /html-encoding-sniffer/2.0.1: + resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==} + engines: {node: '>=10'} + dependencies: + whatwg-encoding: 1.0.5 + dev: true + + /html-escaper/2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /http-cache-semantics/4.1.0: + resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} + + /http-errors/1.7.2: + resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==} + engines: {node: '>= 0.6'} + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.1 + statuses: 1.5.0 + toidentifier: 1.0.0 + dev: false + + /http-errors/1.7.3: + resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} + engines: {node: '>= 0.6'} + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.1.1 + statuses: 1.5.0 + toidentifier: 1.0.0 + dev: false + + /http-signature/1.2.0: + resolution: {integrity: sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=} + engines: {node: '>=0.8', npm: '>=1.3.7'} + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.1 + sshpk: 1.16.1 + dev: true + + /http2-wrapper/1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.1.2 + dev: false + + /https-browserify/1.0.0: + resolution: {integrity: sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=} + dev: true + + /human-signals/1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + dev: true + + /iconv-lite/0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + + /iconv-lite/0.6.2: + resolution: {integrity: sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /identity-obj-proxy/3.0.0: + resolution: {integrity: sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=} + engines: {node: '>=4'} + dependencies: + harmony-reflect: 1.6.2 + dev: true + + /ieee754/1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore-by-default/1.0.1: + resolution: {integrity: sha1-SMptcvbGo68Aqa1K5odr44ieKwk=} + dev: true + + /immediate/3.0.6: + resolution: {integrity: sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=} + dev: false + + /import-cwd/2.1.0: + resolution: {integrity: sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=} + engines: {node: '>=4'} + dependencies: + import-from: 2.1.0 + dev: true + + /import-fresh/2.0.0: + resolution: {integrity: sha1-2BNVwVYS04bGH53dOSLUMEgipUY=} + engines: {node: '>=4'} + dependencies: + caller-path: 2.0.0 + resolve-from: 3.0.0 + dev: true + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /import-from/2.1.0: + resolution: {integrity: sha1-M1238qev/VOqpHHUuAId7ja387E=} + engines: {node: '>=4'} + dependencies: + resolve-from: 3.0.0 + dev: true + + /import-lazy/2.1.0: + resolution: {integrity: sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=} + engines: {node: '>=4'} + dev: true + + /import-local/3.0.2: + resolution: {integrity: sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /imurmurhash/0.1.4: + resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string/4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /indexes-of/1.0.1: + resolution: {integrity: sha1-8w9xbI4r00bHtn0985FVZqfAVgc=} + dev: true + + /infer-owner/1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.1: + resolution: {integrity: sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=} + dev: true + + /inherits/2.0.3: + resolution: {integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=} + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /ini/1.3.7: + resolution: {integrity: sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==} + dev: true + + /ini/1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + + /invariant/2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: true + + /ipaddr.js/1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: false + + /is-accessor-descriptor/0.1.6: + resolution: {integrity: sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-accessor-descriptor/1.0.0: + resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-arrayish/0.2.1: + resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=} + dev: true + + /is-arrayish/0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: false + + /is-bigint/1.0.2: + resolution: {integrity: sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==} + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object/1.1.1: + resolution: {integrity: sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-buffer/1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + dev: true + + /is-callable/1.2.3: + resolution: {integrity: sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==} + engines: {node: '>= 0.4'} + dev: true + + /is-ci/1.2.1: + resolution: {integrity: sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==} + hasBin: true + dependencies: + ci-info: 1.6.0 + dev: true + + /is-ci/2.0.0: + resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} + hasBin: true + dependencies: + ci-info: 2.0.0 + dev: true + + /is-core-module/2.4.0: + resolution: {integrity: sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==} + dependencies: + has: 1.0.3 + dev: true + + /is-data-descriptor/0.1.4: + resolution: {integrity: sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-data-descriptor/1.0.0: + resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-date-object/1.0.4: + resolution: {integrity: sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==} + engines: {node: '>= 0.4'} + dev: true + + /is-descriptor/0.1.6: + resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 0.1.6 + is-data-descriptor: 0.1.4 + kind-of: 5.1.0 + dev: true + + /is-descriptor/1.0.2: + resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 1.0.0 + is-data-descriptor: 1.0.0 + kind-of: 6.0.3 + dev: true + + /is-directory/0.3.1: + resolution: {integrity: sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=} + engines: {node: '>=0.10.0'} + dev: true + + /is-docker/2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-extendable/0.1.1: + resolution: {integrity: sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=} + engines: {node: '>=0.10.0'} + dev: true + + /is-extendable/1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-object: 2.0.4 + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point/2.0.0: + resolution: {integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=} + engines: {node: '>=4'} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-generator-fn/2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + + /is-glob/4.0.1: + resolution: {integrity: sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-installed-globally/0.3.2: + resolution: {integrity: sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==} + engines: {node: '>=8'} + dependencies: + global-dirs: 2.1.0 + is-path-inside: 3.0.3 + dev: true + + /is-nan/1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + dev: false + + /is-negative-zero/2.0.1: + resolution: {integrity: sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==} + engines: {node: '>= 0.4'} + dev: true + + /is-npm/4.0.0: + resolution: {integrity: sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==} + engines: {node: '>=8'} + dev: true + + /is-number-object/1.0.5: + resolution: {integrity: sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==} + engines: {node: '>= 0.4'} + dev: true + + /is-number/3.0.0: + resolution: {integrity: sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj/1.0.1: + resolution: {integrity: sha1-PkcprB9f3gJc19g6iW2rn09n2w8=} + engines: {node: '>=0.10.0'} + dev: true + + /is-obj/2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + dev: true + + /is-path-inside/3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-plain-obj/1.1.0: + resolution: {integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=} + engines: {node: '>=0.10.0'} + dev: true + + /is-plain-object/2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-potential-custom-element-name/1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + dev: true + + /is-regex/1.1.3: + resolution: {integrity: sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-symbols: 1.0.2 + dev: true + + /is-regexp/1.0.0: + resolution: {integrity: sha1-/S2INUXEa6xaYz57mgnof6LLUGk=} + engines: {node: '>=0.10.0'} + dev: true + + /is-stream/1.1.0: + resolution: {integrity: sha1-EtSj3U5o4Lec6428hBc66A2RykQ=} + engines: {node: '>=0.10.0'} + dev: true + + /is-stream/2.0.0: + resolution: {integrity: sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==} + engines: {node: '>=8'} + + /is-string/1.0.6: + resolution: {integrity: sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==} + engines: {node: '>= 0.4'} + dev: true + + /is-symbol/1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.2 + dev: true + + /is-typedarray/1.0.0: + resolution: {integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=} + dev: true + + /is-unicode-supported/0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /is-windows/1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-wsl/2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + + /is-yarn-global/0.3.0: + resolution: {integrity: sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==} + dev: true + + /isarray/0.0.1: + resolution: {integrity: sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=} + dev: true + + /isarray/1.0.0: + resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} + + /isexe/2.0.0: + resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} + dev: true + + /isobject/2.1.0: + resolution: {integrity: sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=} + engines: {node: '>=0.10.0'} + dependencies: + isarray: 1.0.0 + dev: true + + /isobject/3.0.1: + resolution: {integrity: sha1-TkMekrEalzFjaqH5yNHMvP2reN8=} + engines: {node: '>=0.10.0'} + dev: true + + /isomorphic-fetch/2.2.1: + resolution: {integrity: sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=} + dependencies: + node-fetch: 1.7.3 + whatwg-fetch: 3.6.2 + dev: true + + /isstream/0.1.2: + resolution: {integrity: sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=} + dev: true + + /istanbul-lib-coverage/2.0.5: + resolution: {integrity: sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==} + engines: {node: '>=6'} + dev: true + + /istanbul-lib-coverage/3.0.0: + resolution: {integrity: sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument/3.3.0: + resolution: {integrity: sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==} + engines: {node: '>=6'} + dependencies: + '@babel/generator': 7.14.2 + '@babel/parser': 7.14.2 + '@babel/template': 7.12.13 + '@babel/traverse': 7.14.2 + '@babel/types': 7.14.2 + istanbul-lib-coverage: 2.0.5 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-instrument/4.0.3: + resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.12.10 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.0.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} + engines: {node: '>=8'} + dependencies: + istanbul-lib-coverage: 3.0.0 + make-dir: 3.1.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps/4.0.0: + resolution: {integrity: sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==} + engines: {node: '>=8'} + dependencies: + debug: 4.3.1 + istanbul-lib-coverage: 3.0.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports/3.0.2: + resolution: {integrity: sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.0 + dev: true + + /javascript-stringify/2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + dev: true + + /jest-changed-files/26.6.2: + resolution: {integrity: sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + execa: 4.1.0 + throat: 5.0.0 + dev: true + + /jest-cli/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==} + engines: {node: '>= 10.14.2'} + hasBin: true + dependencies: + '@jest/core': 26.6.3_ts-node@9.1.1 + '@jest/test-result': 26.6.2 + '@jest/types': 26.6.2 + chalk: 4.1.1 + exit: 0.1.2 + graceful-fs: 4.2.6 + import-local: 3.0.2 + is-ci: 2.0.0 + jest-config: 26.6.3_ts-node@9.1.1 + jest-util: 26.6.2 + jest-validate: 26.6.2 + prompts: 2.4.1 + yargs: 15.4.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /jest-config/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==} + engines: {node: '>= 10.14.2'} + peerDependencies: + ts-node: '>=9.0.0' + peerDependenciesMeta: + ts-node: + optional: true + dependencies: + '@babel/core': 7.12.10 + '@jest/test-sequencer': 26.6.3_ts-node@9.1.1 + '@jest/types': 26.6.2 + babel-jest: 26.6.3_@babel+core@7.12.10 + chalk: 4.1.1 + deepmerge: 4.2.2 + glob: 7.1.7 + graceful-fs: 4.2.6 + jest-environment-jsdom: 26.6.2 + jest-environment-node: 26.6.2 + jest-get-type: 26.3.0 + jest-jasmine2: 26.6.3_ts-node@9.1.1 + jest-regex-util: 26.0.0 + jest-resolve: 26.6.2 + jest-util: 26.6.2 + jest-validate: 26.6.2 + micromatch: 4.0.4 + pretty-format: 26.6.2 + ts-node: 9.1.1_typescript@4.2.4 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-diff/26.6.2: + resolution: {integrity: sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==} + engines: {node: '>= 10.14.2'} + dependencies: + chalk: 4.1.1 + diff-sequences: 26.6.2 + jest-get-type: 26.3.0 + pretty-format: 26.6.2 + dev: true + + /jest-docblock/26.0.0: + resolution: {integrity: sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==} + engines: {node: '>= 10.14.2'} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each/26.6.2: + resolution: {integrity: sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + chalk: 4.1.1 + jest-get-type: 26.3.0 + jest-util: 26.6.2 + pretty-format: 26.6.2 + dev: true + + /jest-environment-jsdom-fourteen/1.0.1: + resolution: {integrity: sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q==} + dependencies: + '@jest/environment': 24.9.0 + '@jest/fake-timers': 24.9.0 + '@jest/types': 24.9.0 + jest-mock: 24.9.0 + jest-util: 24.9.0 + jsdom: 14.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-environment-jsdom/26.6.2: + resolution: {integrity: sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/environment': 26.6.2 + '@jest/fake-timers': 26.6.2 + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + jest-mock: 26.6.2 + jest-util: 26.6.2 + jsdom: 16.5.3 + transitivePeerDependencies: + - bufferutil + - canvas + - utf-8-validate + dev: true + + /jest-environment-node/26.6.2: + resolution: {integrity: sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/environment': 26.6.2 + '@jest/fake-timers': 26.6.2 + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + jest-mock: 26.6.2 + jest-util: 26.6.2 + dev: true + + /jest-get-type/26.3.0: + resolution: {integrity: sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==} + engines: {node: '>= 10.14.2'} + dev: true + + /jest-haste-map/24.9.0: + resolution: {integrity: sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==} + engines: {node: '>= 6'} + dependencies: + '@jest/types': 24.9.0 + anymatch: 2.0.0 + fb-watchman: 2.0.1 + graceful-fs: 4.2.6 + invariant: 2.2.4 + jest-serializer: 24.9.0 + jest-util: 24.9.0 + jest-worker: 24.9.0 + micromatch: 3.1.10 + sane: 4.1.0 + walker: 1.0.7 + optionalDependencies: + fsevents: 1.2.13 + dev: true + + /jest-haste-map/26.6.2: + resolution: {integrity: sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + '@types/graceful-fs': 4.1.5 + '@types/node': 14.14.45 + anymatch: 3.1.2 + fb-watchman: 2.0.1 + graceful-fs: 4.2.6 + jest-regex-util: 26.0.0 + jest-serializer: 26.6.2 + jest-util: 26.6.2 + jest-worker: 26.6.2 + micromatch: 4.0.4 + sane: 4.1.0 + walker: 1.0.7 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /jest-jasmine2/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==} + engines: {node: '>= 10.14.2'} + dependencies: + '@babel/traverse': 7.14.2 + '@jest/environment': 26.6.2 + '@jest/source-map': 26.6.2 + '@jest/test-result': 26.6.2 + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + chalk: 4.1.1 + co: 4.6.0 + expect: 26.6.2 + is-generator-fn: 2.1.0 + jest-each: 26.6.2 + jest-matcher-utils: 26.6.2 + jest-message-util: 26.6.2 + jest-runtime: 26.6.3_ts-node@9.1.1 + jest-snapshot: 26.6.2 + jest-util: 26.6.2 + pretty-format: 26.6.2 + throat: 5.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /jest-leak-detector/26.6.2: + resolution: {integrity: sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==} + engines: {node: '>= 10.14.2'} + dependencies: + jest-get-type: 26.3.0 + pretty-format: 26.6.2 + dev: true + + /jest-matcher-utils/26.6.2: + resolution: {integrity: sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==} + engines: {node: '>= 10.14.2'} + dependencies: + chalk: 4.1.1 + jest-diff: 26.6.2 + jest-get-type: 26.3.0 + pretty-format: 26.6.2 + dev: true + + /jest-message-util/24.9.0: + resolution: {integrity: sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==} + engines: {node: '>= 6'} + dependencies: + '@babel/code-frame': 7.12.13 + '@jest/test-result': 24.9.0 + '@jest/types': 24.9.0 + '@types/stack-utils': 1.0.1 + chalk: 2.4.2 + micromatch: 3.1.10 + slash: 2.0.0 + stack-utils: 1.0.5 + dev: true + + /jest-message-util/26.6.2: + resolution: {integrity: sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==} + engines: {node: '>= 10.14.2'} + dependencies: + '@babel/code-frame': 7.12.13 + '@jest/types': 26.6.2 + '@types/stack-utils': 2.0.0 + chalk: 4.1.1 + graceful-fs: 4.2.6 + micromatch: 4.0.4 + pretty-format: 26.6.2 + slash: 3.0.0 + stack-utils: 2.0.3 + dev: true + + /jest-mock/24.9.0: + resolution: {integrity: sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==} + engines: {node: '>= 6'} + dependencies: + '@jest/types': 24.9.0 + dev: true + + /jest-mock/26.6.2: + resolution: {integrity: sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + dev: true + + /jest-pnp-resolver/1.2.2_jest-resolve@26.6.2: + resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 26.6.2 + dev: true + + /jest-regex-util/24.9.0: + resolution: {integrity: sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==} + engines: {node: '>= 6'} + dev: true + + /jest-regex-util/26.0.0: + resolution: {integrity: sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==} + engines: {node: '>= 10.14.2'} + dev: true + + /jest-resolve-dependencies/26.6.3: + resolution: {integrity: sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + jest-regex-util: 26.0.0 + jest-snapshot: 26.6.2 + dev: true + + /jest-resolve/26.6.2: + resolution: {integrity: sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + chalk: 4.1.1 + graceful-fs: 4.2.6 + jest-pnp-resolver: 1.2.2_jest-resolve@26.6.2 + jest-util: 26.6.2 + read-pkg-up: 7.0.1 + resolve: 1.20.0 + slash: 3.0.0 + dev: true + + /jest-runner/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/console': 26.6.2 + '@jest/environment': 26.6.2 + '@jest/test-result': 26.6.2 + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + chalk: 4.1.1 + emittery: 0.7.2 + exit: 0.1.2 + graceful-fs: 4.2.6 + jest-config: 26.6.3_ts-node@9.1.1 + jest-docblock: 26.0.0 + jest-haste-map: 26.6.2 + jest-leak-detector: 26.6.2 + jest-message-util: 26.6.2 + jest-resolve: 26.6.2 + jest-runtime: 26.6.3_ts-node@9.1.1 + jest-util: 26.6.2 + jest-worker: 26.6.2 + source-map-support: 0.5.19 + throat: 5.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /jest-runtime/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==} + engines: {node: '>= 10.14.2'} + hasBin: true + dependencies: + '@jest/console': 26.6.2 + '@jest/environment': 26.6.2 + '@jest/fake-timers': 26.6.2 + '@jest/globals': 26.6.2 + '@jest/source-map': 26.6.2 + '@jest/test-result': 26.6.2 + '@jest/transform': 26.6.2 + '@jest/types': 26.6.2 + '@types/yargs': 15.0.13 + chalk: 4.1.1 + cjs-module-lexer: 0.6.0 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.1.7 + graceful-fs: 4.2.6 + jest-config: 26.6.3_ts-node@9.1.1 + jest-haste-map: 26.6.2 + jest-message-util: 26.6.2 + jest-mock: 26.6.2 + jest-regex-util: 26.0.0 + jest-resolve: 26.6.2 + jest-snapshot: 26.6.2 + jest-util: 26.6.2 + jest-validate: 26.6.2 + slash: 3.0.0 + strip-bom: 4.0.0 + yargs: 15.4.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /jest-serializer/24.9.0: + resolution: {integrity: sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==} + engines: {node: '>= 6'} + dev: true + + /jest-serializer/26.6.2: + resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} + engines: {node: '>= 10.14.2'} + dependencies: + '@types/node': 14.14.45 + graceful-fs: 4.2.6 + dev: true + + /jest-snapshot/26.6.2: + resolution: {integrity: sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==} + engines: {node: '>= 10.14.2'} + dependencies: + '@babel/types': 7.14.2 + '@jest/types': 26.6.2 + '@types/babel__traverse': 7.11.1 + '@types/prettier': 2.2.3 + chalk: 4.1.1 + expect: 26.6.2 + graceful-fs: 4.2.6 + jest-diff: 26.6.2 + jest-get-type: 26.3.0 + jest-haste-map: 26.6.2 + jest-matcher-utils: 26.6.2 + jest-message-util: 26.6.2 + jest-resolve: 26.6.2 + natural-compare: 1.4.0 + pretty-format: 26.6.2 + semver: 7.3.5 + dev: true + + /jest-util/24.9.0: + resolution: {integrity: sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==} + engines: {node: '>= 6'} + dependencies: + '@jest/console': 24.9.0 + '@jest/fake-timers': 24.9.0 + '@jest/source-map': 24.9.0 + '@jest/test-result': 24.9.0 + '@jest/types': 24.9.0 + callsites: 3.1.0 + chalk: 2.4.2 + graceful-fs: 4.2.6 + is-ci: 2.0.0 + mkdirp: 0.5.5 + slash: 2.0.0 + source-map: 0.6.1 + dev: true + + /jest-util/26.6.2: + resolution: {integrity: sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + chalk: 4.1.1 + graceful-fs: 4.2.6 + is-ci: 2.0.0 + micromatch: 4.0.4 + dev: true + + /jest-validate/26.6.2: + resolution: {integrity: sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/types': 26.6.2 + camelcase: 6.2.0 + chalk: 4.1.1 + jest-get-type: 26.3.0 + leven: 3.1.0 + pretty-format: 26.6.2 + dev: true + + /jest-watcher/26.6.2: + resolution: {integrity: sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==} + engines: {node: '>= 10.14.2'} + dependencies: + '@jest/test-result': 26.6.2 + '@jest/types': 26.6.2 + '@types/node': 14.14.45 + ansi-escapes: 4.3.2 + chalk: 4.1.1 + jest-util: 26.6.2 + string-length: 4.0.2 + dev: true + + /jest-worker/24.9.0: + resolution: {integrity: sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==} + engines: {node: '>= 6'} + dependencies: + merge-stream: 2.0.0 + supports-color: 6.1.0 + dev: true + + /jest-worker/26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 14.14.45 + merge-stream: 2.0.0 + supports-color: 7.2.0 + dev: true + + /jest/26.6.3_ts-node@9.1.1: + resolution: {integrity: sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==} + engines: {node: '>= 10.14.2'} + hasBin: true + dependencies: + '@jest/core': 26.6.3_ts-node@9.1.1 + import-local: 3.0.2 + jest-cli: 26.6.3_ts-node@9.1.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /joi/17.4.0: + resolution: {integrity: sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==} + dependencies: + '@hapi/hoek': 9.2.0 + '@hapi/topo': 5.0.0 + '@sideway/address': 4.1.2 + '@sideway/formula': 3.0.0 + '@sideway/pinpoint': 2.0.0 + dev: false + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml/3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /jsbn/0.1.1: + resolution: {integrity: sha1-peZUwuWi3rXyAdls77yoDA7y9RM=} + dev: true + + /jsdom/14.1.0: + resolution: {integrity: sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==} + engines: {node: '>=8'} + dependencies: + abab: 2.0.5 + acorn: 6.4.2 + acorn-globals: 4.3.4 + array-equal: 1.0.0 + cssom: 0.3.8 + cssstyle: 1.4.0 + data-urls: 1.1.0 + domexception: 1.0.1 + escodegen: 1.14.3 + html-encoding-sniffer: 1.0.2 + nwsapi: 2.2.0 + parse5: 5.1.0 + pn: 1.1.0 + request: 2.88.2 + request-promise-native: 1.0.9_request@2.88.2 + saxes: 3.1.11 + symbol-tree: 3.2.4 + tough-cookie: 2.5.0 + w3c-hr-time: 1.0.2 + w3c-xmlserializer: 1.1.2 + webidl-conversions: 4.0.2 + whatwg-encoding: 1.0.5 + whatwg-mimetype: 2.3.0 + whatwg-url: 7.1.0 + ws: 6.2.1 + xml-name-validator: 3.0.0 + dev: true + + /jsdom/16.5.3: + resolution: {integrity: sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==} + engines: {node: '>=10'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: 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 + html-encoding-sniffer: 2.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.0 + parse5: 6.0.1 + request: 2.88.2 + request-promise-native: 1.0.9_request@2.88.2 + 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 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-buffer/3.0.0: + resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=} + dev: true + + /json-buffer/3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: false + + /json-parse-better-errors/1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + dev: true + + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema/0.2.3: + resolution: {integrity: sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=} + dev: true + + /json-stringify-safe/5.0.1: + resolution: {integrity: sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=} + dev: true + + /json2mq/0.2.0: + resolution: {integrity: sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=} + dependencies: + string-convert: 0.2.1 + dev: true + + /json5/1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.5 + dev: true + + /json5/2.2.0: + resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + minimist: 1.2.5 + dev: true + + /jsonwebtoken/8.5.1: + resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} + engines: {node: '>=4', npm: '>=1.4.28'} + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 5.7.1 + dev: false + + /jsprim/1.4.1: + resolution: {integrity: sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.2.3 + verror: 1.10.0 + dev: true + + /jwa/1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: false + + /jws/3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + dev: false + + /keyv/3.1.0: + resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} + dependencies: + json-buffer: 3.0.0 + dev: true + + /keyv/4.0.3: + resolution: {integrity: sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==} + dependencies: + json-buffer: 3.0.1 + dev: false + + /kind-of/3.2.2: + resolution: {integrity: sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of/4.0.0: + resolution: {integrity: sha1-IIE989cSkosgc3hpGkUGb65y3Vc=} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of/5.1.0: + resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} + engines: {node: '>=0.10.0'} + dev: true + + /kind-of/6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kleur/3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /kuler/2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + dev: false + + /latest-version/5.1.0: + resolution: {integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==} + engines: {node: '>=8'} + dependencies: + package-json: 6.5.0 + dev: true + + /leven/3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /levn/0.3.0: + resolution: {integrity: sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: true + + /lie/3.1.1: + resolution: {integrity: sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=} + dependencies: + immediate: 3.0.6 + dev: false + + /lines-and-columns/1.1.6: + resolution: {integrity: sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=} + dev: true + + /lint-staged/10.5.4: + resolution: {integrity: sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==} + hasBin: true + dependencies: + chalk: 4.1.1 + cli-truncate: 2.1.0 + commander: 6.2.1 + cosmiconfig: 7.0.0 + debug: 4.3.1 + dedent: 0.7.0 + enquirer: 2.3.6 + execa: 4.1.0 + listr2: 3.8.2_enquirer@2.3.6 + 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 + transitivePeerDependencies: + - supports-color + dev: true + + /listr2/3.8.2_enquirer@2.3.6: + resolution: {integrity: sha512-E28Fw7Zd3HQlCJKzb9a8C8M0HtFWQeucE+S8YrSrqZObuCLPRHMRrR8gNmYt65cU9orXYHwvN5agXC36lYt7VQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + dependencies: + chalk: 4.1.1 + cli-truncate: 2.1.0 + enquirer: 2.3.6 + figures: 3.2.0 + indent-string: 4.0.0 + log-update: 4.0.0 + p-map: 4.0.0 + rxjs: 6.6.7 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + + /load-json-file/4.0.0: + resolution: {integrity: sha1-L19Fq5HjMhYjT9U62rZo607AmTs=} + engines: {node: '>=4'} + dependencies: + graceful-fs: 4.2.6 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + dev: true + + /loader-runner/4.2.0: + resolution: {integrity: sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==} + engines: {node: '>=6.11.5'} + dev: true + + /loader-utils/1.4.0: + resolution: {integrity: sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==} + engines: {node: '>=4.0.0'} + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 1.0.1 + dev: true + + /localforage/1.9.0: + resolution: {integrity: sha512-rR1oyNrKulpe+VM9cYmcFn6tsHuokyVHFaCM3+osEmxaHTbEk8oQu6eGDfS6DQLWi/N67XRmB8ECG37OES368g==} + dependencies: + lie: 3.1.1 + dev: false + + /locate-path/3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path/5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /lodash.includes/4.3.0: + resolution: {integrity: sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=} + dev: false + + /lodash.isboolean/3.0.3: + resolution: {integrity: sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=} + dev: false + + /lodash.isequal/4.5.0: + resolution: {integrity: sha1-QVxEePK8wwEgwizhDtMib30+GOA=} + dev: true + + /lodash.isinteger/4.0.4: + resolution: {integrity: sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=} + dev: false + + /lodash.isnumber/3.0.3: + resolution: {integrity: sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=} + dev: false + + /lodash.isplainobject/4.0.6: + resolution: {integrity: sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=} + dev: false + + /lodash.isstring/4.0.1: + resolution: {integrity: sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=} + dev: false + + /lodash.once/4.1.1: + resolution: {integrity: sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=} + dev: false + + /lodash.set/4.3.2: + resolution: {integrity: sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=} + dev: false + + /lodash.sortby/4.7.0: + resolution: {integrity: sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=} + dev: true + + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + /log-symbols/4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.1 + is-unicode-supported: 0.1.0 + dev: true + + /log-update/4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + + /logform/2.2.0: + resolution: {integrity: sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==} + dependencies: + colors: 1.4.0 + fast-safe-stringify: 2.0.7 + fecha: 4.2.1 + ms: 2.1.3 + triple-beam: 1.3.0 + dev: false + + /long-timeout/0.1.1: + resolution: {integrity: sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=} + dev: false + + /loose-envify/1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /lowercase-keys/1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + dev: true + + /lowercase-keys/2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + /lru-cache/4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: true + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /luxon/1.27.0: + resolution: {integrity: sha512-VKsFsPggTA0DvnxtJdiExAucKdAnwbCCNlMM5ENvHlxubqWd0xhZcdb4XgZ7QFNhaRhilXCFxHuoObP5BNA4PA==} + dev: false + + /make-dir/3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /make-error/1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /makeerror/1.0.11: + resolution: {integrity: sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=} + dependencies: + tmpl: 1.0.4 + dev: true + + /map-cache/0.2.2: + resolution: {integrity: sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=} + engines: {node: '>=0.10.0'} + dev: true + + /map-visit/1.0.0: + resolution: {integrity: sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=} + engines: {node: '>=0.10.0'} + dependencies: + object-visit: 1.0.1 + dev: true + + /md5.js/1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /media-typer/0.3.0: + resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} + engines: {node: '>= 0.6'} + dev: false + + /memoize-one/5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + dev: true + + /merge-descriptors/1.0.1: + resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=} + dev: false + + /merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /methods/1.1.2: + resolution: {integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=} + engines: {node: '>= 0.6'} + dev: false + + /micromatch/3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + dev: true + + /micromatch/4.0.4: + resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.2.3 + dev: true + + /miller-rabin/4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + dev: true + + /mime-db/1.47.0: + resolution: {integrity: sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==} + engines: {node: '>= 0.6'} + + /mime-types/2.1.30: + resolution: {integrity: sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.47.0 + + /mime/1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: false + + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-response/1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + /mimic-response/3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + + /mini-create-react-context/0.4.1_prop-types@15.7.2+react@16.14.0: + resolution: {integrity: sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==} + peerDependencies: + prop-types: ^15.0.0 + react: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + dependencies: + '@babel/runtime': 7.14.0 + prop-types: 15.7.2 + react: 16.14.0 + tiny-warning: 1.0.3 + dev: true + + /mini-store/3.0.6_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-YzffKHbYsMQGUWQRKdsearR79QsMzzJcDDmZKlJBqt5JNkqpyJHYlK6gP61O36X+sLf76sO9G6mhKBe83gIZIQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + hoist-non-react-statics: 3.3.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + shallowequal: 1.1.0 + dev: true + + /minimalistic-assert/1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + dev: true + + /minimalistic-crypto-utils/1.0.1: + resolution: {integrity: sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=} + dev: true + + /minimatch/3.0.4: + resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist/1.2.5: + resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} + + /minipass-collect/1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.1.3 + dev: true + + /minipass-flush/1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.1.3 + dev: true + + /minipass-pipeline/1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + dependencies: + minipass: 3.1.3 + dev: true + + /minipass/3.1.3: + resolution: {integrity: sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /minizlib/2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.1.3 + yallist: 4.0.0 + dev: true + + /mixin-deep/1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + dev: true + + /mkdirp/0.5.5: + resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} + hasBin: true + dependencies: + minimist: 1.2.5 + + /mkdirp/1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /moment/2.29.1: + resolution: {integrity: sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==} + dev: true + + /ms/2.0.0: + resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} + + /ms/2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + dev: false + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms/2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /nan/2.14.2: + resolution: {integrity: sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==} + dev: true + optional: true + + /nanomatch/1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + 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.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + dev: true + + /natural-compare/1.4.0: + resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} + dev: true + + /nedb/1.8.0: + resolution: {integrity: sha1-DjUCzYLABNU1WkPJ5VV3vXvZHYg=} + dependencies: + async: 0.2.10 + binary-search-tree: 0.2.5 + localforage: 1.9.0 + mkdirp: 0.5.5 + underscore: 1.4.4 + dev: false + + /negotiator/0.6.2: + resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==} + engines: {node: '>= 0.6'} + dev: false + + /neo-async/2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /nice-try/1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + dev: true + + /node-fetch/1.7.3: + resolution: {integrity: sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==} + dependencies: + encoding: 0.1.13 + is-stream: 1.1.0 + dev: true + + /node-fetch/2.6.1: + resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==} + engines: {node: 4.x || >=6.0.0} + dev: false + + /node-int64/0.4.0: + resolution: {integrity: sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=} + dev: true + + /node-libs-browser/2.2.1: + resolution: {integrity: sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==} + dependencies: + assert: 1.5.0 + browserify-zlib: 0.2.0 + buffer: 4.9.2 + console-browserify: 1.2.0 + constants-browserify: 1.0.0 + crypto-browserify: 3.12.0 + domain-browser: 1.2.0 + events: 3.3.0 + https-browserify: 1.0.0 + os-browserify: 0.3.0 + path-browserify: 0.0.1 + process: 0.11.10 + punycode: 1.4.1 + querystring-es3: 0.2.1 + readable-stream: 2.3.7 + stream-browserify: 2.0.2 + stream-http: 2.8.3 + string_decoder: 1.3.0 + timers-browserify: 2.0.12 + tty-browserify: 0.0.0 + url: 0.11.0 + util: 0.11.1 + vm-browserify: 1.1.2 + dev: true + + /node-modules-regexp/1.0.0: + resolution: {integrity: sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=} + engines: {node: '>=0.10.0'} + dev: true + + /node-notifier/8.0.2: + resolution: {integrity: sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==} + dependencies: + growly: 1.3.0 + is-wsl: 2.2.0 + semver: 7.3.5 + shellwords: 0.1.1 + uuid: 8.3.2 + which: 2.0.2 + dev: true + optional: true + + /node-releases/1.1.72: + resolution: {integrity: sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==} + dev: true + + /node-schedule/2.0.0: + resolution: {integrity: sha512-cHc9KEcfiuXxYDU+HjsBVo2FkWL1jRAUoczFoMIzRBpOA4p/NRHuuLs85AWOLgKsHtSPjN8csvwIxc2SqMv+CQ==} + engines: {node: '>=6'} + dependencies: + cron-parser: 3.5.0 + long-timeout: 0.1.1 + sorted-array-functions: 1.3.0 + dev: false + + /nodemon/2.0.7: + resolution: {integrity: sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==} + engines: {node: '>=8.10.0'} + hasBin: true + requiresBuild: true + dependencies: + chokidar: 3.5.1 + debug: 3.2.7 + ignore-by-default: 1.0.1 + minimatch: 3.0.4 + pstree.remy: 1.1.8 + semver: 5.7.1 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.3 + update-notifier: 4.1.3 + dev: true + + /nopt/1.0.10: + resolution: {integrity: sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-package-data/2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.20.0 + semver: 5.7.1 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path/1.0.0: + resolution: {integrity: sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-path/2.1.1: + resolution: {integrity: sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=} + engines: {node: '>=0.10.0'} + dependencies: + remove-trailing-separator: 1.1.0 + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-range/0.1.2: + resolution: {integrity: sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-url/1.9.1: + resolution: {integrity: sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=} + engines: {node: '>=4'} + dependencies: + object-assign: 4.1.1 + prepend-http: 1.0.4 + query-string: 4.3.4 + sort-keys: 1.1.2 + dev: true + + /normalize-url/4.5.0: + resolution: {integrity: sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==} + engines: {node: '>=8'} + + /normalize.css/7.0.0: + resolution: {integrity: sha1-q/sd2CRwZ04DIrU86xqvQSk45L8=} + dev: true + + /npm-run-path/2.0.2: + resolution: {integrity: sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=} + engines: {node: '>=4'} + dependencies: + path-key: 2.0.1 + dev: true + + /npm-run-path/4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /num2fraction/1.2.2: + resolution: {integrity: sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=} + dev: true + + /nwsapi/2.2.0: + resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==} + dev: true + + /oauth-sign/0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + dev: true + + /object-assign/4.1.1: + resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} + engines: {node: '>=0.10.0'} + + /object-copy/0.1.0: + resolution: {integrity: sha1-fn2Fi3gb18mRpBupde04EnVOmYw=} + engines: {node: '>=0.10.0'} + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + dev: true + + /object-inspect/1.10.3: + resolution: {integrity: sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==} + dev: true + + /object-keys/1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + /object-visit/1.0.1: + resolution: {integrity: sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /object.assign/4.1.2: + resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + has-symbols: 1.0.2 + object-keys: 1.1.1 + dev: true + + /object.getownpropertydescriptors/2.1.2: + resolution: {integrity: sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==} + engines: {node: '>= 0.8'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.18.0 + dev: true + + /object.pick/1.3.0: + resolution: {integrity: sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /omit.js/2.0.2: + resolution: {integrity: sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==} + dev: true + + /on-finished/2.3.0: + resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: false + + /once/1.4.0: + resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} + dependencies: + wrappy: 1.0.2 + + /one-time/1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + dependencies: + fn.name: 1.1.0 + dev: false + + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /optionator/0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + 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 + dev: true + + /os-browserify/0.3.0: + resolution: {integrity: sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=} + dev: true + + /p-cancelable/1.1.0: + resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} + engines: {node: '>=6'} + dev: true + + /p-cancelable/2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + dev: false + + /p-each-series/2.2.0: + resolution: {integrity: sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==} + engines: {node: '>=8'} + dev: true + + /p-finally/1.0.0: + resolution: {integrity: sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=} + engines: {node: '>=4'} + + /p-limit/2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit/3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate/3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate/4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-map/4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /p-queue/6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + dev: false + + /p-timeout/3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + dependencies: + p-finally: 1.0.0 + dev: false + + /p-try/2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /package-json/6.5.0: + resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==} + engines: {node: '>=8'} + dependencies: + got: 9.6.0 + registry-auth-token: 4.2.1 + registry-url: 5.1.0 + semver: 6.3.0 + dev: true + + /pako/1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: true + + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-asn1/5.1.6: + resolution: {integrity: sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==} + dependencies: + asn1.js: 5.4.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + pbkdf2: 3.1.2 + safe-buffer: 5.2.1 + dev: true + + /parse-json/4.0.0: + resolution: {integrity: sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=} + engines: {node: '>=4'} + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + dev: true + + /parse-json/5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.12.13 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.1.6 + dev: true + + /parse5/5.1.0: + resolution: {integrity: sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==} + dev: true + + /parse5/6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + dev: true + + /parseurl/1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: false + + /pascalcase/0.1.1: + resolution: {integrity: sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=} + engines: {node: '>=0.10.0'} + dev: true + + /path-browserify/0.0.1: + resolution: {integrity: sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==} + dev: true + + /path-exists/3.0.0: + resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} + engines: {node: '>=4'} + dev: true + + /path-exists/4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} + engines: {node: '>=0.10.0'} + dev: true + + /path-key/2.0.1: + resolution: {integrity: sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=} + engines: {node: '>=4'} + dev: true + + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse/1.0.6: + resolution: {integrity: sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==} + dev: true + + /path-to-regexp/0.1.7: + resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=} + dev: false + + /path-to-regexp/1.8.0: + resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==} + dependencies: + isarray: 0.0.1 + dev: true + + /path-to-regexp/2.4.0: + resolution: {integrity: sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==} + dev: true + + /path-type/3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + dependencies: + pify: 3.0.0 + dev: true + + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /pbkdf2/3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + dev: true + + /performance-now/2.1.0: + resolution: {integrity: sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=} + dev: true + + /picomatch/2.2.3: + resolution: {integrity: sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==} + engines: {node: '>=8.6'} + dev: true + + /pify/3.0.0: + resolution: {integrity: sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=} + engines: {node: '>=4'} + dev: true + + /pirates/4.0.1: + resolution: {integrity: sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==} + engines: {node: '>= 6'} + dependencies: + node-modules-regexp: 1.0.0 + dev: true + + /pkg-dir/4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /please-upgrade-node/3.2.0: + resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} + dependencies: + semver-compare: 1.0.0 + dev: true + + /pn/1.1.0: + resolution: {integrity: sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==} + dev: true + + /posix-character-classes/0.1.1: + resolution: {integrity: sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=} + engines: {node: '>=0.10.0'} + dev: true + + /postcss-attribute-case-insensitive/4.0.2: + resolution: {integrity: sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA==} + dependencies: + postcss: 7.0.32 + postcss-selector-parser: 6.0.6 + dev: true + + /postcss-color-functional-notation/2.0.1: + resolution: {integrity: sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-color-gray/5.0.0: + resolution: {integrity: sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw==} + engines: {node: '>=6.0.0'} + dependencies: + '@csstools/convert-colors': 1.4.0 + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-color-hex-alpha/5.0.3: + resolution: {integrity: sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-color-mod-function/3.0.3: + resolution: {integrity: sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@csstools/convert-colors': 1.4.0 + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-color-rebeccapurple/4.0.1: + resolution: {integrity: sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-custom-media/7.0.8: + resolution: {integrity: sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-custom-properties/8.0.11: + resolution: {integrity: sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-custom-selectors/5.1.2: + resolution: {integrity: sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-selector-parser: 5.0.0 + dev: true + + /postcss-dir-pseudo-class/5.0.0: + resolution: {integrity: sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw==} + engines: {node: '>=4.0.0'} + dependencies: + postcss: 7.0.32 + postcss-selector-parser: 5.0.0 + dev: true + + /postcss-double-position-gradients/1.0.0: + resolution: {integrity: sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-env-function/2.0.2: + resolution: {integrity: sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-flexbugs-fixes/4.2.1: + resolution: {integrity: sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-focus-visible/4.0.0: + resolution: {integrity: sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-focus-within/3.0.0: + resolution: {integrity: sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-font-variant/4.0.1: + resolution: {integrity: sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA==} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-gap-properties/2.0.0: + resolution: {integrity: sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-image-set-function/3.0.1: + resolution: {integrity: sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-initial/3.0.4: + resolution: {integrity: sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-lab-function/2.0.1: + resolution: {integrity: sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg==} + engines: {node: '>=6.0.0'} + dependencies: + '@csstools/convert-colors': 1.4.0 + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-load-config/2.1.2: + resolution: {integrity: sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==} + engines: {node: '>= 4'} + dependencies: + cosmiconfig: 5.2.1 + import-cwd: 2.1.0 + dev: true + + /postcss-loader/3.0.0: + resolution: {integrity: sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==} + engines: {node: '>= 6'} + dependencies: + loader-utils: 1.4.0 + postcss: 7.0.32 + postcss-load-config: 2.1.2 + schema-utils: 1.0.0 + dev: true + + /postcss-logical/3.0.0: + resolution: {integrity: sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-media-minmax/4.0.0: + resolution: {integrity: sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-nesting/7.0.1: + resolution: {integrity: sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-overflow-shorthand/2.0.0: + resolution: {integrity: sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-page-break/2.0.0: + resolution: {integrity: sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ==} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-place/4.0.1: + resolution: {integrity: sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-values-parser: 2.0.1 + dev: true + + /postcss-preset-env/6.7.0: + resolution: {integrity: sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg==} + engines: {node: '>=6.0.0'} + dependencies: + autoprefixer: 9.8.6 + browserslist: 4.16.6 + caniuse-lite: 1.0.30001228 + css-blank-pseudo: 0.1.4 + css-has-pseudo: 0.10.0 + css-prefers-color-scheme: 3.1.1 + cssdb: 4.4.0 + postcss: 7.0.32 + postcss-attribute-case-insensitive: 4.0.2 + postcss-color-functional-notation: 2.0.1 + postcss-color-gray: 5.0.0 + postcss-color-hex-alpha: 5.0.3 + postcss-color-mod-function: 3.0.3 + postcss-color-rebeccapurple: 4.0.1 + postcss-custom-media: 7.0.8 + postcss-custom-properties: 8.0.11 + postcss-custom-selectors: 5.1.2 + postcss-dir-pseudo-class: 5.0.0 + postcss-double-position-gradients: 1.0.0 + postcss-env-function: 2.0.2 + postcss-focus-visible: 4.0.0 + postcss-focus-within: 3.0.0 + postcss-font-variant: 4.0.1 + postcss-gap-properties: 2.0.0 + postcss-image-set-function: 3.0.1 + postcss-initial: 3.0.4 + postcss-lab-function: 2.0.1 + postcss-logical: 3.0.0 + postcss-media-minmax: 4.0.0 + postcss-nesting: 7.0.1 + postcss-overflow-shorthand: 2.0.0 + postcss-page-break: 2.0.0 + postcss-place: 4.0.1 + postcss-pseudo-class-any-link: 6.0.0 + postcss-replace-overflow-wrap: 3.0.0 + postcss-selector-matches: 4.0.0 + postcss-selector-not: 4.0.1 + dev: true + + /postcss-pseudo-class-any-link/6.0.0: + resolution: {integrity: sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + postcss-selector-parser: 5.0.0 + dev: true + + /postcss-replace-overflow-wrap/3.0.0: + resolution: {integrity: sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw==} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-safe-parser/4.0.2: + resolution: {integrity: sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==} + engines: {node: '>=6.0.0'} + dependencies: + postcss: 7.0.32 + dev: true + + /postcss-selector-matches/4.0.0: + resolution: {integrity: sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww==} + dependencies: + balanced-match: 1.0.2 + postcss: 7.0.32 + dev: true + + /postcss-selector-not/4.0.1: + resolution: {integrity: sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ==} + dependencies: + balanced-match: 1.0.2 + postcss: 7.0.32 + dev: true + + /postcss-selector-parser/5.0.0: + resolution: {integrity: sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==} + engines: {node: '>=4'} + dependencies: + cssesc: 2.0.0 + indexes-of: 1.0.1 + uniq: 1.0.1 + dev: true + + /postcss-selector-parser/6.0.6: + resolution: {integrity: sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser/4.1.0: + resolution: {integrity: sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==} + dev: true + + /postcss-values-parser/2.0.1: + resolution: {integrity: sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==} + engines: {node: '>=6.14.4'} + dependencies: + flatten: 1.0.3 + indexes-of: 1.0.1 + uniq: 1.0.1 + dev: true + + /postcss/7.0.32: + resolution: {integrity: sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==} + engines: {node: '>=6.0.0'} + dependencies: + chalk: 2.4.2 + source-map: 0.6.1 + supports-color: 6.1.0 + dev: true + + /prelude-ls/1.1.2: + resolution: {integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=} + engines: {node: '>= 0.8.0'} + dev: true + + /prepend-http/1.0.4: + resolution: {integrity: sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=} + engines: {node: '>=0.10.0'} + dev: true + + /prepend-http/2.0.0: + resolution: {integrity: sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=} + engines: {node: '>=4'} + dev: true + + /prettier/2.2.1: + resolution: {integrity: sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /prettier/2.3.0: + resolution: {integrity: sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-format/26.6.2: + resolution: {integrity: sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==} + engines: {node: '>= 10'} + dependencies: + '@jest/types': 26.6.2 + ansi-regex: 5.0.0 + ansi-styles: 4.3.0 + react-is: 17.0.2 + dev: true + + /process-nextick-args/2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + /process/0.11.10: + resolution: {integrity: sha1-czIwDoQBYb2j5podHZGn1LwW8YI=} + engines: {node: '>= 0.6.0'} + dev: true + + /promise-inflight/1.0.1: + resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=} + dev: true + + /promise/7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + dependencies: + asap: 2.0.6 + dev: true + + /prompts/2.4.1: + resolution: {integrity: sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /prop-types/15.7.2: + resolution: {integrity: sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /proxy-addr/2.0.6: + resolution: {integrity: sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.1.2 + ipaddr.js: 1.9.1 + dev: false + + /pseudomap/1.0.2: + resolution: {integrity: sha1-8FKijacOYYkX7wqKw0wa5aaChrM=} + dev: true + + /psl/1.8.0: + resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==} + dev: true + + /pstree.remy/1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: true + + /public-encrypt/4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + dependencies: + bn.js: 4.12.0 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + parse-asn1: 5.1.6 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: true + + /pump/3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + /punycode/1.3.2: + resolution: {integrity: sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=} + dev: true + + /punycode/1.4.1: + resolution: {integrity: sha1-wNWmOycYgArY4esPpSachN1BhF4=} + dev: true + + /punycode/2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /pupa/2.1.1: + resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==} + engines: {node: '>=8'} + dependencies: + escape-goat: 2.1.1 + dev: true + + /qr.js/0.0.0: + resolution: {integrity: sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=} + dev: true + + /qrcode.react/1.0.1_react@17.0.2: + resolution: {integrity: sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg==} + peerDependencies: + react: ^15.5.3 || ^16.0.0 || ^17.0.0 + dependencies: + loose-envify: 1.4.0 + prop-types: 15.7.2 + qr.js: 0.0.0 + react: 17.0.2 + dev: true + + /qs/6.10.1: + resolution: {integrity: sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /qs/6.5.2: + resolution: {integrity: sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==} + engines: {node: '>=0.6'} + dev: true + + /qs/6.7.0: + resolution: {integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==} + engines: {node: '>=0.6'} + dev: false + + /query-string/4.3.4: + resolution: {integrity: sha1-u7aTucqRXCMlFbIosaArYJBD2+s=} + engines: {node: '>=0.10.0'} + dependencies: + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + dev: true + + /query-string/6.14.1: + resolution: {integrity: sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==} + engines: {node: '>=6'} + dependencies: + decode-uri-component: 0.2.0 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + dev: true + + /querystring-es3/0.2.1: + resolution: {integrity: sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=} + engines: {node: '>=0.4.x'} + dev: true + + /querystring/0.2.0: + resolution: {integrity: sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=} + engines: {node: '>=0.4.x'} + dev: true + + /quick-lru/5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: false + + /raf/3.4.1: + resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} + dependencies: + performance-now: 2.1.0 + dev: true + + /randombytes/2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /randomfill/1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: true + + /range-parser/1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: false + + /raw-body/2.4.0: + resolution: {integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.0 + http-errors: 1.7.2 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + + /rc-align/2.4.5: + resolution: {integrity: sha512-nv9wYUYdfyfK+qskThf4BQUSIadeI/dCsfaMZfNEoxm9HwOIioQ+LyqmMK6jWHAZQgOzMLaqawhuBXlF63vgjw==} + dependencies: + babel-runtime: 6.26.0 + dom-align: 1.12.1 + prop-types: 15.7.2 + rc-util: 4.21.1 + dev: true + + /rc-align/4.0.9_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-myAM2R4qoB6LqBul0leaqY8gFaiECDJ3MtQDmzDo9xM9NRT/04TvWOYd2YHU9zvGzqk9QXF6S9/MifzSKDZeMw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + dom-align: 1.12.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + resize-observer-polyfill: 1.5.1 + dev: true + + /rc-animate/2.11.1: + resolution: {integrity: sha512-1NyuCGFJG/0Y+9RKh5y/i/AalUCA51opyyS/jO2seELpgymZm2u9QV3xwODwEuzkmeQ1BDPxMLmYLcTJedPlkQ==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + css-animation: 1.6.1 + prop-types: 15.7.2 + raf: 3.4.1 + rc-util: 4.21.1 + react-lifecycles-compat: 3.0.4 + dev: true + + /rc-cascader/1.4.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-JVuLGrSi+3G8DZyPvlKlGVWJjhoi9NTz6REHIgRspa5WnznRkKGm2ejb0jJtz0m2IL8Q9BG4ZA2sXuqAu71ltQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + array-tree-filter: 2.1.0 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + warning: 4.0.3 + dev: true + + /rc-checkbox/2.0.3: + resolution: {integrity: sha1-Q2qdUIlI4iSYDwU16nOLSBd6jyU=} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + prop-types: 15.7.2 + rc-util: 4.21.1 + dev: true + + /rc-checkbox/2.3.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-afVi1FYiGv1U0JlpNH/UaEXdh6WUJjcWokj/nUN2TgG80bfG+MDdbfHKlLcNNba94mbjy2/SXJ1HDgrOkXGAjg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-collapse/1.9.3: + resolution: {integrity: sha512-8cG+FzudmgFCC9zRGKXJZA36zoI9Dmyjp6UDi8N80sXUch0JOpsZDxgcFzw4HPpPpK/dARtTilEe9zyuspnW0w==} + dependencies: + classnames: 2.3.1 + css-animation: 1.6.1 + prop-types: 15.7.2 + rc-animate: 2.11.1 + dev: true + + /rc-collapse/3.1.0_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-EwpNPJcLe7b+5JfyaxM9ZNnkCgqArt3QQO0Cr5p5plwz/C9h8liAmjYY5I4+hl9lAjBqb7ZwLu94+z+rt5g1WQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + shallowequal: 1.1.0 + dev: true + + /rc-dialog/8.5.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-3n4taFcjqhTE9uNuzjB+nPDeqgRBTEGBfe46mb1e7r88DgDo0lL4NnxY/PZ6PJKd2tsCt+RrgF/+YeTvJ/Thsw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-drawer/4.3.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-GMfFy4maqxS9faYXEhQ+0cA1xtkddEQzraf6SAdzWbn444DrrLogwYPk1NXSpdXjLCLxgxOj9MYtyYG42JsfXg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-dropdown/3.2.0_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-j1HSw+/QqlhxyTEF6BArVZnTmezw2LnSmRk6I9W7BCqNCKaRwleRmMMs1PHbuaG8dKHVqP6e21RQ7vPBLVnnNw==} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-field-form/1.20.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-f64KEZop7zSlrG4ef/PLlH12SLn6iHDQ3sTG+RfKBM45hikwV1i8qMf53xoX12NvXXWg1VwchggX/FSso4bWaA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>= 16.9.0' + react-dom: '>= 16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + async-validator: 3.5.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-gesture/0.0.22: + resolution: {integrity: sha512-6G6qrCE0MUTXyjh/powj91XkjRjoFL4HiJLPU5lALXHvGX+/efcUjGYUrHrrw0mwQdmrmg4POqnY/bibns+G3g==} + dependencies: + babel-runtime: 6.26.0 + dev: true + + /rc-image/5.2.4_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-kWOjhZC1OoGKfvWqtDoO9r8WUNswBwnjcstI6rf7HMudz0usmbGvewcWqsOhyaBRJL9+I4eeG+xiAoxV1xi75Q==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-dialog: 8.5.2_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-input-number/7.1.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-xKeg+cQuhFZK4PkV+m7bvnVJgJPV02bSCAnuKx7HhGA/O8a+7chbW2AFiP0UZcuAMmZe+nE0oS1Gxe0RkRqdHQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-mentions/1.5.3_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-NG/KB8YiKBCJPHHvr/QapAb4f9YzLJn7kDHtmI1K6t7ZMM5YgrjIxNNhoRKKP9zJvb9PdPts69Hbg4ZMvLVIFQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-menu: 8.10.7_react-dom@17.0.2+react@17.0.2 + rc-textarea: 0.3.4_react-dom@17.0.2+react@17.0.2 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-menu/8.10.7_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-m/ypV7OjkkUsMdutzMUxEI8tWyi0Y1TQ5YkSDk7k2uv2aCKkHYEoDKsDAfcPeejo3HMo2z5unWE+jD+dCphraw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + mini-store: 3.0.6_react-dom@17.0.2+react@17.0.2 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + resize-observer-polyfill: 1.5.1 + shallowequal: 1.1.0 + dev: true + + /rc-motion/2.4.3_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-GZLLFXHl/VqTfI7bSZNNZozcblNmDka1AAoQig7EZ6s0rWg5y0RlgrcHWO+W+nrOVbYfJDxoaQUoP2fEmvCWmA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-notification/4.5.5_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-YIfhTSw+h5GsSdgMnuMx24wqiPlg3FeamuOlkh9RkyHx+SeZVAKzQ0juy2NGvPEF2hDWi5xTqxUqLdo0L2AmGg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-overflow/1.1.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-bkGrxvWtz6xQfxBPBQcN8xOEHFCeG0R4pfLAku6kFLQF9NPMTt5HvT+Bq0+stqom9eI3WRlun6RPzfjTamPwew==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-resize-observer: 1.0.0_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-pagination/3.1.6_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-Pb2zJEt8uxXzYCWx/2qwsYZ3vSS9Eqdw0cJBli6C58/iYhmvutSBqrBJh51Z5UzYc5ZcW5CMeP5LbbKE1J3rpw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-picker/2.5.10_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-d2or2jql9SSY8CaRPybpbKkXBq3bZ6g88UKyWQZBLTCrc92Xm87RfRC/P3UEQo/CLmia3jVF7IXVi1HmNe2DZA==} + engines: {node: '>=8.x'} + peerDependencies: + dayjs: ^1.8.30 + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + date-fns: 2.21.3 + moment: 2.29.1 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + shallowequal: 1.1.0 + dev: true + + /rc-progress/3.1.3_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-Jl4fzbBExHYMoC6HBPzel0a9VmhcSXx24LVt/mdhDM90MuzoMCJjXZAlhA0V0CJi+SKjMhfBoIQ6Lla1nD4QNw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-rate/2.9.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-resize-observer/0.2.6_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-YX6nYnd6fk7zbuvT6oSDMKiZjyngjHoy+fz+vL3Tez38d/G5iGdaDJa2yE7345G6sc4Mm1IGRUIwclvltddhmA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + resize-observer-polyfill: 1.5.1 + dev: true + + /rc-resize-observer/1.0.0_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-RgKGukg1mlzyGdvzF7o/LGFC8AeoMH9aGzXTUdp6m+OApvmRdUuOscq/Y2O45cJA+rXt1ApWlpFoOIioXL3AGg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + resize-observer-polyfill: 1.5.1 + dev: true + + /rc-select/12.1.10_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-LQdUhYncvcULlrNcAShYicc1obPtnNK7/rvCD+YCm0b2BLLYxl3M3b/HOX6o+ppPej+yZulkUPeU6gcgcp9nag==} + engines: {node: '>=8.x'} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-overflow: 1.1.1_react-dom@17.0.2+react@17.0.2 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + rc-virtual-list: 3.2.6_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-slider/8.2.0: + resolution: {integrity: sha1-rjfRcUTK1g4dpurA7k/8/qCwpug=} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + prop-types: 15.7.2 + rc-tooltip: 3.7.3 + rc-util: 4.21.1 + shallowequal: 1.1.0 + warning: 3.0.0 + dev: true + + /rc-slider/9.7.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-mVaLRpDo6otasBs6yVnG02ykI3K6hIrLTNfT5eyaqduFv95UODI9PDS6fWuVVehVpdS4ENgOSwsTjrPVun+k9g==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-tooltip: 5.1.1_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + shallowequal: 1.1.0 + dev: true + + /rc-steps/4.1.3_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-GXrMfWQOhN3sVze3JnzNboHpQdNHcdFubOETUHyDpa/U3HEKBZC3xJ8XK4paBgF4OJ3bdUVLC+uBPc6dCxvDYA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-swipeout/2.0.11: + resolution: {integrity: sha512-d37Lgn4RX4OOQyuA2BFo0rGlUwrmZk5q83srH3ixJ1Y1jidr2GKjgJDbNeGUVZPNfYBL91Elu6+xfVGftWf4Lg==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + rc-gesture: 0.0.22 + react-native-swipeout: 2.3.6 + dev: true + + /rc-switch/3.2.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-table/7.13.3_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-oP4fknjvKCZAaiDnvj+yzBaWcg+JYjkASbeWonU1BbrLcomkpKvMUgPODNEzg0QdXA9OGW0PO86h4goDSW06Kg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-resize-observer: 1.0.0_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + shallowequal: 1.1.0 + dev: true + + /rc-tabs/11.7.3_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-5nd2NVss9TprPRV9r8N05SjQyAE7zDrLejxFLcbJ+BdLxSwnGnk3ws/Iq0smqKZUnPQC0XEvnpF3+zlllUUT2w==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-dropdown: 3.2.0_react-dom@17.0.2+react@17.0.2 + rc-menu: 8.10.7_react-dom@17.0.2+react@17.0.2 + rc-resize-observer: 1.0.0_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-textarea/0.3.4_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-ILUYx831ZukQPv3m7R4RGRtVVWmL1LV4ME03L22mvT56US0DGCJJaRTHs4vmpcSjFHItph5OTmhodY4BOwy81A==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-resize-observer: 1.0.0_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-tooltip/3.7.3: + resolution: {integrity: sha512-dE2ibukxxkrde7wH9W8ozHKUO4aQnPZ6qBHtrTH9LoO836PjDdiaWO73fgPB05VfJs9FbZdmGPVEbXCeOP99Ww==} + dependencies: + babel-runtime: 6.26.0 + prop-types: 15.7.2 + rc-trigger: 2.6.5 + dev: true + + /rc-tooltip/5.1.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + rc-trigger: 5.2.7_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-tree-select/4.3.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-tkouzhl8OpbTg4C9tVuP8nJ5jiZS7/wiusOIcFVgswhs1V3Jc+XHMKpLhR01egJ1bgsW1A6VrVCz3udxtdJSDA==} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-select: 12.1.10_react-dom@17.0.2+react@17.0.2 + rc-tree: 4.1.5_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-tree/4.1.5_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-q2vjcmnBDylGZ9/ZW4F9oZMKMJdbFWC7um+DAQhZG1nqyg1iwoowbBggUDUaUOEryJP+08bpliEAYnzJXbI5xQ==} + engines: {node: '>=8.x'} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + rc-virtual-list: 3.2.6_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-trigger/2.6.5: + resolution: {integrity: sha512-m6Cts9hLeZWsTvWnuMm7oElhf+03GOjOLfTuU0QmdB9ZrW7jR2IpI5rpNM7i9MvAAlMAmTx5Zr7g3uu/aMvZAw==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + prop-types: 15.7.2 + rc-align: 2.4.5 + rc-animate: 2.11.1 + rc-util: 4.21.1 + react-lifecycles-compat: 3.0.4 + dev: true + + /rc-trigger/5.2.7_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-ttRWAd47pviWDeNDszhmuSgppmHY5aCr3y1+I6kvzS9QIlflsSC4GVjuF/eNl6F4cs7eB8B3tg7TxUCTWY7BHA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-align: 4.0.9_react-dom@17.0.2+react@17.0.2 + rc-motion: 2.4.3_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-upload/4.2.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-ylCwyzKjCFpD2ZrTe49adxnyo/bJIhoydWRg9y6LwYM0eRT/GDYvkLauXR0MKWVVmCtp+x6pOjTXqd3b0Z3KzA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + classnames: 2.3.1 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc-util/4.21.1: + resolution: {integrity: sha512-Z+vlkSQVc1l8O2UjR3WQ+XdWlhj5q9BMQNLk2iOBch75CqPfrJyGtcWMcnhRlNuDu0Ndtt4kLVO8JI8BrABobg==} + dependencies: + add-dom-event-listener: 1.1.0 + prop-types: 15.7.2 + react-is: 16.13.1 + react-lifecycles-compat: 3.0.4 + shallowequal: 1.1.0 + dev: true + + /rc-util/5.12.2_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-kzqG2lHY4oZsoj5Svov12K+9wi0xQHvGzfbLlsF1PDEH1aTbgdNTwlE7mejc3MGEr+7bNHa4+T5ZemCS8vQ1Gw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + dependencies: + '@babel/runtime': 7.14.0 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + react-is: 16.13.1 + shallowequal: 1.1.0 + dev: true + + /rc-virtual-list/3.2.6_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-8FiQLDzm3c/tMX0d62SQtKDhLH7zFlSI6pWBAPt+TUntEqd3Lz9zFAmpvTu8gkvUom/HCsDSZs4wfV4wDPWC0Q==} + engines: {node: '>=8.x'} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + classnames: 2.3.1 + rc-resize-observer: 1.0.0_react-dom@17.0.2+react@17.0.2 + rc-util: 5.12.2_react-dom@17.0.2+react@17.0.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /rc/1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.5 + strip-json-comments: 2.0.1 + dev: true + + /react-codemirror2/7.2.1_codemirror@5.61.0+react@17.0.2: + resolution: {integrity: sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==} + peerDependencies: + codemirror: 5.x + react: '>=15.5 <=16.x' + dependencies: + codemirror: 5.61.0 + react: 17.0.2 + dev: true + + /react-diff-viewer/3.1.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-rmvwNdcClp6ZWdS11m1m01UnBA4OwYaLG/li0dB781e/bQEzsGyj+qewVd6W5ztBwseQ72pO7nwaCcq5jnlzcw==} + engines: {node: '>= 8'} + peerDependencies: + react: ^15.3.0 || ^16.0.0 + react-dom: ^15.3.0 || ^16.0.0 + dependencies: + classnames: 2.3.1 + create-emotion: 10.0.27 + diff: 4.0.2 + emotion: 10.0.27 + memoize-one: 5.2.1 + prop-types: 15.7.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + dev: true + + /react-dnd-html5-backend/14.0.0: + resolution: {integrity: sha512-2wAQqRFC1hbRGmk6+dKhOXsyQQOn3cN8PSZyOUeOun9J8t3tjZ7PS2+aFu7CVu2ujMDwTJR3VTwZh8pj2kCv7g==} + dependencies: + dnd-core: 14.0.0 + dev: true + + /react-dnd/14.0.2_695545ed68ea337339babea285839fc0: + resolution: {integrity: sha512-JoEL78sBCg8SzjOKMlkR70GWaPORudhWuTNqJ56lb2P8Vq0eM2+er3ZrMGiSDhOmzaRPuA9SNBz46nHCrjn11A==} + peerDependencies: + '@types/hoist-non-react-statics': '>= 3.3.1' + '@types/node': '>= 12' + '@types/react': '>= 16' + react: '>= 16.14' + peerDependenciesMeta: + '@types/hoist-non-react-statics': + optional: true + '@types/node': + optional: true + '@types/react': + optional: true + dependencies: + '@react-dnd/invariant': 2.0.0 + '@react-dnd/shallowequal': 2.0.0 + '@types/node': 14.14.45 + '@types/react': 17.0.5 + dnd-core: 14.0.0 + fast-deep-equal: 3.1.3 + hoist-non-react-statics: 3.3.2 + react: 17.0.2 + dev: true + + /react-dom/16.14.0_react@16.14.0: + resolution: {integrity: sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==} + peerDependencies: + react: ^16.14.0 + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + prop-types: 15.7.2 + react: 16.14.0 + scheduler: 0.19.1 + dev: true + + /react-dom/17.0.2_react@17.0.2: + resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} + peerDependencies: + react: 17.0.2 + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react: 17.0.2 + scheduler: 0.20.2 + dev: true + + /react-is/16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react-is/17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /react-lifecycles-compat/3.0.4: + resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} + dev: true + + /react-native-swipeout/2.3.6: + resolution: {integrity: sha512-t9suUCspzck4vp2pWggWe0frS/QOtX6yYCawHnEes75A7dZCEE74bxX2A1bQzGH9cUMjq6xsdfC94RbiDKIkJg==} + deprecated: Package no longer supported. Use at your own risk or consider using https://github.com/software-mansion/react-native-gesture-handler + dependencies: + create-react-class: 15.7.0 + prop-types: 15.7.2 + react-tween-state: 0.1.5 + dev: true + + /react-refresh/0.9.0: + resolution: {integrity: sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==} + engines: {node: '>=0.10.0'} + dev: true + + /react-router-config/5.1.1_react-router@5.2.0+react@16.14.0: + resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} + peerDependencies: + react: '>=15' + react-router: '>=5' + dependencies: + '@babel/runtime': 7.14.0 + react: 16.14.0 + react-router: 5.2.0_react@16.14.0 + dev: true + + /react-router-dom/5.2.0_react@16.14.0: + resolution: {integrity: sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==} + peerDependencies: + react: '>=15' + dependencies: + '@babel/runtime': 7.14.0 + history: 4.10.1 + loose-envify: 1.4.0 + prop-types: 15.7.2 + react: 16.14.0 + react-router: 5.2.0_react@16.14.0 + tiny-invariant: 1.1.0 + tiny-warning: 1.0.3 + dev: true + + /react-router/5.2.0_react@16.14.0: + resolution: {integrity: sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==} + peerDependencies: + react: '>=15' + dependencies: + '@babel/runtime': 7.14.0 + history: 4.10.1 + hoist-non-react-statics: 3.3.2 + loose-envify: 1.4.0 + mini-create-react-context: 0.4.1_prop-types@15.7.2+react@16.14.0 + path-to-regexp: 1.8.0 + prop-types: 15.7.2 + react: 16.14.0 + react-is: 16.13.1 + tiny-invariant: 1.1.0 + tiny-warning: 1.0.3 + dev: true + + /react-tween-state/0.1.5: + resolution: {integrity: sha1-6YsGZVHvuTy5LdG+FJlcLj3q4zk=} + dependencies: + raf: 3.4.1 + tween-functions: 1.2.0 + dev: true + + /react/16.14.0: + resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + prop-types: 15.7.2 + dev: true + + /react/17.0.2: + resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + dev: true + + /read-pkg-up/4.0.0: + resolution: {integrity: sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==} + engines: {node: '>=6'} + dependencies: + find-up: 3.0.0 + read-pkg: 3.0.0 + dev: true + + /read-pkg-up/7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg/3.0.0: + resolution: {integrity: sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=} + engines: {node: '>=4'} + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + dev: true + + /read-pkg/5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.0 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /readable-stream/2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.2 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + /readable-stream/3.6.0: + resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + /readdirp/3.5.0: + resolution: {integrity: sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.2.3 + dev: true + + /realpath-native/1.1.0: + resolution: {integrity: sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==} + engines: {node: '>=4'} + dependencies: + util.promisify: 1.1.1 + dev: true + + /redux/4.1.0: + resolution: {integrity: sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g==} + dependencies: + '@babel/runtime': 7.14.0 + dev: true + + /reflect-metadata/0.1.13: + resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + dev: false + + /regenerator-runtime/0.11.1: + resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} + dev: true + + /regenerator-runtime/0.13.5: + resolution: {integrity: sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==} + dev: true + + /regenerator-runtime/0.13.7: + resolution: {integrity: sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==} + dev: true + + /regex-not/1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + dev: true + + /registry-auth-token/4.2.1: + resolution: {integrity: sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==} + engines: {node: '>=6.0.0'} + dependencies: + rc: 1.2.8 + dev: true + + /registry-url/5.1.0: + resolution: {integrity: sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==} + engines: {node: '>=8'} + dependencies: + rc: 1.2.8 + dev: true + + /remove-trailing-separator/1.1.0: + resolution: {integrity: sha1-wkvOKig62tW8P1jg1IJJuSN52O8=} + dev: true + + /repeat-element/1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + dev: true + + /repeat-string/1.6.1: + resolution: {integrity: sha1-jcrkcOHIirwtYA//Sndihtp15jc=} + engines: {node: '>=0.10'} + dev: true + + /request-promise-core/1.1.4_request@2.88.2: + resolution: {integrity: sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==} + engines: {node: '>=0.10.0'} + peerDependencies: + request: ^2.34 + dependencies: + lodash: 4.17.21 + request: 2.88.2 + dev: true + + /request-promise-native/1.0.9_request@2.88.2: + resolution: {integrity: sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==} + engines: {node: '>=0.12.0'} + deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 + peerDependencies: + request: ^2.34 + dependencies: + request: 2.88.2 + request-promise-core: 1.1.4_request@2.88.2 + stealthy-require: 1.1.1 + tough-cookie: 2.5.0 + dev: true + + /request/2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + dependencies: + aws-sign2: 0.7.0 + aws4: 1.11.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.30 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.2 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + dev: true + + /require-directory/2.1.1: + resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename/2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /resize-observer-polyfill/1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + dev: true + + /resolve-alpn/1.1.2: + resolution: {integrity: sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==} + dev: false + + /resolve-cwd/3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-from/3.0.0: + resolution: {integrity: sha1-six699nWiBvItuZTM17rywoYh0g=} + engines: {node: '>=4'} + dev: true + + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from/5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve-pathname/3.0.0: + resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==} + dev: true + + /resolve-url/0.2.1: + resolution: {integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=} + deprecated: https://github.com/lydell/resolve-url#deprecated + dev: true + + /resolve/1.20.0: + resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==} + dependencies: + is-core-module: 2.4.0 + path-parse: 1.0.6 + dev: true + + /responselike/1.0.2: + resolution: {integrity: sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=} + dependencies: + lowercase-keys: 1.0.1 + dev: true + + /responselike/2.0.0: + resolution: {integrity: sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==} + dependencies: + lowercase-keys: 2.0.0 + dev: false + + /restore-cursor/3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.3 + dev: true + + /ret/0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.1.7 + dev: true + + /ripemd160/2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + dev: true + + /rmc-align/1.0.0: + resolution: {integrity: sha512-3gEa5/+hqqoEVoeQ25KoRc8DOsXIdSaVpaBq1zQFaV941LR3xvZIRTlxTDT/IagYwoGM1KZea/jd7cNMYP34Rg==} + dependencies: + babel-runtime: 6.26.0 + dom-align: 1.12.1 + rc-util: 4.21.1 + dev: true + + /rmc-calendar/1.1.4: + resolution: {integrity: sha512-xxQZaPFDnpHt4IFO8mukYrXSgC1W8LcNVp+EoX4iyeOJFimungOKB/iP5/cy+st8yXq8lUgk9TXsHNtM6Xo6ZA==} + dependencies: + babel-runtime: 6.26.0 + rc-animate: 2.11.1 + rmc-date-picker: 6.0.10 + dev: true + + /rmc-cascader/5.0.3: + resolution: {integrity: sha512-PxDhMjWViDdG4SMZqoXtAthGwgDyYnyxxZEE17IDDYsiCHpWtOhoIL8nsI+/hZ212UT/XF2LpqCsOlMoJiYk+w==} + dependencies: + array-tree-filter: 2.1.0 + babel-runtime: 6.26.0 + rmc-picker: 5.0.10 + dev: true + + /rmc-date-picker/6.0.10: + resolution: {integrity: sha512-/9+I6lm3EDEl6M7862V6++zFuxwsM0UEq8wSHbotYIPPmyB/65gx1cviblghOv2QfB0O9+U2w3qEJlRP/WsMrA==} + dependencies: + babel-runtime: 6.26.0 + rmc-picker: 5.0.10 + dev: true + + /rmc-dialog/1.1.1: + resolution: {integrity: sha512-28aJqtPTX6v13Z/aU1WBy1AFIXkE74PxZXde7JvtEIy9hQDTjH8fqOi822BpzAbXCyNE7jF9iFomy3H2ClsDJA==} + dependencies: + babel-runtime: 6.26.0 + rc-animate: 2.11.1 + dev: true + + /rmc-drawer/0.4.11: + resolution: {integrity: sha512-YfB9XEJ8iM0MMuLWAK4313uOxSM8NAljC8Cqun1KamXutglYTuRviUuTLNSOzV8HHPp5kNpsVduvPCGLWXvThw==} + engines: {node: '>=4.0.0'} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + prop-types: 15.7.2 + dev: true + + /rmc-feedback/2.0.0: + resolution: {integrity: sha512-5PWOGOW7VXks/l3JzlOU9NIxRpuaSS8d9zA3UULUCuTKnpwBHNvv1jSJzxgbbCQeYzROWUpgKI4za3X4C/mKmQ==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + dev: true + + /rmc-input-number/1.0.5: + resolution: {integrity: sha512-prPkEtoOVde77GnEnEaBeWjBobMOPgGqU5bd0gxfp1kt1pUN740mMpVAcH7uxpJjVfmw+kuGWtiz4S7CueagSg==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + rmc-feedback: 2.0.0 + dev: true + + /rmc-list-view/0.11.5: + resolution: {integrity: sha512-eMOC5394tLNawcdEEhF7boMpQgpjJGDdL5lS+LblAWdBec7Q4EYkUdnrKNbt+O9k5RGM6nSLAGZK5oB4FN85Lg==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + fbjs: 0.8.17 + prop-types: 15.7.2 + warning: 3.0.0 + zscroller: 0.4.8 + dev: true + + /rmc-notification/1.0.0: + resolution: {integrity: sha512-9sPxjltFvtRLt2v312Hu7OXwk53pHkBYgINRDmnJ3A5NF1qtJeCCcdN0Xr0fzJ6sbQvtGju822tWHdzYA9u7Vw==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + prop-types: 15.7.2 + rc-animate: 2.11.1 + rc-util: 4.21.1 + dev: true + + /rmc-nuka-carousel/3.0.1: + resolution: {integrity: sha512-w2EPTERMUUZqcUSKFuejjin7xsMlhrLrtS0A/igTXpFJGq3kemDKcRi7q3pSYDuZBHYBl5iV4UqsLLkjdFtrYA==} + dependencies: + exenv: 1.2.2 + raf: 3.4.1 + dev: true + + /rmc-picker/5.0.10: + resolution: {integrity: sha512-KZ70+WjcaZHnG5GyCxWCPFWAZ12s6NqyrbW73LeqH0WEqaTMMs0sOrk2f4mQAZ/CGT0XcFN6VZLw7Ozoxfn7LA==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + rmc-dialog: 1.1.1 + rmc-feedback: 2.0.0 + dev: true + + /rmc-pull-to-refresh/1.0.13: + resolution: {integrity: sha512-iYLsURiR7G/sKmRA6p2kq6ZXicn7Hyeo6VQFljssV1eMW+fzDgihhaz0kv5mza0f88vphGJvjOihT9E6+xGb6Q==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + dev: true + + /rmc-steps/1.0.1: + resolution: {integrity: sha512-8ijtwp4D1CYTtI2yerXJYqCv+GQbiBc9T12nrFngd/vM0y+58CnznGphTAueF6IWf7qbxBwcjTrcFgg7bP2YGA==} + dependencies: + babel-runtime: 6.26.0 + classnames: 2.3.1 + dev: true + + /rmc-tabs/1.2.29: + resolution: {integrity: sha512-wiJS9WSJi9JH9GQO+FqncX+zaHP31qHa/S8nDW9UXUx0qbCX294QcJEnvfB+WmsfUws7rXjs6sOQp5EDiObnHg==} + dependencies: + babel-runtime: 6.26.0 + rc-gesture: 0.0.22 + dev: true + + /rmc-tooltip/1.0.1: + resolution: {integrity: sha512-fSDArf2BlMVrHExmBiqb2TkCRJHshvXFJQ/7tMraLellwaJLNiwrxtWpW329k3S+zTtoVG8UxFS1TjBGEsMzRg==} + dependencies: + babel-runtime: 6.26.0 + rmc-trigger: 1.0.12 + dev: true + + /rmc-trigger/1.0.12: + resolution: {integrity: sha512-AccQniX7PX7Pm8hBhHEsnf3JU6CA61Xc7fAt2WbO+oXrGaI/jqN8C3COhhOXG54S5iTOjLS26j858zshwAxR9A==} + dependencies: + babel-runtime: 6.26.0 + rc-animate: 2.11.1 + rc-util: 4.21.1 + rmc-align: 1.0.0 + dev: true + + /rsvp/4.8.5: + resolution: {integrity: sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==} + engines: {node: 6.* || >= 7.*} + dev: true + + /rxjs/6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + dependencies: + tslib: 1.14.1 + dev: true + + /safe-buffer/5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + /safe-regex/1.1.0: + resolution: {integrity: sha1-QKNmnzsHfR6UPURinhV91IAjvy4=} + dependencies: + ret: 0.1.15 + dev: true + + /safer-buffer/2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + /sane/4.1.0: + resolution: {integrity: sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==} + engines: {node: 6.* || 8.* || >= 10.*} + hasBin: true + dependencies: + '@cnakazawa/watch': 1.0.4 + anymatch: 2.0.0 + capture-exit: 2.0.0 + exec-sh: 0.3.6 + execa: 1.0.0 + fb-watchman: 2.0.1 + micromatch: 3.1.10 + minimist: 1.2.5 + walker: 1.0.7 + dev: true + + /saxes/3.1.11: + resolution: {integrity: sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==} + engines: {node: '>=8'} + dependencies: + xmlchars: 2.2.0 + dev: true + + /saxes/5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + dependencies: + xmlchars: 2.2.0 + dev: true + + /scheduler/0.19.1: + resolution: {integrity: sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + dev: true + + /scheduler/0.20.2: + resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + dev: true + + /schema-utils/1.0.0: + resolution: {integrity: sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==} + engines: {node: '>= 4'} + dependencies: + ajv: 6.12.6 + ajv-errors: 1.0.1_ajv@6.12.6 + ajv-keywords: 3.5.2_ajv@6.12.6 + dev: true + + /schema-utils/3.0.0: + resolution: {integrity: sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.7 + ajv: 6.12.6 + ajv-keywords: 3.5.2_ajv@6.12.6 + dev: true + + /scroll-into-view-if-needed/2.2.28: + resolution: {integrity: sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==} + dependencies: + compute-scroll-into-view: 1.0.17 + dev: true + + /semver-compare/1.0.0: + resolution: {integrity: sha1-De4hahyUGrN+nvsXiPavxf9VN/w=} + dev: true + + /semver-diff/3.1.1: + resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /semver/5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + + /semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver/7.3.5: + resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /send/0.17.1: + resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==} + engines: {node: '>= 0.8.0'} + 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.3 + mime: 1.6.0 + ms: 2.1.1 + on-finished: 2.3.0 + range-parser: 1.2.1 + statuses: 1.5.0 + dev: false + + /serialize-javascript/5.0.1: + resolution: {integrity: sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serve-static/1.14.1: + resolution: {integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.17.1 + dev: false + + /set-blocking/2.0.0: + resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=} + dev: true + + /set-value/2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + dev: true + + /setimmediate/1.0.5: + resolution: {integrity: sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=} + dev: true + + /setprototypeof/1.1.1: + resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} + dev: false + + /sha.js/2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /shallowequal/1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + dev: true + + /shebang-command/1.2.0: + resolution: {integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + + /shebang-command/2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/1.0.0: + resolution: {integrity: sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=} + engines: {node: '>=0.10.0'} + dev: true + + /shebang-regex/3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /shellwords/0.1.1: + resolution: {integrity: sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==} + dev: true + optional: true + + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.1 + object-inspect: 1.10.3 + dev: true + + /signal-exit/3.0.3: + resolution: {integrity: sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==} + dev: true + + /simple-swizzle/0.2.2: + resolution: {integrity: sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=} + dependencies: + is-arrayish: 0.3.2 + dev: false + + /sisteransi/1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash/2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + dev: true + + /slash/3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi/3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi/4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /snapdragon-node/2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + dev: true + + /snapdragon-util/3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /snapdragon/0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + dev: true + + /sort-keys/1.1.2: + resolution: {integrity: sha1-RBttTTRnmPG05J6JIK37oOVD+a0=} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-obj: 1.1.0 + dev: true + + /sorted-array-functions/1.3.0: + resolution: {integrity: sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==} + dev: false + + /source-list-map/2.0.1: + resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} + dev: true + + /source-map-resolve/0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.0 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + dev: true + + /source-map-support/0.5.19: + resolution: {integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==} + dependencies: + buffer-from: 1.1.1 + source-map: 0.6.1 + dev: true + + /source-map-url/0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + dev: true + + /source-map/0.5.7: + resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=} + engines: {node: '>=0.10.0'} + dev: true + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map/0.7.3: + resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==} + engines: {node: '>= 8'} + dev: true + + /spdx-correct/3.1.1: + resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.7 + dev: true + + /spdx-exceptions/2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse/3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.7 + dev: true + + /spdx-license-ids/3.0.7: + resolution: {integrity: sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==} + dev: true + + /split-on-first/1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + dev: true + + /split-string/3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + dev: true + + /sprintf-js/1.0.3: + resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} + dev: true + + /sshpk/1.16.1: + resolution: {integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.4 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: true + + /ssri/8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.1.3 + dev: true + + /stack-trace/0.0.10: + resolution: {integrity: sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=} + dev: false + + /stack-utils/1.0.5: + resolution: {integrity: sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /stack-utils/2.0.3: + resolution: {integrity: sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /static-extend/0.1.2: + resolution: {integrity: sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + dev: true + + /statuses/1.5.0: + resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=} + engines: {node: '>= 0.6'} + dev: false + + /stealthy-require/1.1.1: + resolution: {integrity: sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=} + engines: {node: '>=0.10.0'} + dev: true + + /stream-browserify/2.0.2: + resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.7 + dev: true + + /stream-http/2.8.3: + resolution: {integrity: sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==} + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 2.3.7 + to-arraybuffer: 1.0.1 + xtend: 4.0.2 + dev: true + + /strict-uri-encode/1.1.0: + resolution: {integrity: sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=} + engines: {node: '>=0.10.0'} + dev: true + + /strict-uri-encode/2.0.0: + resolution: {integrity: sha1-ucczDHBChi9rFC3CdLvMWGbONUY=} + engines: {node: '>=4'} + dev: true + + /string-argv/0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + dev: true + + /string-convert/0.2.1: + resolution: {integrity: sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=} + dev: true + + /string-length/4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.0 + dev: true + + /string-width/3.1.0: + resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} + engines: {node: '>=6'} + dependencies: + emoji-regex: 7.0.3 + is-fullwidth-code-point: 2.0.0 + strip-ansi: 5.2.0 + dev: true + + /string-width/4.2.2: + resolution: {integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.0 + dev: true + + /string.prototype.trimend/1.0.4: + resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + dev: true + + /string.prototype.trimstart/1.0.4: + resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + dev: true + + /string_decoder/1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + + /string_decoder/1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + + /stringify-object/3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + dev: true + + /strip-ansi/5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + dependencies: + ansi-regex: 4.1.0 + dev: true + + /strip-ansi/6.0.0: + resolution: {integrity: sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.0 + dev: true + + /strip-bom/3.0.0: + resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=} + engines: {node: '>=4'} + dev: true + + /strip-bom/4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-eof/1.0.0: + resolution: {integrity: sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=} + engines: {node: '>=0.10.0'} + dev: true + + /strip-final-newline/2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-indent/2.0.0: + resolution: {integrity: sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=} + engines: {node: '>=4'} + dev: true + + /strip-json-comments/2.0.1: + resolution: {integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo=} + engines: {node: '>=0.10.0'} + dev: true + + /supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color/6.1.0: + resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==} + engines: {node: '>=6'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-hyperlinks/2.2.0: + resolution: {integrity: sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /swr/0.5.6_react@17.0.2: + resolution: {integrity: sha512-Bmx3L4geMZjYT5S2Z6EE6/5Cx6v1Ka0LhqZKq8d6WL2eu9y6gHWz3dUzfIK/ymZVHVfwT/EweFXiYGgfifei3w==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 + dependencies: + dequal: 2.0.2 + react: 17.0.2 + dev: true + + /symbol-tree/3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + dev: true + + /tapable/2.2.0: + resolution: {integrity: sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==} + engines: {node: '>=6'} + dev: true + + /tar/6.1.0: + resolution: {integrity: sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==} + engines: {node: '>= 10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 3.1.3 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: true + + /term-size/2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + dev: true + + /terminal-link/2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.2.0 + dev: true + + /terser-webpack-plugin/5.1.2_webpack@5.37.0: + resolution: {integrity: sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^5.1.0 + dependencies: + jest-worker: 26.6.2 + p-limit: 3.1.0 + schema-utils: 3.0.0 + serialize-javascript: 5.0.1 + source-map: 0.6.1 + terser: 5.7.0 + webpack: 5.37.0 + dev: true + + /terser/5.6.0: + resolution: {integrity: sha512-vyqLMoqadC1uR0vywqOZzriDYzgEkNJFK4q9GeyOBHIbiECHiWLKcWfbQWAUaPfxkjDhapSlZB9f7fkMrvkVjA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + commander: 2.20.3 + source-map: 0.7.3 + source-map-support: 0.5.19 + dev: true + + /terser/5.7.0: + resolution: {integrity: sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==} + engines: {node: '>=10'} + hasBin: true + dependencies: + commander: 2.20.3 + source-map: 0.7.3 + source-map-support: 0.5.19 + dev: true + + /test-exclude/5.2.3: + resolution: {integrity: sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==} + engines: {node: '>=6'} + dependencies: + glob: 7.1.7 + minimatch: 3.0.4 + read-pkg-up: 4.0.0 + require-main-filename: 2.0.0 + dev: true + + /test-exclude/6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.1.7 + minimatch: 3.0.4 + dev: true + + /text-hex/1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + dev: false + + /throat/5.0.0: + resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + dev: true + + /through/2.3.8: + resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=} + dev: true + + /timers-browserify/2.0.12: + resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} + engines: {node: '>=0.6.0'} + dependencies: + setimmediate: 1.0.5 + dev: true + + /tiny-invariant/1.1.0: + resolution: {integrity: sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==} + dev: true + + /tiny-warning/1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + dev: true + + /tmpl/1.0.4: + resolution: {integrity: sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=} + dev: true + + /to-arraybuffer/1.0.1: + resolution: {integrity: sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=} + dev: true + + /to-fast-properties/2.0.0: + resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} + engines: {node: '>=4'} + dev: true + + /to-object-path/0.3.0: + resolution: {integrity: sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /to-readable-stream/1.0.0: + resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} + engines: {node: '>=6'} + dev: true + + /to-regex-range/2.1.1: + resolution: {integrity: sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + dev: true + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /to-regex/3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + dev: true + + /toggle-selection/1.0.6: + resolution: {integrity: sha1-bkWxJj8gF/oKzH2J14sVuL932jI=} + dev: true + + /toidentifier/1.0.0: + resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} + engines: {node: '>=0.6'} + dev: false + + /touch/3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + dependencies: + nopt: 1.0.10 + dev: true + + /tough-cookie/2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + dependencies: + psl: 1.8.0 + punycode: 2.1.1 + dev: true + + /tough-cookie/4.0.0: + resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} + engines: {node: '>=6'} + dependencies: + psl: 1.8.0 + punycode: 2.1.1 + universalify: 0.1.2 + dev: true + + /tr46/1.0.1: + resolution: {integrity: sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=} + dependencies: + punycode: 2.1.1 + dev: true + + /tr46/2.0.2: + resolution: {integrity: sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==} + engines: {node: '>=8'} + dependencies: + punycode: 2.1.1 + dev: true + + /triple-beam/1.3.0: + resolution: {integrity: sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==} + dev: false + + /ts-node/9.1.1_typescript@4.2.4: + resolution: {integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==} + engines: {node: '>=10.0.0'} + hasBin: true + peerDependencies: + typescript: '>=2.7' + dependencies: + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + source-map-support: 0.5.19 + typescript: 4.2.4 + yn: 3.1.1 + dev: true + + /tslib/1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tty-browserify/0.0.0: + resolution: {integrity: sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=} + dev: true + + /tunnel-agent/0.6.0: + resolution: {integrity: sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /tween-functions/1.2.0: + resolution: {integrity: sha1-GuOlDnxguz3vd06scHrLynO7w/8=} + dev: true + + /tweetnacl/0.14.5: + resolution: {integrity: sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=} + dev: true + + /type-check/0.3.2: + resolution: {integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + dev: true + + /type-detect/4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest/0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest/0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /type-is/1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.30 + dev: false + + /typedarray-to-buffer/3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: true + + /typedi/0.8.0: + resolution: {integrity: sha512-/c7Bxnm6eh5kXx2I+mTuO+2OvoWni5+rXA3PhXwVWCtJRYmz3hMok5s1AKLzoDvNAZqj/Q/acGstN0ri5aQoOA==} + dev: false + + /typescript/4.2.4: + resolution: {integrity: sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /ua-parser-js/0.7.28: + resolution: {integrity: sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==} + dev: true + + /umi-request/1.3.5: + resolution: {integrity: sha512-PqGz1mbLTkLjvL7ovM5Tmx/ChfY819T6P6VIsp4n15Lldn9Q85VYil4WuHSPpnur7I0thbWBuMnfLY7j5QWstg==} + dependencies: + isomorphic-fetch: 2.2.1 + qs: 6.10.1 + dev: true + + /umi/3.4.20: + resolution: {integrity: sha512-bmpE0UQXULw98VND7jzuV0AmC00vBP+jiRH5O5XajuH+cisstu4f1lDsGDfZ0HbMB3go9ELE66UIeLiWkaGqHA==} + hasBin: true + dependencies: + '@umijs/bundler-webpack': 3.4.20 + '@umijs/core': 3.4.20 + '@umijs/deps': 3.4.20 + '@umijs/preset-built-in': 3.4.20_react-dom@16.14.0+react@16.14.0 + '@umijs/runtime': 3.4.20_react@16.14.0 + '@umijs/types': 3.4.20 + '@umijs/utils': 3.4.20 + react: 16.14.0 + react-dom: 16.14.0_react@16.14.0 + v8-compile-cache: 2.3.0 + dev: true + + /unbox-primitive/1.0.1: + resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==} + dependencies: + function-bind: 1.1.1 + has-bigints: 1.0.1 + has-symbols: 1.0.2 + which-boxed-primitive: 1.0.2 + dev: true + + /undefsafe/2.0.3: + resolution: {integrity: sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==} + dependencies: + debug: 2.6.9 + dev: true + + /underscore/1.4.4: + resolution: {integrity: sha1-YaajIBBiKvoHljvzJSA88SI51gQ=} + dev: false + + /union-value/1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + dev: true + + /uniq/1.0.1: + resolution: {integrity: sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=} + dev: true + + /unique-filename/1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + dependencies: + unique-slug: 2.0.2 + dev: true + + /unique-slug/2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + dependencies: + imurmurhash: 0.1.4 + dev: true + + /unique-string/2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + dependencies: + crypto-random-string: 2.0.0 + dev: true + + /universalify/0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /unpipe/1.0.0: + resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=} + engines: {node: '>= 0.8'} + dev: false + + /unset-value/1.0.0: + resolution: {integrity: sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=} + engines: {node: '>=0.10.0'} + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + dev: true + + /unstated-next/1.1.0: + resolution: {integrity: sha512-AAn47ZncPvgBGOvMcn8tSRxsrqwf2VdAPxLASTuLJvZt4rhKfDvUkmYZLGfclImSfTVMv7tF4ynaVxin0JjDCA==} + dev: true + + /update-notifier/4.1.3: + resolution: {integrity: sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==} + engines: {node: '>=8'} + 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.2 + is-npm: 4.0.0 + is-yarn-global: 0.3.0 + latest-version: 5.1.0 + pupa: 2.1.1 + semver-diff: 3.1.1 + xdg-basedir: 4.0.0 + dev: true + + /uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /urix/0.1.0: + resolution: {integrity: sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=} + deprecated: Please see https://github.com/lydell/urix#deprecated + dev: true + + /url-parse-lax/3.0.0: + resolution: {integrity: sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=} + engines: {node: '>=4'} + dependencies: + prepend-http: 2.0.0 + dev: true + + /url/0.11.0: + resolution: {integrity: sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=} + dependencies: + punycode: 1.3.2 + querystring: 0.2.0 + dev: true + + /use-json-comparison/1.0.5_react@17.0.2: + resolution: {integrity: sha512-P/AgEKXphcN0L/8G5wLfbEz88mZQ9ayHS1OVESZaS2nxkN/msDWTGE8E1e9HXOWCZ9yoAfDrbVKAmTYpsYupFA==} + peerDependencies: + react: 16.x + dependencies: + react: 17.0.2 + dev: true + + /use-media-antd-query/1.0.7_react@17.0.2: + resolution: {integrity: sha512-vxO+ThMiuHevxrdbNfcs8NCQ2GXy6b4n8YS273fKxLMEu4P3fmEm5cPdSdN2qh07uMclk5R6AHHhjga31I0pDg==} + peerDependencies: + react: '>=16.9.0' + dependencies: + react: 17.0.2 + dev: true + + /use-subscription/1.5.1_react@16.14.0: + resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 + dependencies: + object-assign: 4.1.1 + react: 16.14.0 + dev: true + + /use/3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + dev: true + + /util-deprecate/1.0.2: + resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} + + /util.promisify/1.1.1: + resolution: {integrity: sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + for-each: 0.3.3 + has-symbols: 1.0.2 + object.getownpropertydescriptors: 2.1.2 + dev: true + + /util/0.10.3: + resolution: {integrity: sha1-evsa/lCAUkZInj23/g7TeTNqwPk=} + dependencies: + inherits: 2.0.1 + dev: true + + /util/0.11.1: + resolution: {integrity: sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==} + dependencies: + inherits: 2.0.3 + dev: true + + /utils-merge/1.0.1: + resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} + engines: {node: '>= 0.4.0'} + dev: false + + /uuid/3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + hasBin: true + dev: true + + /uuid/8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: true + optional: true + + /v8-compile-cache/2.3.0: + resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} + dev: true + + /v8-to-istanbul/7.1.2: + resolution: {integrity: sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==} + engines: {node: '>=10.10.0'} + dependencies: + '@types/istanbul-lib-coverage': 2.0.3 + convert-source-map: 1.7.0 + source-map: 0.7.3 + dev: true + + /validate-npm-package-license/3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.1.1 + spdx-expression-parse: 3.0.1 + dev: true + + /value-equal/1.0.1: + resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} + dev: true + + /vary/1.1.2: + resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=} + engines: {node: '>= 0.8'} + dev: false + + /verror/1.10.0: + resolution: {integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + + /vh-check/2.0.5: + resolution: {integrity: sha512-vHtIYWt9uLl2P2tLlatVpMwv9+ezuJCtMNjUVIpzd5Pa/dJXN8AtqkKmVRcNSlmXyCjkCkbMQX/Vs9axmdlfgg==} + dev: true + + /vm-browserify/1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + dev: true + + /w3c-hr-time/1.0.2: + resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + dependencies: + browser-process-hrtime: 1.0.0 + dev: true + + /w3c-xmlserializer/1.1.2: + resolution: {integrity: sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==} + dependencies: + domexception: 1.0.1 + webidl-conversions: 4.0.2 + xml-name-validator: 3.0.0 + dev: true + + /w3c-xmlserializer/2.0.0: + resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==} + engines: {node: '>=10'} + dependencies: + xml-name-validator: 3.0.0 + dev: true + + /walker/1.0.7: + resolution: {integrity: sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=} + dependencies: + makeerror: 1.0.11 + dev: true + + /warning/3.0.0: + resolution: {integrity: sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=} + dependencies: + loose-envify: 1.4.0 + dev: true + + /warning/4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + dependencies: + loose-envify: 1.4.0 + dev: true + + /watchpack/2.1.1: + resolution: {integrity: sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.6 + dev: true + + /webidl-conversions/4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /webidl-conversions/5.0.0: + resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} + engines: {node: '>=8'} + dev: true + + /webidl-conversions/6.1.0: + resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} + engines: {node: '>=10.4'} + dev: true + + /webpack-chain/6.5.1: + resolution: {integrity: sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==} + engines: {node: '>=8'} + dependencies: + deepmerge: 1.5.2 + javascript-stringify: 2.1.0 + dev: true + + /webpack-sources/1.4.3: + resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} + dependencies: + source-list-map: 2.0.1 + source-map: 0.6.1 + dev: true + + /webpack-sources/2.2.0: + resolution: {integrity: sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==} + engines: {node: '>=10.13.0'} + dependencies: + source-list-map: 2.0.1 + source-map: 0.6.1 + dev: true + + /webpack/5.37.0: + resolution: {integrity: sha512-yvdhgcI6QkQkDe1hINBAJ1UNevqNGTVaCkD2SSJcB8rcrNNl922RI8i2DXUAuNfANoxwsiXXEA4ZPZI9q2oGLA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@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.4 + browserslist: 4.16.6 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.8.2 + es-module-lexer: 0.4.1 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.6 + json-parse-better-errors: 1.0.2 + loader-runner: 4.2.0 + mime-types: 2.1.30 + neo-async: 2.6.2 + schema-utils: 3.0.0 + tapable: 2.2.0 + terser-webpack-plugin: 5.1.2_webpack@5.37.0 + watchpack: 2.1.1 + webpack-sources: 2.2.0 + dev: true + + /whatwg-encoding/1.0.5: + resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} + dependencies: + iconv-lite: 0.4.24 + dev: true + + /whatwg-fetch/3.6.2: + resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} + dev: true + + /whatwg-mimetype/2.3.0: + resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} + dev: true + + /whatwg-url/7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + + /whatwg-url/8.5.0: + resolution: {integrity: sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg==} + engines: {node: '>=10'} + dependencies: + lodash: 4.17.21 + tr46: 2.0.2 + webidl-conversions: 6.1.0 + dev: true + + /which-boxed-primitive/1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.2 + is-boolean-object: 1.1.1 + is-number-object: 1.0.5 + is-string: 1.0.6 + is-symbol: 1.0.4 + dev: true + + /which-module/2.0.0: + resolution: {integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=} + dev: true + + /which/1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which/2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /widest-line/3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + dependencies: + string-width: 4.2.2 + dev: true + + /winston-transport/4.4.0: + resolution: {integrity: sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==} + engines: {node: '>= 6.4.0'} + dependencies: + readable-stream: 2.3.7 + triple-beam: 1.3.0 + dev: false + + /winston/3.3.3: + resolution: {integrity: sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==} + engines: {node: '>= 6.4.0'} + dependencies: + '@dabh/diagnostics': 2.0.2 + async: 3.2.0 + is-stream: 2.0.0 + logform: 2.2.0 + one-time: 1.0.0 + readable-stream: 3.6.0 + stack-trace: 0.0.10 + triple-beam: 1.3.0 + winston-transport: 4.4.0 + dev: false + + /word-wrap/1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wrap-ansi/6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.2 + strip-ansi: 6.0.0 + dev: true + + /wrap-ansi/7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.2 + strip-ansi: 6.0.0 + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + + /write-file-atomic/2.4.1: + resolution: {integrity: sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==} + dependencies: + graceful-fs: 4.2.6 + imurmurhash: 0.1.4 + signal-exit: 3.0.3 + dev: true + + /write-file-atomic/3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.3 + typedarray-to-buffer: 3.1.5 + dev: true + + /ws/6.2.1: + resolution: {integrity: sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==} + dependencies: + async-limiter: 1.0.1 + dev: true + + /ws/7.4.5: + resolution: {integrity: sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==} + 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 + dev: true + + /xdg-basedir/4.0.0: + resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} + engines: {node: '>=8'} + dev: true + + /xml-name-validator/3.0.0: + resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} + dev: true + + /xmlchars/2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + dev: true + + /xtend/4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /y18n/4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /yallist/2.1.2: + resolution: {integrity: sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=} + dev: true + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml/1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yargs-parser/18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs/15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.2 + which-module: 2.0.0 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yn/3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /yocto-queue/0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /yorkie/2.0.0: + resolution: {integrity: sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==} + engines: {node: '>=4'} + requiresBuild: true + dependencies: + execa: 0.8.0 + is-ci: 1.2.1 + normalize-path: 1.0.0 + strip-indent: 2.0.0 + dev: true + + /zscroller/0.4.8: + resolution: {integrity: sha512-G5NiNLKx2+QhhvZi2yV1jjVXY50otktxkseX2hG2N/eixohOUk0AY8ZpbAxNqS9oJS/NxItCsowupy2tsXxAMw==} + dependencies: + babel-runtime: 6.26.0 + dev: true diff --git a/shell/share.sh b/shell/share.sh index 9df6d354..6d78e9c5 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -204,7 +204,7 @@ npm_install_sub() { npm install --production --no-save --registry=https://registry.npm.taobao.org || npm install --production --no-save else echo -e "检测到本机安装了 pnpm,使用 pnpm 替代 ...\n" - pnpm install --prod --registry=https://registry.npm.taobao.org || pnpm install --prod + pnpm install --prod fi } @@ -247,10 +247,8 @@ diff_and_copy() { update_depend() { local dir_current=$(pwd) - if [ ! -s $dir_scripts/package.json ] || [[ $(diff $dir_sample/package.json $dir_scripts/package.json) ]]; then - cp -f $dir_sample/package.json $dir_scripts/package.json - npm_install_2 $dir_scripts - fi + cp -f $dir_sample/package.json $dir_scripts/package.json + npm_install_2 $dir_scripts if [ ! -s $dir_scripts/requirements.txt ] || [[ $(diff $dir_sample/requirements.txt $dir_scripts/requirements.txt) ]]; then cp -f $dir_sample/requirements.txt $dir_scripts/requirements.txt diff --git a/shell/update.sh b/shell/update.sh index 64301d4c..3b0c890d 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -247,7 +247,6 @@ usage() { ## 更新qinglong update_qinglong() { echo -e "--------------------------------------------------------------\n" - [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" git_pull_scripts $dir_root @@ -257,8 +256,7 @@ update_qinglong() { detect_config_version update_depend - [ -f $dir_root/package.json ] && ql_depend_new=$(cat $dir_root/package.json) - [[ "$ql_depend_old" != "$ql_depend_new" ]] && npm_install_2 $dir_root + npm_install_2 $dir_root else echo -e "\n更新$dir_root失败,请检查原因...\n" fi diff --git a/src/app.tsx b/src/app.tsx index ca5c3221..a726a792 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -2,6 +2,18 @@ import { history } from 'umi'; import { request } from '@/utils/http'; import config from '@/utils/config'; +const titleMap: any = { + '/': '控制面板', + '/login': '登录', + '/crontab': '定时任务', + '/cookie': 'Session管理', + '/config': '配置文件', + '/diy': '自定义脚本', + '/diff': '对比工具', + '/log': '日志', + '/setting': '系统设置', +}; + export function render(oldRender: any) { request .get(`${config.apiPrefix}user`) @@ -22,3 +34,10 @@ export function render(oldRender: any) { } }); } + +export function onRouteChange({ matchedRoutes }: any) { + if (matchedRoutes.length) { + const path: string = matchedRoutes[matchedRoutes.length - 1].route.path; + document.title = `${titleMap[path]} - 控制面板`; + } +} diff --git a/src/assets/logo.png b/src/assets/logo.png deleted file mode 100644 index 0a53e4e8bcc51ab1229ecf06a219eeb45c26bcd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65119 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 diff --git a/src/layouts/defaultProps.tsx b/src/layouts/defaultProps.tsx index b852905b..547d6988 100644 --- a/src/layouts/defaultProps.tsx +++ b/src/layouts/defaultProps.tsx @@ -13,7 +13,7 @@ export default { route: { routes: [ { - name: 'login', + name: '登录', path: '/login', hideInMenu: true, component: '@/pages/login/index', diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index a8853dd1..d7008868 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -95,6 +95,7 @@ export default function (props: any) { }, ]; }} + pageTitleRender={() => '控制面板'} {...defaultProps} > {props.children} From 64aadb7eb8436604b0afc1c3a716723b96962d34 Mon Sep 17 00:00:00 2001 From: Fcatme <33803252+Fcatme@users.noreply.github.com> Date: Mon, 7 Jun 2021 21:42:28 +0800 Subject: [PATCH 061/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0go-cqhttp=E6=8E=A8?= =?UTF-8?q?=E9=80=81=20(#257)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/notify.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/sample/notify.js b/sample/notify.js index 1f5adcb1..4ca59b21 100644 --- a/sample/notify.js +++ b/sample/notify.js @@ -13,6 +13,15 @@ const querystring = require('querystring'); const $ = new Env(); const timeout = 15000; //超时时间(单位毫秒) +// =======================================go-cqhttp通知设置区域=========================================== +//gobot_url 填写请求地址http://127.0.0.1/send_private_msg +//gobot_token 填写在go-cqhttp文件设置的访问密钥 +//gobot_qq 填写推送到个人QQ或者QQ群号 +//go-cqhttp相关API https://docs.go-cqhttp.org/api +let GOBOT_URL = ''; // 推送到个人QQ: http://127.0.0.1/send_private_msg 群:http://127.0.0.1/send_group_msg +let GOBOT_TOKEN = ''; //访问密钥 +let GOBOT_QQ = ''; // 如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群 + // =======================================微信server酱通知设置区域=========================================== //此处填你申请的SCKEY. //(环境变量名 PUSH_KEY) @@ -73,6 +82,16 @@ let PUSH_PLUS_TOKEN = ''; let PUSH_PLUS_USER = ''; //==========================云端环境变量的判断与接收========================= +if (process.env.GOBOT_URL) { + GOBOT_URL = process.env.GOBOT_URL; +} +if (process.env.GOBOT_TOKEN) { + GOBOT_TOKEN = process.env.GOBOT_TOKEN; +} +if (process.env.GOBOT_QQ) { + GOBOT_QQ = process.env.GOBOT_QQ; +} + if (process.env.PUSH_KEY) { SCKEY = process.env.PUSH_KEY; } @@ -175,9 +194,52 @@ async function sendNotify( qywxBotNotify(text, desp), //企业微信机器人 qywxamNotify(text, desp), //企业微信应用消息推送 iGotNotify(text, desp, params), //iGot + gobotNotify(text, desp),//go-cqhttp ]); } +function gobotNotify(text, desp, time = 2100) { + return new Promise((resolve) => { + if (GOBOT_URL) { + const options = { + url: `${GOBOT_URL}?access_token=${GOBOT_TOKEN}&${GOBOT_QQ}`, + body: `message=${text}\n${desp}`, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + timeout, + }; + setTimeout(() => { + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log('发送go-cqhttp通知调用API失败!!\n'); + console.log(err); + } else { + data = JSON.parse(data); + if (data.retcode === 0) { + console.log('go-cqhttp发送通知消息成功🎉\n'); + } else if (data.retcode === 100) { + console.log(`go-cqhttp发送通知消息异常: ${data.errmsg}\n`); + } else { + console.log( + `go-cqhttp发送通知消息异常\n${JSON.stringify(data)}`, + ); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }); + }, time); + } else { + resolve(); + } + }); +} + function serverNotify(text, desp, time = 2100) { return new Promise((resolve) => { if (SCKEY) { From 9e666f434855ef267c12f4eb6ba487e214eaff16 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 7 Jun 2021 21:54:49 +0800 Subject: [PATCH 062/247] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=87=8D=E7=BD=AEql?= =?UTF-8?q?=20reset=E5=91=BD=E4=BB=A4=EF=BC=8C=E6=94=AF=E6=8C=81=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=93=8D=E4=BD=9Cck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/reset.sh | 16 +++++ shell/share.sh | 8 ++- shell/update.sh | 8 ++- src/pages/config/index.tsx | 6 +- src/pages/cookie/index.tsx | 119 ++++++++++++++++++++++++++++----- src/pages/crontab/index.tsx | 6 +- src/pages/crontab/logModal.tsx | 18 ++++- src/pages/diff/index.tsx | 6 +- src/pages/diy/index.tsx | 6 +- src/pages/log/index.tsx | 6 +- src/pages/setting/index.tsx | 6 +- 11 files changed, 166 insertions(+), 39 deletions(-) create mode 100644 shell/reset.sh diff --git a/shell/reset.sh b/shell/reset.sh new file mode 100644 index 00000000..af7ffd73 --- /dev/null +++ b/shell/reset.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# 导入通用变量与函数 +dir_shell=/ql/shell +. $dir_shell/share.sh + +echo -e "1. 开始安装青龙依赖\n" +npm_install_2 $dir_root +echo -e "青龙依赖安装完成\n" + +echo -e "2. 开始安装脚本依赖\n" +cp -f $dir_sample/package.json $dir_scripts/package.json +npm_install_2 $dir_scripts +echo -e "脚本依赖安装完成\n" + +exit 0 diff --git a/shell/share.sh b/shell/share.sh index 6d78e9c5..4f3f7621 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -56,7 +56,7 @@ import_config() { user_sum=0 for line in $(cat $file_cookie); do let user_sum+=1 - eval Cookie${user_sum}="\"$line\"" + eval Cookie${user_sum}="\"${line}\"" done command_timeout_time=${CommandTimeoutTime:-"1h"} @@ -247,8 +247,10 @@ diff_and_copy() { update_depend() { local dir_current=$(pwd) - cp -f $dir_sample/package.json $dir_scripts/package.json - npm_install_2 $dir_scripts + if [ ! -s $dir_scripts/package.json ] || [[ $(diff $dir_sample/package.json $dir_scripts/package.json) ]]; then + cp -f $dir_sample/package.json $dir_scripts/package.json + npm_install_2 $dir_scripts + fi if [ ! -s $dir_scripts/requirements.txt ] || [[ $(diff $dir_sample/requirements.txt $dir_scripts/requirements.txt) ]]; then cp -f $dir_sample/requirements.txt $dir_scripts/requirements.txt diff --git a/shell/update.sh b/shell/update.sh index 3b0c890d..ac938540 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -242,11 +242,13 @@ usage() { echo -e "5. $cmd_update rmlog # 删除旧日志" echo -e "6. $cmd_update code # 获取互助码" echo -e "6. $cmd_update bot # 启动tg-bot" + echo -e "7. $cmd_update reset # 重置青龙基础环境" } ## 更新qinglong update_qinglong() { echo -e "--------------------------------------------------------------\n" + [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" git_pull_scripts $dir_root @@ -256,7 +258,8 @@ update_qinglong() { detect_config_version update_depend - npm_install_2 $dir_root + [ -f $dir_root/package.json ] && ql_depend_new=$(cat $dir_root/package.json) + [[ "$ql_depend_old" != "$ql_depend_new" ]] && npm_install_2 $dir_root else echo -e "\n更新$dir_root失败,请检查原因...\n" fi @@ -417,6 +420,9 @@ main() { bot) . $dir_shell/bot.sh ;; + reset) + . $dir_shell/reset.sh + ;; *) echo -e "命令输入错误...\n" usage diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 0b2ad1c9..5118c6bd 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -6,7 +6,7 @@ import { Controlled as CodeMirror } from 'react-codemirror2'; import { request } from '@/utils/http'; const Config = () => { - const [width, setWdith] = useState('100%'); + const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); @@ -34,11 +34,11 @@ const Config = () => { useEffect(() => { if (document.body.clientWidth < 768) { - setWdith('auto'); + setWidth('auto'); setMarginLeft(0); setMarginTop(0); } else { - setWdith('100%'); + setWidth('100%'); setMarginLeft(0); setMarginTop(-72); } diff --git a/src/pages/cookie/index.tsx b/src/pages/cookie/index.tsx index 0624aae8..11c59458 100644 --- a/src/pages/cookie/index.tsx +++ b/src/pages/cookie/index.tsx @@ -42,6 +42,16 @@ enum StatusColor { 'error', } +enum OperationName { + '启用', + '禁用', +} + +enum OperationPath { + 'enable', + 'disable', +} + const type = 'DragableBodyRow'; const DragableBodyRow = ({ @@ -105,17 +115,6 @@ const Config = () => { return {index + 1} ; }, }, - // { - // title: '用户名', - // dataIndex: 'pin', - // key: 'pin', - // align: 'center' as const, - // render: (text: string, record: any) => { - // const match = record.value.match(/pt_pin=([^; ]+)(?=;?)/); - // const val = (match && match[1]) || '未匹配用户名'; - // return {decodeUrl(val)}; - // }, - // }, { title: '昵称', dataIndex: 'nickname', @@ -123,8 +122,10 @@ const Config = () => { align: 'center' as const, width: '15%', render: (text: string, record: any, index: number) => { + const match = record.value.match(/pt_pin=([^; ]+)(?=;?)/); + const val = (match && match[1]) || '未匹配用户名'; return ( - {record.nickname || '-'} + {record.nickname || val} ); }, }, @@ -204,13 +205,14 @@ const Config = () => { ), }, ]; - const [width, setWdith] = useState('100%'); + const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); const [editedCookie, setEditedCookie] = useState(); + const [selectedRowIds, setSelectedRowIds] = useState([]); const getCookies = () => { setLoading(true); @@ -376,13 +378,68 @@ const Config = () => { [value], ); + const onSelectChange = (selectedIds: any[]) => { + setSelectedRowIds(selectedIds); + }; + + const rowSelection = { + selectedRowIds, + onChange: onSelectChange, + }; + + const delCookies = () => { + Modal.confirm({ + title: '确认删除', + content: <>确认删除选中的Cookie吗, + onOk() { + request + .delete(`${config.apiPrefix}cookies`, { data: selectedRowIds }) + .then((data: any) => { + if (data.code === 200) { + message.success('批量删除成功'); + setSelectedRowIds([]); + getCookies(); + } else { + message.error(data); + } + }); + }, + onCancel() { + console.log('Cancel'); + }, + }); + }; + + const operateCookies = (operationStatus: number) => { + Modal.confirm({ + title: `确认${OperationName[operationStatus]}`, + content: <>确认{OperationName[operationStatus]}选中的Cookie吗, + onOk() { + request + .put(`${config.apiPrefix}cookies/${OperationPath[operationStatus]}`, { + data: selectedRowIds, + }) + .then((data: any) => { + if (data.code === 200) { + getCookies(); + } else { + message.error(data); + } + }); + }, + onCancel() { + console.log('Cancel'); + }, + }); + }; + useEffect(() => { if (document.body.clientWidth < 768) { - setWdith('auto'); + setWidth('auto'); setMarginLeft(0); setMarginTop(0); } else { - setWdith('100%'); + setWidth('100%'); setMarginLeft(0); setMarginTop(-72); } @@ -411,12 +468,42 @@ const Config = () => { }, }} > + {selectedRowIds.length > 0 && ( +

+ + + + + 已选择 + {selectedRowIds?.length}项 + +
+ )} { }, ]; - const [width, setWdith] = useState('100%'); + const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState([]); @@ -524,11 +524,11 @@ const Crontab = () => { useEffect(() => { if (document.body.clientWidth < 768) { - setWdith('auto'); + setWidth('auto'); setMarginLeft(0); setMarginTop(0); } else { - setWdith('100%'); + setWidth('100%'); setMarginLeft(0); setMarginTop(-72); } diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index a6fa3117..deb47297 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -27,6 +27,7 @@ const CronLogModal = ({ const [value, setValue] = useState('启动中...'); const [loading, setLoading] = useState(true); const [excuting, setExcuting] = useState(true); + const [isPhone, setIsPhone] = useState(false); const getCronLog = (isFirst?: boolean) => { if (isFirst) { @@ -86,6 +87,10 @@ const CronLogModal = ({ } }, [cron]); + useEffect(() => { + setIsPhone(document.body.clientWidth < 768); + }, []); + return ( cancel()} > {!loading && value && ( -
+        
           {value}
         
)} diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index e5d79a0c..6012a695 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -7,7 +7,7 @@ import ReactDiffViewer from 'react-diff-viewer'; import './index.less'; const Crontab = () => { - const [width, setWdith] = useState('100%'); + const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); @@ -32,11 +32,11 @@ const Crontab = () => { useEffect(() => { if (document.body.clientWidth < 768) { - setWdith('auto'); + setWidth('auto'); setMarginLeft(0); setMarginTop(0); } else { - setWdith('100%'); + setWidth('100%'); setMarginLeft(0); setMarginTop(-72); } diff --git a/src/pages/diy/index.tsx b/src/pages/diy/index.tsx index 92440e79..a110a01e 100644 --- a/src/pages/diy/index.tsx +++ b/src/pages/diy/index.tsx @@ -6,7 +6,7 @@ import { Controlled as CodeMirror } from 'react-codemirror2'; import { request } from '@/utils/http'; const Crontab = () => { - const [width, setWdith] = useState('100%'); + const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); @@ -34,11 +34,11 @@ const Crontab = () => { useEffect(() => { if (document.body.clientWidth < 768) { - setWdith('auto'); + setWidth('auto'); setMarginLeft(0); setMarginTop(0); } else { - setWdith('100%'); + setWidth('100%'); setMarginLeft(0); setMarginTop(-72); } diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index a18840d8..5281cc97 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -36,7 +36,7 @@ function getFilterData(keyword: string, data: any) { } const Log = () => { - const [width, setWdith] = useState('100%'); + const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); const [title, setTitle] = useState('请选择日志文件'); @@ -103,12 +103,12 @@ const Log = () => { useEffect(() => { if (document.body.clientWidth < 768) { - setWdith('auto'); + setWidth('auto'); setMarginLeft(0); setMarginTop(0); setIsPhone(true); } else { - setWdith('100%'); + setWidth('100%'); setMarginLeft(0); setMarginTop(-72); setIsPhone(false); diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx index a65314c6..08827385 100644 --- a/src/pages/setting/index.tsx +++ b/src/pages/setting/index.tsx @@ -18,7 +18,7 @@ const optionsWithDisabled = [ ]; const Password = () => { - const [width, setWdith] = useState('100%'); + const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); @@ -56,11 +56,11 @@ const Password = () => { useEffect(() => { if (document.body.clientWidth < 768) { - setWdith('auto'); + setWidth('auto'); setMarginLeft(0); setMarginTop(0); } else { - setWdith('100%'); + setWidth('100%'); setMarginLeft(0); setMarginTop(-72); } From 26fdb626ea0120d591e8efa77deeb53704f26fa1 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 7 Jun 2021 22:14:04 +0800 Subject: [PATCH 063/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=EF=BC=8C=E6=9B=B4=E6=96=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 78 +++++++++++++++++++++++++++++++++++++++-- shell/reset.sh | 10 ++++++ src/version.ts | 4 +-- 3 files changed, 87 insertions(+), 5 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 9c040605..5217cb62 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,6 +1,6 @@ -## Version: v2.0.0-05302045 -## Date: 2021-05-30 -## Update Content: 增加GithubProxyUrl参数,访问github链接不需要代理时,可移除此参数 +## Version: v2.2.0 +## Date: 2021-06-07 +## Update Content: session管理增加批量操作\n增加go-cqhttp通知方式\n修复页面标题 ## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新 @@ -42,6 +42,78 @@ AutoStartBot="" ## 安装bot依赖时指定pip源,默认使用清华源,如不需要源,设置此参数为空 PipMirror="https://pypi.tuna.tsinghua.edu.cn/simple" +## 通知环境变量 +## 1. Server酱 +## https://sct.ftqq.com +## 下方填写 SCHKEY 值或 SendKey 值 +export PUSH_KEY="" + +## 2. BARK +## 下方填写app提供的设备码,例如:https://api.day.app/123 那么此处的设备码就是123 +export BARK_PUSH="" +## 下方填写推送声音设置,例如choo,具体值请在bark-推送铃声-查看所有铃声 +export BARK_SOUND="" + +## 3. Telegram +## 下方填写自己申请@BotFather的Token,如10xxx4:AAFcqxxxxgER5uw +export TG_BOT_TOKEN="" +## 下方填写 @getuseridbot 中获取到的纯数字ID +export TG_USER_ID="" +## Telegram 代理IP(选填) +## 下方填写代理IP地址,代理类型为 http,比如您代理是 http://127.0.0.1:1080,则填写 "127.0.0.1" +## 如需使用,请自行解除下一行的注释 +export TG_PROXY_HOST="" +## Telegram 代理端口(选填) +## 下方填写代理端口号,代理类型为 http,比如您代理是 http://127.0.0.1:1080,则填写 "1080" +## 如需使用,请自行解除下一行的注释 +export TG_PROXY_PORT="" +## Telegram 代理的认证参数(选填) +export TG_PROXY_AUTH="" +## Telegram api自建反向代理地址(选填) +## 教程:https://www.hostloc.com/thread-805441-1-1.html +## 如反向代理地址 http://aaa.bbb.ccc 则填写 aaa.bbb.ccc +## 如需使用,请赋值代理地址链接,并自行解除下一行的注释 +export TG_API_HOST="" + +## 4. 钉钉 +## 官方文档:https://developers.dingtalk.com/document/app/custom-robot-access +## 下方填写token后面的内容,只需 https://oapi.dingtalk.com/robot/send?access_token=XXX 等于=符号后面的XXX即可 +export DD_BOT_TOKEN="" +export DD_BOT_SECRET="" + +## 5. 企业微信机器人 +## 官方说明文档:https://work.weixin.qq.com/api/doc/90000/90136/91770 +## 下方填写密钥,企业微信推送 webhook 后面的 key +export QYWX_KEY="" + +## 6. 企业微信应用 +## 参考文档:http://note.youdao.com/s/HMiudGkb +## 下方填写素材库图片id(corpid,corpsecret,touser,agentid),素材库图片填0为图文消息, 填1为纯文本消息 +export QYWX_AM="" + +## 7. iGot聚合 +## 参考文档:https://wahao.github.io/Bark-MP-helper +## 下方填写iGot的推送key,支持多方式推送,确保消息可达 +export IGOT_PUSH_KEY="" + +## 8. Push Plus +## 官方网站:http://www.pushplus.plus +## 下方填写您的Token,微信扫码登录后一对一推送或一对多推送下面的token,只填 PUSH_PLUS_TOKEN 默认为一对一推送 +export PUSH_PLUS_TOKEN="" +## 一对一多推送(选填) +## 下方填写您的一对多推送的 "群组编码" ,(一对多推送下面->您的群组(如无则新建)->群组编码) +## 1. 需订阅者扫描二维码 2、如果您是创建群组所属人,也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送 +export PUSH_PLUS_USER="" + +## 8. go-cqhttp +## gobot_url 推送到个人QQ: http://127.0.0.1/send_private_msg 群:http://127.0.0.1/send_group_msg +## gobot_token 填写在go-cqhttp文件设置的访问密钥 +## gobot_qq 如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群 +## go-cqhttp相关API https://docs.go-cqhttp.org/api +export GOBOT_URL = "" +export GOBOT_TOKEN = "" +export GOBOT_QQ = "" + ## 需组合的环境变量列表,env_name需要和var_name一一对应,如何有新活动按照格式添加(不懂勿动) env_name=( JD_COOKIE diff --git a/shell/reset.sh b/shell/reset.sh index af7ffd73..9003cdb9 100644 --- a/shell/reset.sh +++ b/shell/reset.sh @@ -13,4 +13,14 @@ cp -f $dir_sample/package.json $dir_scripts/package.json npm_install_2 $dir_scripts echo -e "脚本依赖安装完成\n" +echo -e "3. 复制通知文件\n" +echo -e "复制一份 $file_notify_py_sample 为 $file_notify_py\n" +cp -fv $file_notify_py_sample $file_notify_py +echo + +echo -e "复制一份 $file_notify_js_sample 为 $file_notify_js\n" +cp -fv $file_notify_js_sample $file_notify_js + +echo -e "通知文件复制完成\n" + exit 0 diff --git a/src/version.ts b/src/version.ts index 8c1ea99e..5421497b 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.1.0'; -export const changeLog = 'https://t.me/jiaolongwang/101'; +export const version = 'v2.2.0'; +export const changeLog = 'https://t.me/jiaolongwang/102'; From a5b09240360c48bc06ac03367ad9ef50ca8c2019 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 7 Jun 2021 22:31:03 +0800 Subject: [PATCH 064/247] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9F=90=E4=B8=AAck?= =?UTF-8?q?=E4=B8=B4=E6=97=B6=E5=B1=8F=E8=94=BD=E6=9F=90=E4=B8=AA=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 7 +++++++ shell/task.sh | 3 +++ 2 files changed, 10 insertions(+) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 5217cb62..0517ec21 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -114,6 +114,13 @@ export GOBOT_URL = "" export GOBOT_TOKEN = "" export GOBOT_QQ = "" +## 如果只是想要屏蔽某个ck不执行某个脚本,可以参考下面 case 这个命令的例子来控制,脚本名称包含后缀 +## case $1 in +## test.js) +## TempBlockCookie="5" +## ;; +## esac + ## 需组合的环境变量列表,env_name需要和var_name一一对应,如何有新活动按照格式添加(不懂勿动) env_name=( JD_COOKIE diff --git a/shell/task.sh b/shell/task.sh index 11b7a05a..708d1d99 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -10,6 +10,9 @@ combine_sub() { local combined_all="" local tmp1 tmp2 for ((i = 1; i <= $user_sum; i++)); do + for num in $TempBlockCookie; do + [[ $i -eq $num ]] && continue 2 + done local tmp1=$what_combine$i local tmp2=${!tmp1} combined_all="$combined_all&$tmp2" From 5b3c37d07cd02a21609d3f28e53492a4cd746768 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 12:50:19 +0800 Subject: [PATCH 065/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dconfig=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 0517ec21..850dc6d0 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -110,9 +110,9 @@ export PUSH_PLUS_USER="" ## gobot_token 填写在go-cqhttp文件设置的访问密钥 ## gobot_qq 如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群 ## go-cqhttp相关API https://docs.go-cqhttp.org/api -export GOBOT_URL = "" -export GOBOT_TOKEN = "" -export GOBOT_QQ = "" +export GOBOT_URL="" +export GOBOT_TOKEN="" +export GOBOT_QQ="" ## 如果只是想要屏蔽某个ck不执行某个脚本,可以参考下面 case 这个命令的例子来控制,脚本名称包含后缀 ## case $1 in From 1cbc534edc89ce7489edd611f008d1f803f6fde5 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 15:28:35 +0800 Subject: [PATCH 066/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/rmlog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/rmlog.sh b/shell/rmlog.sh index 31fac006..53402417 100755 --- a/shell/rmlog.sh +++ b/shell/rmlog.sh @@ -8,7 +8,7 @@ days=$1 ## 删除运行js脚本的旧日志 remove_js_log() { - local log_full_path_list=$(ls -l $dir_log/*/*.log | awk '{print $9}') + local log_full_path_list=$(find test/ -name "*.log") local diff_time for log in $log_full_path_list; do local log_date=$(echo $log | awk -F "/" '{print $NF}' | cut -c1-10) #文件名比文件属性获得的日期要可靠 From c3c3dc3e06a886f9548001a055a197585a610c6b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 15:29:00 +0800 Subject: [PATCH 067/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/rmlog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/rmlog.sh b/shell/rmlog.sh index 53402417..bf9a39ad 100755 --- a/shell/rmlog.sh +++ b/shell/rmlog.sh @@ -8,7 +8,7 @@ days=$1 ## 删除运行js脚本的旧日志 remove_js_log() { - local log_full_path_list=$(find test/ -name "*.log") + local log_full_path_list=$(find $dir_log/ -name "*.log") local diff_time for log in $log_full_path_list; do local log_date=$(echo $log | awk -F "/" '{print $NF}' | cut -c1-10) #文件名比文件属性获得的日期要可靠 From 5989be7f259fab2133ed733dc534d46e58deb181 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 21:35:12 +0800 Subject: [PATCH 068/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E4=BA=8C=E7=BB=B4=E7=A0=81=E5=B0=BA=E5=AF=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 2 +- src/pages/crontab/logModal.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index 708d1d99..e03fb70c 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -17,7 +17,7 @@ combine_sub() { local tmp2=${!tmp1} combined_all="$combined_all&$tmp2" done - echo $combined_all | perl -pe "{s|^&||; s|^@+||; s|&@|&|g; s|@+&|&|g; s|@+|@|g; s|@+$||}" + echo $combined_all | xargs perl -pe "{s|^&||; s|^@+||; s|&@|&|g; s|@+&|&|g; s|@+|@|g; s|@+$||}" } ## 正常依次运行时,组合所有账号的Cookie与互助码 diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index deb47297..016a0c8f 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -113,7 +113,7 @@ const CronLogModal = ({ whiteSpace: 'break-spaces', lineHeight: '17px', width: 375, - zoom: 0.88, + zoom: 0.83, } } > From b6042c7e46d1b01a15ce240de5c09875eae12acd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 21:48:31 +0800 Subject: [PATCH 069/247] =?UTF-8?q?=E6=B7=BB=E5=8A=A0monospace=E5=AD=97?= =?UTF-8?q?=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/fonts/monospace.eot | Bin 0 -> 22484 bytes src/assets/fonts/monospace.svg | 590 ++++++++++++++++++++++++++++++++ src/assets/fonts/monospace.ttf | Bin 0 -> 22288 bytes src/assets/fonts/monospace.woff | Bin 0 -> 13164 bytes src/layouts/index.less | 11 + 5 files changed, 601 insertions(+) create mode 100644 src/assets/fonts/monospace.eot create mode 100644 src/assets/fonts/monospace.svg create mode 100644 src/assets/fonts/monospace.ttf create mode 100644 src/assets/fonts/monospace.woff diff --git a/src/assets/fonts/monospace.eot b/src/assets/fonts/monospace.eot new file mode 100644 index 0000000000000000000000000000000000000000..d207a795f4767d354bdc67917798b77d80dde3fa GIT binary patch literal 22484 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 Yj1uwt;boIicKmK_`TOk1z6<;R0CjM5xBvhE literal 0 HcmV?d00001 diff --git a/src/assets/fonts/monospace.svg b/src/assets/fonts/monospace.svg new file mode 100644 index 00000000..bad41a15 --- /dev/null +++ b/src/assets/fonts/monospace.svg @@ -0,0 +1,590 @@ + + + + +Created by FontForge 20110222 at Fri Feb 17 12:34:19 2012 + By www-data +The programs to draw the splines of this font are Copyright (c) 2000,2001 by George Williams. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/fonts/monospace.ttf b/src/assets/fonts/monospace.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a541cd55030c403596380ab1bc379033bd05cef8 GIT binary patch literal 22288 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 literal 0 HcmV?d00001 diff --git a/src/layouts/index.less b/src/layouts/index.less index 1fd3fb67..076f2b60 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -1,4 +1,15 @@ @import '~@/styles/variable.less'; + +@font-face { + font-family: 'monospace'; + src: url('../assets/fonts/monospace.eot?') format('eot'), + url('../assets/fonts/monospace.woff') format('woff'), + url('../assets/fonts/monospace.ttf') format('truetype'), + url('../assets/fonts/monospace.svg#monospace') format('svg'); + font-weight: normal; + font-style: normal; +} + body { height: 100%; overflow-y: hidden; From 8df18342c00a0cfa8676dbef10b55d8ea82163a4 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 21:50:48 +0800 Subject: [PATCH 070/247] =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E5=BF=BD=E7=95=A5=E5=A4=A7=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/log/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index 5281cc97..61b91229 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -11,13 +11,13 @@ function getFilterData(keyword: string, data: any) { if (keyword) { const tree: any = []; data.forEach((item: any) => { - if (item.title.includes(keyword)) { + if (item.title.toLocaleLowerCase().includes(keyword)) { tree.push(item); expandedKeys.push(...item.children.map((x: any) => x.key)); } else { const children: any[] = []; (item.children || []).forEach((subItem: any) => { - if (subItem.title.includes(keyword)) { + if (subItem.title.toLocaleLowerCase().includes(keyword)) { children.push(subItem); } }); @@ -95,7 +95,7 @@ const Log = () => { const onSearch = useCallback( (e) => { const keyword = e.target.value; - const { tree } = getFilterData(keyword, data); + const { tree } = getFilterData(keyword.toLocaleLowerCase(), data); setFilterData(tree); }, [data, setFilterData], From 69068ff899e26b5ac905bacfcbeee32aacc39506 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 22:10:12 +0800 Subject: [PATCH 071/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 5421497b..03f5de17 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.2.0'; -export const changeLog = 'https://t.me/jiaolongwang/102'; +export const version = 'v2.2.0-061'; +export const changeLog = 'https://t.me/jiaolongwang/104'; From 1824fd35fe9acd8f1f18e46069f0e403c0b6a1ab Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 8 Jun 2021 22:44:04 +0800 Subject: [PATCH 072/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtask=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/task.sh b/shell/task.sh index e03fb70c..708d1d99 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -17,7 +17,7 @@ combine_sub() { local tmp2=${!tmp1} combined_all="$combined_all&$tmp2" done - echo $combined_all | xargs perl -pe "{s|^&||; s|^@+||; s|&@|&|g; s|@+&|&|g; s|@+|@|g; s|@+$||}" + echo $combined_all | perl -pe "{s|^&||; s|^@+||; s|&@|&|g; s|@+&|&|g; s|@+|@|g; s|@+$||}" } ## 正常依次运行时,组合所有账号的Cookie与互助码 From 3355963168e2f127fb60b920f62e896551dda2cd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 9 Jun 2021 22:19:50 +0800 Subject: [PATCH 073/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=89=E5=8D=93?= =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E7=AB=AF=E6=97=A5=E5=BF=97=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fonts/SourceCodePro-Regular.otf.woff | Bin 0 -> 86532 bytes src/assets/fonts/SourceCodePro-Regular.ttf | Bin 0 -> 138680 bytes .../fonts/SourceCodePro-Regular.ttf.woff2 | Bin 0 -> 52228 bytes src/assets/fonts/monospace.eot | Bin 22484 -> 0 bytes src/assets/fonts/monospace.svg | 590 ------------------ src/assets/fonts/monospace.ttf | Bin 22288 -> 0 bytes src/assets/fonts/monospace.woff | Bin 13164 -> 0 bytes src/layouts/index.less | 11 +- src/pages/crontab/logModal.tsx | 1 + 9 files changed, 5 insertions(+), 597 deletions(-) create mode 100644 src/assets/fonts/SourceCodePro-Regular.otf.woff create mode 100644 src/assets/fonts/SourceCodePro-Regular.ttf create mode 100644 src/assets/fonts/SourceCodePro-Regular.ttf.woff2 delete mode 100644 src/assets/fonts/monospace.eot delete mode 100644 src/assets/fonts/monospace.svg delete mode 100644 src/assets/fonts/monospace.ttf delete mode 100644 src/assets/fonts/monospace.woff diff --git a/src/assets/fonts/SourceCodePro-Regular.otf.woff b/src/assets/fonts/SourceCodePro-Regular.otf.woff new file mode 100644 index 0000000000000000000000000000000000000000..33b55344f817734aca09d51ccdae436bebb6652f GIT binary patch literal 86532 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

|BVeeRvgoSEd&!9l6RWFHC#R%*f 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 z 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 VPoPKO>nq%T(TdfN`-7hl{|8{rQ_BDV literal 0 HcmV?d00001 diff --git a/src/assets/fonts/SourceCodePro-Regular.ttf.woff2 b/src/assets/fonts/SourceCodePro-Regular.ttf.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..10b558e0b69a74b8329766fffbd5f64356c7230d GIT binary patch literal 52228 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 Yj1uwt;boIicKmK_`TOk1z6<;R0CjM5xBvhE diff --git a/src/assets/fonts/monospace.svg b/src/assets/fonts/monospace.svg deleted file mode 100644 index bad41a15..00000000 --- a/src/assets/fonts/monospace.svg +++ /dev/null @@ -1,590 +0,0 @@ - - - - -Created by FontForge 20110222 at Fri Feb 17 12:34:19 2012 - By www-data -The programs to draw the splines of this font are Copyright (c) 2000,2001 by George Williams. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/fonts/monospace.ttf b/src/assets/fonts/monospace.ttf deleted file mode 100644 index a541cd55030c403596380ab1bc379033bd05cef8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22288 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 diff --git a/src/layouts/index.less b/src/layouts/index.less index 076f2b60..8d364b9b 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -1,13 +1,10 @@ @import '~@/styles/variable.less'; @font-face { - font-family: 'monospace'; - src: url('../assets/fonts/monospace.eot?') format('eot'), - url('../assets/fonts/monospace.woff') format('woff'), - url('../assets/fonts/monospace.ttf') format('truetype'), - url('../assets/fonts/monospace.svg#monospace') format('svg'); - font-weight: normal; - font-style: normal; + font-family: 'Source Code Pro'; + src: url('../assets/fonts/SourceCodePro-Regular.ttf.woff2') format('woff2'), + url('../assets/fonts/SourceCodePro-Regular.otf.woff') format('woff'), + url('../assets/fonts/SourceCodePro-Regular.ttf') format('truetype'); } body { diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 016a0c8f..2cb32d7d 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -112,6 +112,7 @@ const CronLogModal = ({ : { whiteSpace: 'break-spaces', lineHeight: '17px', + fontFamily: 'Source Code Pro', width: 375, zoom: 0.83, } From 049a87780ee2010254d52c74552bbb0f55c989d6 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 9 Jun 2021 22:31:13 +0800 Subject: [PATCH 074/247] =?UTF-8?q?ql=20repo=E5=91=BD=E4=BB=A4=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=88=86=E6=94=AF=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/share.sh | 6 ++++-- shell/update.sh | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/shell/share.sh b/shell/share.sh index 4f3f7621..248d70c2 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -275,12 +275,14 @@ git_clone_scripts() { ## 更新脚本,$1:仓库保存路径 git_pull_scripts() { local dir_current=$(pwd) - local dir_work=$1 + local dir_work="$1" + local branch="$2" + [[ $branch ]] && local cmd="origin/${branch}" cd $dir_work echo -e "开始更新仓库:$dir_work\n" git fetch --all exit_status=$? - git reset --hard + git reset --hard $cmd git pull cd $dir_current } diff --git a/shell/update.sh b/shell/update.sh index ac938540..244745df 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -14,11 +14,14 @@ reset_romote_url() { local dir_current=$(pwd) local dir_work=$1 local url=$2 + local branch="$3" + + [[ $branch ]] && local cmd="origin/${branch}" if [ -d "$dir_work/.git" ]; then cd $dir_work git remote set-url origin $url >/dev/null - git reset --hard >/dev/null + git reset --hard $cmd >/dev/null cd $dir_current fi } @@ -156,6 +159,7 @@ update_repo() { local path="$2" local blackword="$3" local dependence="$4" + local branch="$5" local urlTmp="${url%*/}" local repoTmp="${urlTmp##*/}" local repo="${repoTmp%.*}" @@ -165,11 +169,13 @@ update_repo() { local author="${authorTmp2##*.}" local repo_path="${dir_repo}/${author}_${repo}" + [[ $branch ]] && repo_path="${repo_path}_${branch}" + if [ -d ${repo_path}/.git ]; then - reset_romote_url ${repo_path} "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" - git_pull_scripts ${repo_path} + reset_romote_url ${repo_path} "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" "${branch}" + git_pull_scripts ${repo_path} "${branch}" else - git_clone_scripts ${url} ${repo_path} + git_clone_scripts ${url} ${repo_path} "${branch}" fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新${repo_path}成功...\n" @@ -380,6 +386,7 @@ main() { local p3=$3 local p4=$4 local p5=$5 + local p6=$6 log_time=$(date "+%Y-%m-%d-%H-%M-%S") log_path="$dir_log/update/${log_time}_$p1.log" case $p1 in @@ -394,7 +401,7 @@ main() { local name=$(echo "${p2##*/}" | awk -F "." '{print $1}') log_path="$dir_log/update/${log_time}_$name.log" if [[ -n $p2 ]]; then - update_repo "$p2" "$p3" "$p4" "$p5" | tee $log_path + update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee $log_path else echo -e "命令输入错误...\n" usage From 5df860befe74daac5cab0d05fa4b7f90686d931b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 9 Jun 2021 22:46:37 +0800 Subject: [PATCH 075/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B1=8F=E8=94=BD?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E8=84=9A=E6=9C=AC=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/share.sh | 1 + shell/task.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/share.sh b/shell/share.sh index 248d70c2..464be17f 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -61,6 +61,7 @@ import_config() { command_timeout_time=${CommandTimeoutTime:-"1h"} github_proxy_url=${GithubProxyUrl:-""} + block_cookie=${TempBlockCookie:-""} } ## 创建目录,$1:目录的绝对路径 diff --git a/shell/task.sh b/shell/task.sh index 708d1d99..b6208786 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -10,7 +10,7 @@ combine_sub() { local combined_all="" local tmp1 tmp2 for ((i = 1; i <= $user_sum; i++)); do - for num in $TempBlockCookie; do + for num in $block_cookie; do [[ $i -eq $num ]] && continue 2 done local tmp1=$what_combine$i From f068cd6a46a8556a75d757395b2e2939877b39fd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 9 Jun 2021 22:54:31 +0800 Subject: [PATCH 076/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 2 +- shell/update.sh | 18 +++++++++--------- src/version.ts | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 850dc6d0..44efdf7b 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,4 +1,4 @@ -## Version: v2.2.0 +## Version: v2.2.0-062 ## Date: 2021-06-07 ## Update Content: session管理增加批量操作\n增加go-cqhttp通知方式\n修复页面标题 diff --git a/shell/update.sh b/shell/update.sh index 244745df..bc5cb976 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -170,7 +170,7 @@ update_repo() { local repo_path="${dir_repo}/${author}_${repo}" [[ $branch ]] && repo_path="${repo_path}_${branch}" - + if [ -d ${repo_path}/.git ]; then reset_romote_url ${repo_path} "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" "${branch}" git_pull_scripts ${repo_path} "${branch}" @@ -241,14 +241,14 @@ run_extra_shell() { ## 脚本用法 usage() { echo -e "本脚本用法:" - echo -e "1. $cmd_update update # 更新并重启青龙" - echo -e "1. $cmd_update extra # 运行自定义脚本" - echo -e "3. $cmd_update raw # 更新单个脚本文件" - echo -e "4. $cmd_update repo # 更新单个仓库的脚本" - echo -e "5. $cmd_update rmlog # 删除旧日志" - echo -e "6. $cmd_update code # 获取互助码" - echo -e "6. $cmd_update bot # 启动tg-bot" - echo -e "7. $cmd_update reset # 重置青龙基础环境" + echo -e "1. $cmd_update update # 更新并重启青龙" + echo -e "1. $cmd_update extra # 运行自定义脚本" + echo -e "3. $cmd_update raw # 更新单个脚本文件" + echo -e "4. $cmd_update repo # 更新单个仓库的脚本" + echo -e "5. $cmd_update rmlog # 删除旧日志" + echo -e "6. $cmd_update code # 获取互助码" + echo -e "6. $cmd_update bot # 启动tg-bot" + echo -e "7. $cmd_update reset # 重置青龙基础环境" } ## 更新qinglong diff --git a/src/version.ts b/src/version.ts index 03f5de17..246fd666 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.2.0-061'; -export const changeLog = 'https://t.me/jiaolongwang/104'; +export const version = 'v2.2.0-062'; +export const changeLog = 'https://t.me/jiaolongwang/105'; From 61963d5f5dd1e80ca7682c59b4ebf97c3c84789d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 10 Jun 2021 10:28:48 +0800 Subject: [PATCH 077/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E4=BB=BB=E5=8A=A1=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/initData.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/back/loaders/initData.ts b/back/loaders/initData.ts index 927df7f5..f7aa9093 100644 --- a/back/loaders/initData.ts +++ b/back/loaders/initData.ts @@ -70,7 +70,9 @@ export default async () => { .exec((err, docs) => { for (let i = 0; i < docs.length; i++) { const doc = docs[i]; - exec(doc.command); + if (doc && doc.isDisabled !== 1) { + exec(doc.command); + } } }); From 424a1e6491f2087f946c098f887b81ef8d3f58ea Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 11 Jun 2021 22:38:33 +0800 Subject: [PATCH 078/247] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=B5=8B=E8=AF=95she?= =?UTF-8?q?ll?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/test.sh | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 shell/test.sh diff --git a/shell/test.sh b/shell/test.sh deleted file mode 100644 index 817ae298..00000000 --- a/shell/test.sh +++ /dev/null @@ -1,3 +0,0 @@ -url="https://ghproxy.com/https://github.com/zooPanda/zoo.git" -github_proxy_url="https://ghproxy.com/" -echo "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" \ No newline at end of file From 1923ceb5c2856b801de67d4fb4a6c09c8c53e368 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 18:18:01 +0800 Subject: [PATCH 079/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E4=BB=BB=E5=8A=A1=E6=97=B6=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 添加bot远程地址 2. 增加文件后缀配置 3. 增加定时任务页数缓存 --- back/api/cron.ts | 21 +++++++++++++++++++++ back/services/cron.ts | 10 ++++++++-- sample/config.sample.sh | 3 +++ shell/api.sh | 26 ++++++++++++++++++++++++++ shell/bot.sh | 8 ++++++++ shell/share.sh | 1 + shell/task.sh | 4 ++++ shell/update.sh | 9 +++++++-- src/pages/crontab/index.tsx | 24 ++++++++++++++++++------ 9 files changed, 96 insertions(+), 10 deletions(-) diff --git a/back/api/cron.ts b/back/api/cron.ts index ee3f6e4e..63436808 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -225,4 +225,25 @@ export default (app: Router) => { } }, ); + + route.put( + '/crons/status', + celebrate({ + body: Joi.object({ + ids: Joi.array().items(Joi.string().required()), + status: Joi.string().required(), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const cronService = Container.get(CronService); + const data = await cronService.status(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); }; diff --git a/back/services/cron.ts b/back/services/cron.ts index c5c718ec..88f94032 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -83,8 +83,14 @@ export default class CronService { }); } - public async status(_id: string, stopped: boolean) { - this.cronDb.update({ _id }, { $set: { stopped, saved: false } }); + public async status({ + ids, + status, + }: { + ids: string[]; + status: CrontabStatus; + }) { + this.cronDb.update({ _id: { $in: ids } }, { $set: { status } }); } public async remove(ids: string[]) { diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 44efdf7b..924ed3d2 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -10,6 +10,9 @@ AutoDelCron="true" ## 在运行 ql repo 命令时,是否自动增加新的本地定时任务 AutoAddCron="true" +## ql repo命令拉取脚本时需要拉取的文件后缀,直接写文件后缀名即可 +RepoFileExtensions="js py" + ## 由于github仓库拉取较慢,所以会默认添加代理前缀,如不需要请移除 GithubProxyUrl="https://ghproxy.com/" diff --git a/shell/api.sh b/shell/api.sh index 2e3b7d81..b5bec373 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -147,3 +147,29 @@ get_user_info() { exit 0 fi } + +update_cron_status() { + local ids=$1 + local status=$2 + local currentTimeStamp=$(date +%s) + local api=$( + curl -s "http://localhost:5700/api/crons/status?t=$currentTimeStamp" \ + -X 'PUT' \ + -H "Accept: application/json" \ + -H "Authorization: Bearer $token" \ + -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \ + -H "Content-Type: application/json;charset=UTF-8" \ + -H "Origin: http://localhost:5700" \ + -H "Referer: http://localhost:5700/crontab" \ + -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \ + --data-raw "{\"ids\":\"[$ids]\",\"status\":\"$status\"}" \ + --compressed + ) + code=$(echo $api | jq -r .code) + message=$(echo $api | jq -r .message) + if [[ $code == 200 ]]; then + echo -e "成功" + else + echo -e "失败(${message})" + fi +} diff --git a/shell/bot.sh b/shell/bot.sh index e047721f..c6b71d05 100644 --- a/shell/bot.sh +++ b/shell/bot.sh @@ -3,6 +3,7 @@ ## 导入通用变量与函数 dir_shell=/ql/shell . $dir_shell/share.sh +url="${github_proxy_url}https://github.com/SuMaiKaDe/bot.git" repo_path="${dir_repo}/dockerbot" echo -e "\n1、安装bot依赖...\n" @@ -10,6 +11,13 @@ apk --no-cache add -f zlib-dev gcc jpeg-dev python3-dev musl-dev freetype-dev echo -e "\nbot依赖安装成功...\n" echo -e "2、下载bot所需文件...\n" +if [ -d ${repo_path}/.git ]; then + git_pull_scripts ${repo_path} +else + rm -rf ${repo_path} + git_clone_scripts ${url} ${repo_path} "main" +fi + cp -rf "$repo_path/jbot" $dir_root if [[ ! -f "$dir_root/config/bot.json" ]]; then cp -f "$repo_path/config/bot.json" "$dir_root/config" diff --git a/shell/share.sh b/shell/share.sh index 464be17f..e4d9e0f2 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -62,6 +62,7 @@ import_config() { command_timeout_time=${CommandTimeoutTime:-"1h"} github_proxy_url=${GithubProxyUrl:-""} block_cookie=${TempBlockCookie:-""} + file_extensions=${RepoFileExtensions:-"js py"} } ## 创建目录,$1:目录的绝对路径 diff --git a/shell/task.sh b/shell/task.sh index b6208786..35e3ae6c 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -120,6 +120,10 @@ run_normal() { log_dir="$dir_log/${log_dir_tmp%%.*}" log_path="$log_dir/$log_time.log" make_dir "$log_dir" + + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | xargs | sed 's/ /","/g') + local status="0" ## 0 任务运行中 + update_cron_status "\"$id\"" $status timeout $command_timeout_time $which_program $p1 2>&1 | tee $log_path } diff --git a/shell/update.sh b/shell/update.sh index bc5cb976..21fac8b9 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -357,7 +357,12 @@ gen_list_repo() { rm -f $dir_list_tmp/${repo}*.list >/dev/null 2>&1 cd ${repo_path} - files=$(find . -name "*.js" | sed 's/^..//') + + local cmd="find ." + for extension in $file_extensions; do + cmd="${cmd} -o -name \"*.${extension}\"" + done + files=$($cmd | sed 's/^..//') if [[ $path ]]; then files=$(echo "$files" | egrep $path) fi @@ -365,7 +370,7 @@ gen_list_repo() { files=$(echo "$files" | egrep -v $blackword) fi if [[ $dependence ]]; then - find . -name "*.js" | sed 's/^..//' | egrep $dependence | xargs -i cp {} $dir_scripts + $cmd | sed 's/^..//' | egrep $dependence | xargs -i cp {} $dir_scripts fi for file in ${files}; do filename=$(basename $file) diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 8d57ae2f..18da79dc 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -187,6 +187,8 @@ const Crontab = () => { const [isLogModalVisible, setIsLogModalVisible] = useState(false); const [logCron, setLogCron] = useState(); const [selectedRowIds, setSelectedRowIds] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(20); const getCrons = () => { setLoading(true); @@ -233,7 +235,7 @@ const Crontab = () => { if (data.code === 200) { message.success('删除成功'); const result = [...value]; - result.splice(index, 1); + result.splice(index + pageSize * (currentPage - 1), 1); setValue(result); } else { message.error(data); @@ -264,7 +266,7 @@ const Crontab = () => { .then((data: any) => { if (data.code === 200) { const result = [...value]; - result.splice(index, 1, { + result.splice(index + pageSize * (currentPage - 1), 1, { ...record, status: CrontabStatus.running, }); @@ -298,7 +300,7 @@ const Crontab = () => { .then((data: any) => { if (data.code === 200) { const result = [...value]; - result.splice(index, 1, { + result.splice(index + pageSize * (currentPage - 1), 1, { ...record, pid: null, status: CrontabStatus.idle, @@ -342,7 +344,7 @@ const Crontab = () => { if (data.code === 200) { const newStatus = record.isDisabled === 1 ? 0 : 1; const result = [...value]; - result.splice(index, 1, { + result.splice(index + pageSize * (currentPage - 1), 1, { ...record, isDisabled: newStatus, }); @@ -429,7 +431,7 @@ const Crontab = () => { if (index === -1) { result.push(cron); } else { - result.splice(index, 1, { + result.splice(index + pageSize * (currentPage - 1), 1, { ...cron, }); } @@ -442,7 +444,7 @@ const Crontab = () => { .then((data: any) => { const index = value.findIndex((x) => x._id === cron._id); const result = [...value]; - result.splice(index, 1, { + result.splice(index + pageSize * (currentPage - 1), 1, { ...cron, ...data.data, }); @@ -511,6 +513,12 @@ const Crontab = () => { }); }; + const onPageChange = (page: number, pageSize: number | undefined) => { + setCurrentPage(page); + setPageSize(pageSize as number); + localStorage.setItem('pageSize', pageSize + ''); + }; + useEffect(() => { if (logCron) { localStorage.setItem('logCron', logCron._id); @@ -532,6 +540,7 @@ const Crontab = () => { setMarginLeft(0); setMarginTop(-72); } + setPageSize(parseInt(localStorage.getItem('pageSize') || '20')); }, []); return ( @@ -602,6 +611,9 @@ const Crontab = () => { columns={columns} pagination={{ hideOnSinglePage: true, + current: currentPage, + onChange: onPageChange, + pageSize: pageSize, showSizeChanger: true, defaultPageSize: 20, showTotal: (total: number, range: number[]) => From 0360ba0b1e6ee2f70c0cc83ff165e62c46de1067 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 18:34:12 +0800 Subject: [PATCH 080/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=AE=9A=E6=97=B6=E7=8A=B6=E6=80=81=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 6 +++--- shell/task.sh | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index b5bec373..2c2384c2 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -133,7 +133,7 @@ del_cron_api() { get_user_info() { local currentTimeStamp=$(date +%s) local api=$( - curl -s "http://localhost:5700/api/user?t=$currentTimeStamp" \ + curl -s "http://localhost:5600/api/user?t=$currentTimeStamp" \ -H 'Accept: */*' \ -H "Authorization: Bearer $token" \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36' \ @@ -153,7 +153,7 @@ update_cron_status() { local status=$2 local currentTimeStamp=$(date +%s) local api=$( - curl -s "http://localhost:5700/api/crons/status?t=$currentTimeStamp" \ + curl -s "http://localhost:5600/api/crons/status?t=$currentTimeStamp" \ -X 'PUT' \ -H "Accept: application/json" \ -H "Authorization: Bearer $token" \ @@ -162,7 +162,7 @@ update_cron_status() { -H "Origin: http://localhost:5700" \ -H "Referer: http://localhost:5700/crontab" \ -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \ - --data-raw "{\"ids\":\"[$ids]\",\"status\":\"$status\"}" \ + --data-raw "{\"ids\":[$ids],\"status\":\"$status\"}" \ --compressed ) code=$(echo $api | jq -r .code) diff --git a/shell/task.sh b/shell/task.sh index 35e3ae6c..9ea31d87 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -3,6 +3,7 @@ ## 导入通用变量与函数 dir_shell=/ql/shell . $dir_shell/share.sh +. $dir_shell/api.sh ## 组合Cookie和互助码子程序,$1:要组合的内容 combine_sub() { @@ -120,11 +121,11 @@ run_normal() { log_dir="$dir_log/${log_dir_tmp%%.*}" log_path="$log_dir/$log_time.log" make_dir "$log_dir" - + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | xargs | sed 's/ /","/g') - local status="0" ## 0 任务运行中 - update_cron_status "\"$id\"" $status + update_cron_status "\"$id\"" "0" timeout $command_timeout_time $which_program $p1 2>&1 | tee $log_path + update_cron_status "\"$id\"" "1" } ## 并发执行,因为是并发,所以日志只能直接记录在日志文件中(日志文件以Cookie编号结尾),前台执行并发跑时不会输出日志 From a53f78888677861cfa53cd3565b5c33acce37890 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 18:37:25 +0800 Subject: [PATCH 081/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0shell=20token?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 2 ++ shell/update.sh | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index 2c2384c2..c58242b8 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -173,3 +173,5 @@ update_cron_status() { echo -e "失败(${message})" fi } + +get_token \ No newline at end of file diff --git a/shell/update.sh b/shell/update.sh index 21fac8b9..70e0bddd 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -7,8 +7,6 @@ dir_shell=/ql/shell send_mark=$dir_shell/send_mark -get_token - ## 重置仓库remote url,docker专用,$1:要重置的目录,$2:要重置为的网址 reset_romote_url() { local dir_current=$(pwd) From 95221e2b1df2c8dbb75e9779422d0d29306b35a1 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 18:45:05 +0800 Subject: [PATCH 082/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8F=82=E6=95=B0=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cron.ts | 5 ++++- shell/api.sh | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/back/api/cron.ts b/back/api/cron.ts index 63436808..5206c6b6 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -238,7 +238,10 @@ export default (app: Router) => { const logger: Logger = Container.get('logger'); try { const cronService = Container.get(CronService); - const data = await cronService.status(req.body); + const data = await cronService.status({ + ...req.body, + status: parseInt(req.body.status), + }); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); diff --git a/shell/api.sh b/shell/api.sh index c58242b8..d2c1d410 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -168,9 +168,9 @@ update_cron_status() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "成功" + echo -e "更新任务状态成功" else - echo -e "失败(${message})" + echo -e "更新任务状态失败(${message})" fi } From 736da7dfa0922c41f575bdbfd6da7dc789e7f6ff Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 18:50:29 +0800 Subject: [PATCH 083/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 6 +++--- src/version.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 924ed3d2..35a37640 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,6 +1,6 @@ -## Version: v2.2.0-062 -## Date: 2021-06-07 -## Update Content: session管理增加批量操作\n增加go-cqhttp通知方式\n修复页面标题 +## Version: v2.2.0-063 +## Date: 2021-06-13 +## Update Content: \n1. 增加文件后缀配置 RepoFileExtensions\n2. 增加定时任务pageSize缓存\n3. 增加定时任务自动运行时状态展示 ## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新 diff --git a/src/version.ts b/src/version.ts index 246fd666..d2123029 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.2.0-062'; -export const changeLog = 'https://t.me/jiaolongwang/105'; +export const version = 'v2.2.0-063'; +export const changeLog = 'https://t.me/jiaolongwang/106'; From 51133e24ef286085163bd434e5afef2748623a4a Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 19:33:35 +0800 Subject: [PATCH 084/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8B=89=E5=8F=96?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=90=8E=E7=BC=80=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/shell/update.sh b/shell/update.sh index 70e0bddd..efcf7e32 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -357,8 +357,14 @@ gen_list_repo() { cd ${repo_path} local cmd="find ." + local index=0 for extension in $file_extensions; do - cmd="${cmd} -o -name \"*.${extension}\"" + if [[ $index -eq 0 ]]; then + cmd="${cmd} -name \"*.${extension}\"" + else + cmd="${cmd} -o -name \"*.${extension}\"" + fi + let index+=1 done files=$($cmd | sed 's/^..//') if [[ $path ]]; then From 031f1bc1ca6a1abbf51496e4dd994fc0591fcdb5 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 20:04:56 +0800 Subject: [PATCH 085/247] =?UTF-8?q?=E6=9A=82=E6=97=B6=E5=9B=9E=E9=80=80ql?= =?UTF-8?q?=20repo=E6=8B=89=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index efcf7e32..44ff8190 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -356,16 +356,16 @@ gen_list_repo() { cd ${repo_path} - local cmd="find ." - local index=0 - for extension in $file_extensions; do - if [[ $index -eq 0 ]]; then - cmd="${cmd} -name \"*.${extension}\"" - else - cmd="${cmd} -o -name \"*.${extension}\"" - fi - let index+=1 - done + local cmd="find . -name *.js" + # local index=0 + # for extension in $file_extensions; do + # if [[ $index -eq 0 ]]; then + # cmd="${cmd} -name \"*.${extension}\"" + # else + # cmd="${cmd} -o -name \"*.${extension}\"" + # fi + # let index+=1 + # done files=$($cmd | sed 's/^..//') if [[ $path ]]; then files=$(echo "$files" | egrep $path) From 3e481900e2fc8ec3b42b3aad06ba93cbab806459 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 20:27:06 +0800 Subject: [PATCH 086/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20repo=E5=91=BD?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 44ff8190..7bf53451 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -356,17 +356,17 @@ gen_list_repo() { cd ${repo_path} - local cmd="find . -name *.js" - # local index=0 - # for extension in $file_extensions; do - # if [[ $index -eq 0 ]]; then - # cmd="${cmd} -name \"*.${extension}\"" - # else - # cmd="${cmd} -o -name \"*.${extension}\"" - # fi - # let index+=1 - # done - files=$($cmd | sed 's/^..//') + local cmd="find ." + local index=0 + for extension in $file_extensions; do + if [[ $index -eq 0 ]]; then + cmd="${cmd} -name \"*.${extension}\"" + else + cmd="${cmd} -o -name \"*.${extension}\"" + fi + let index+=1 + done + files=$(eval $cmd | sed 's/^..//') if [[ $path ]]; then files=$(echo "$files" | egrep $path) fi From 8c7f1bc3d3c1e34b78105e8970aa50b47a28c99f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 13 Jun 2021 22:41:38 +0800 Subject: [PATCH 087/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20repo=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/update.sh b/shell/update.sh index 7bf53451..f8d8c5cb 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -374,7 +374,7 @@ gen_list_repo() { files=$(echo "$files" | egrep -v $blackword) fi if [[ $dependence ]]; then - $cmd | sed 's/^..//' | egrep $dependence | xargs -i cp {} $dir_scripts + eval $cmd | sed 's/^..//' | egrep $dependence | xargs -i cp {} $dir_scripts fi for file in ${files}; do filename=$(basename $file) From 4336f6f1759f95bd2d7d1df7051a13d26b796a6a Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 15 Jun 2021 23:15:58 +0800 Subject: [PATCH 088/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8DTempCk=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=8C=E4=BF=AE=E5=A4=8Dql=20raw=E6=8B=89=E5=8F=96?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/share.sh | 5 +++++ shell/task.sh | 7 +++++-- shell/update.sh | 9 +++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/shell/share.sh b/shell/share.sh index e4d9e0f2..28ca2c55 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -289,8 +289,13 @@ git_pull_scripts() { cd $dir_current } +init_env() { + TempBlockCookie="" +} + ## 导入配置文件,检测平台,创建软连接,识别命令,修复配置文件 detect_termux detect_macos define_cmd +init_env import_config $1 diff --git a/shell/task.sh b/shell/task.sh index 9ea31d87..0c181557 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -24,7 +24,10 @@ combine_sub() { ## 正常依次运行时,组合所有账号的Cookie与互助码 combine_all() { for ((i = 0; i < ${#env_name[*]}; i++)); do - export ${env_name[i]}=$(combine_sub ${var_name[i]}) + result=$(combine_sub ${var_name[i]}) + if [[ $result ]]; then + export ${env_name[i]}="$result" + fi done } @@ -53,7 +56,7 @@ random_delay() { local random_delay_max=$RandomDelay if [[ $random_delay_max ]] && [[ $random_delay_max -gt 0 ]]; then local current_min=$(date "+%-M") - if [[ $current_min -gt 2 && $current_min -lt 30 ]] || [[ $current_min -gt 31 && $current_min -lt 59 ]]; then + if [[ $current_min -ne 0 ]] && [[ $current_min -ne 30 ]]; then delay_second=$(($(gen_random_num $random_delay_max) + 1)) echo -e "\n命令未添加 \"now\",随机延迟 $delay_second 秒后再执行任务,如需立即终止,请按 CTRL+C...\n" sleep $delay_second diff --git a/shell/update.sh b/shell/update.sh index f8d8c5cb..bdc31cbc 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -89,7 +89,7 @@ del_cron() { local ids="" echo -e "开始尝试自动删除失效的定时任务...\n" for cron in $(cat $list_drop); do - local id=$(cat $list_crontab_user | grep -E "$cmd_task $cron$" | perl -pe "s|.*ID=(.*) $cmd_task $cron$|\1|" | xargs | sed 's/ /","/g') + local id=$(cat $list_crontab_user | grep -E "$cmd_task $cron" | perl -pe "s|.*ID=(.*) $cmd_task $cron|\1|" | xargs | sed 's/ /","/g' | head -1) if [[ $ids ]]; then ids="$ids,\"$id\"" else @@ -195,7 +195,7 @@ update_raw() { echo -e "下载 ${raw_file_name} 成功...\n" cd $dir_raw local filename="raw_${raw_file_name}" - local cron_id=$(cat $list_crontab_user | grep -E "$cmd_task $filename$" | perl -pe "s|.*ID=(.*) $cmd_task $filename$|\1|") + local cron_id=$(cat $list_crontab_user | grep -E "$cmd_task $filename" | perl -pe "s|.*ID=(.*) $cmd_task $filename\.*|\1|" | head -1) cp -f $raw_file_name $dir_scripts/${filename} cron_line=$( perl -ne "{ @@ -253,7 +253,8 @@ usage() { update_qinglong() { echo -e "--------------------------------------------------------------\n" [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) - reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" + url=https://github.com/whyour/qinglong.git + reset_romote_url ${dir_root} "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" git_pull_scripts $dir_root if [[ $exit_status -eq 0 ]]; then @@ -380,7 +381,7 @@ gen_list_repo() { filename=$(basename $file) cp -f $file $dir_scripts/${repo}_${filename} echo ${repo}_${filename} >>"$dir_list_tmp/${repo}_scripts.list" - cron_id=$(cat $list_crontab_user | grep -E "$cmd_task ${author}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|") + cron_id=$(cat $list_crontab_user | grep -E "$cmd_task ${author}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|" | head -1) if [[ $cron_id ]]; then result=$(update_cron_command_api "$cmd_task ${repo}_${filename}:$cron_id") fi From f6d7c3c35ee83473ed77dedea1db68e112f0a8e8 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 15 Jun 2021 23:17:24 +0800 Subject: [PATCH 089/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 6 +++--- src/version.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 35a37640..a9699cd1 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,6 +1,6 @@ -## Version: v2.2.0-063 -## Date: 2021-06-13 -## Update Content: \n1. 增加文件后缀配置 RepoFileExtensions\n2. 增加定时任务pageSize缓存\n3. 增加定时任务自动运行时状态展示 +## Version: v2.2.0-064 +## Date: 2021-06-15 +## Update Content: \n1. 修复TempBlockCookie参数问题\n2. 修复ql raw拉取脚本重复 ## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新 diff --git a/src/version.ts b/src/version.ts index d2123029..76139d2d 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.2.0-063'; -export const changeLog = 'https://t.me/jiaolongwang/106'; +export const version = 'v2.2.0-064'; +export const changeLog = 'https://t.me/jiaolongwang/107'; From 63cc3e59b436497b5cbcebb5cc395adad9571d49 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 15 Jun 2021 23:33:41 +0800 Subject: [PATCH 090/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95entrypoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 2 +- docker/docker-entrypoint.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 599379c2..3437cb75 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,7 +1,7 @@ FROM node:lts-alpine LABEL maintainer="whyour" ARG QL_URL=https://github.com/whyour/qinglong.git -ARG QL_BRANCH=master +ARG QL_BRANCH=develop ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ LANG=zh_CN.UTF-8 \ SHELL=/bin/bash \ diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index f448e0cb..99631094 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -46,6 +46,6 @@ echo -e "容器启动成功..." echo -e "\n请先访问5700端口,登录成功面板之后再执行添加定时任务..." echo -e "############################################################\n" -crond -f +crond -f >/dev/null exec "$@" From 896a09d701b50be0221207792dcf6aa60bf78dda Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 21:06:47 +0800 Subject: [PATCH 091/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E6=A0=B7=E5=BC=8F=EF=BC=8Cfix=20#349?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 2 +- shell/update.sh | 16 +++++++++------- src/layouts/index.tsx | 4 +++- src/pages/config/index.tsx | 1 - 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 99631094..467e5fd2 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -10,7 +10,7 @@ cp -fv $dir_root/docker/front.conf /etc/nginx/conf.d/front.conf echo echo -e "======================2. 更新源代码========================\n" -ql update +ql update "no-restart" echo echo -e "======================3. 启动nginx========================\n" diff --git a/shell/update.sh b/shell/update.sh index bdc31cbc..2aeaae48 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -251,10 +251,10 @@ usage() { ## 更新qinglong update_qinglong() { + local no_restart="$1" echo -e "--------------------------------------------------------------\n" [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) - url=https://github.com/whyour/qinglong.git - reset_romote_url ${dir_root} "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" + reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" git_pull_scripts $dir_root if [[ $exit_status -eq 0 ]]; then @@ -288,10 +288,12 @@ update_qinglong() { cd $dir_root rm -rf $dir_root/build && rm -rf $dir_root/dist cp -rf $ql_static_repo/* $dir_root - echo -e "重启面板中..." - nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf - sleep 1 - reload_pm2 + if [[ $no_restart != "no-restart" ]]; then + echo -e "重启面板中..." + nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf + sleep 1 + reload_pm2 + fi else echo -e "\n更新$dir_root失败,请检查原因...\n" fi @@ -401,7 +403,7 @@ main() { log_path="$dir_log/update/${log_time}_$p1.log" case $p1 in update) - update_qinglong | tee $log_path + update_qinglong "$2" | tee $log_path ;; extra) run_extra_shell | tee -a $log_path diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index d7008868..85911186 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -68,7 +68,9 @@ export default function (props: any) { <> 控制面板 - + {version} diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 5118c6bd..a0842325 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -71,7 +71,6 @@ const Config = () => { value={value} options={{ lineNumbers: true, - lineWrapping: true, styleActiveLine: true, matchBrackets: true, mode: 'shell', From e217ca6d8faddc2459f3ee3e679202bd9f5758ab Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 21:09:43 +0800 Subject: [PATCH 092/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9docker=E5=88=86?= =?UTF-8?q?=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 3437cb75..599379c2 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,7 +1,7 @@ FROM node:lts-alpine LABEL maintainer="whyour" ARG QL_URL=https://github.com/whyour/qinglong.git -ARG QL_BRANCH=develop +ARG QL_BRANCH=master ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \ LANG=zh_CN.UTF-8 \ SHELL=/bin/bash \ From 3232f1efa49e1eb4db7ef11a0c1d1b049425d844 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 21:27:21 +0800 Subject: [PATCH 093/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 12 ++++-------- shell/update.sh | 13 +++++-------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 467e5fd2..fc3af305 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -9,15 +9,11 @@ fix_config cp -fv $dir_root/docker/front.conf /etc/nginx/conf.d/front.conf echo -echo -e "======================2. 更新源代码========================\n" -ql update "no-restart" -echo - -echo -e "======================3. 启动nginx========================\n" +echo -e "======================2. 启动nginx========================\n" nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf echo -e "nginx启动成功...\n" -echo -e "======================4. 启动控制面板========================\n" +echo -e "======================3. 启动控制面板========================\n" cd $dir_root if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel @@ -26,7 +22,7 @@ else fi echo -e "控制面板启动成功...\n" -echo -e "======================5. 启动定时任务========================\n" +echo -e "======================4. 启动定时任务========================\n" cd $dir_root if [[ $(pm2 info schedule 2>/dev/null) ]]; then pm2 reload schedule @@ -36,7 +32,7 @@ fi echo -e "定时任务启动成功...\n" if [[ $AutoStartBot == true ]]; then - echo -e "======================6. 启动bot========================\n" + echo -e "======================5. 启动bot========================\n" cd $dir_root ql bot fi diff --git a/shell/update.sh b/shell/update.sh index 2aeaae48..28ebe2d8 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -251,7 +251,6 @@ usage() { ## 更新qinglong update_qinglong() { - local no_restart="$1" echo -e "--------------------------------------------------------------\n" [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" @@ -288,12 +287,10 @@ update_qinglong() { cd $dir_root rm -rf $dir_root/build && rm -rf $dir_root/dist cp -rf $ql_static_repo/* $dir_root - if [[ $no_restart != "no-restart" ]]; then - echo -e "重启面板中..." - nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf - sleep 1 - reload_pm2 - fi + echo -e "重启面板中..." + nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf + sleep 1 + reload_pm2 else echo -e "\n更新$dir_root失败,请检查原因...\n" fi @@ -403,7 +400,7 @@ main() { log_path="$dir_log/update/${log_time}_$p1.log" case $p1 in update) - update_qinglong "$2" | tee $log_path + update_qinglong | tee $log_path ;; extra) run_extra_shell | tee -a $log_path From 5b9c38385ac640720781066a9c8b23dd97fe2168 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 23:02:07 +0800 Subject: [PATCH 094/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 11 ++++++----- shell/update.sh | 8 +++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index fc3af305..66ba153b 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -14,8 +14,9 @@ nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf echo -e "nginx启动成功...\n" echo -e "======================3. 启动控制面板========================\n" -cd $dir_root -if [[ $(pm2 info panel 2>/dev/null) ]]; then + +app_pid=$(ps -ef | grep "app.js" | grep -v grep) +if [ "$app_pid" != "" ]; then pm2 reload panel else pm2 start $dir_root/build/app.js -n panel @@ -23,8 +24,9 @@ fi echo -e "控制面板启动成功...\n" echo -e "======================4. 启动定时任务========================\n" -cd $dir_root -if [[ $(pm2 info schedule 2>/dev/null) ]]; then + +schedule_pid=$(ps -ef | grep "schedule.js" | grep -v grep) +if [ "$schedule_pid" != "" ]; then pm2 reload schedule else pm2 start $dir_root/build/schedule.js -n schedule @@ -33,7 +35,6 @@ echo -e "定时任务启动成功...\n" if [[ $AutoStartBot == true ]]; then echo -e "======================5. 启动bot========================\n" - cd $dir_root ql bot fi diff --git a/shell/update.sh b/shell/update.sh index 28ebe2d8..99cbd160 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -298,13 +298,15 @@ update_qinglong() { } reload_pm2() { - if [[ $(pm2 info panel 2>/dev/null) ]]; then + local app_pid=$(ps -ef | grep "app.js" | grep -v grep) + if [ "$app_pid" != "" ]; then pm2 reload panel >/dev/null 2>&1 else pm2 start $dir_root/build/app.js -n panel >/dev/null 2>&1 fi - if [[ $(pm2 info schedule 2>/dev/null) ]]; then + local schedule_pid=$(ps -ef | grep "schedule.js" | grep -v grep) + if [ "$schedule_pid" != "" ]; then pm2 reload schedule >/dev/null 2>&1 else pm2 start $dir_root/build/schedule.js -n schedule >/dev/null 2>&1 @@ -355,7 +357,7 @@ gen_list_repo() { rm -f $dir_list_tmp/${repo}*.list >/dev/null 2>&1 cd ${repo_path} - + local cmd="find ." local index=0 for extension in $file_extensions; do From b3fc5bd3660ba04a7161a6affd9473ec34b465fe Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 23:19:05 +0800 Subject: [PATCH 095/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 21 +++++++++++---------- shell/update.sh | 13 ++++++++----- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 66ba153b..10fc670e 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -9,24 +9,25 @@ fix_config cp -fv $dir_root/docker/front.conf /etc/nginx/conf.d/front.conf echo -echo -e "======================2. 启动nginx========================\n" +echo -e "======================2. 更新源代码========================\n" +ql update "no-restart" +echo + +echo -e "======================3. 启动nginx========================\n" nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf echo -e "nginx启动成功...\n" -echo -e "======================3. 启动控制面板========================\n" - -app_pid=$(ps -ef | grep "app.js" | grep -v grep) -if [ "$app_pid" != "" ]; then +echo -e "======================4. 启动控制面板========================\n" +if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel else pm2 start $dir_root/build/app.js -n panel fi echo -e "控制面板启动成功...\n" -echo -e "======================4. 启动定时任务========================\n" - -schedule_pid=$(ps -ef | grep "schedule.js" | grep -v grep) -if [ "$schedule_pid" != "" ]; then +echo -e "======================5. 启动定时任务========================\n" +cd $dir_root +if [[ $(pm2 info schedule 2>/dev/null) ]]; then pm2 reload schedule else pm2 start $dir_root/build/schedule.js -n schedule @@ -34,7 +35,7 @@ fi echo -e "定时任务启动成功...\n" if [[ $AutoStartBot == true ]]; then - echo -e "======================5. 启动bot========================\n" + echo -e "======================6. 启动bot========================\n" ql bot fi diff --git a/shell/update.sh b/shell/update.sh index 99cbd160..a8f16a2f 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -251,6 +251,7 @@ usage() { ## 更新qinglong update_qinglong() { + local no_restart="$1" echo -e "--------------------------------------------------------------\n" [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" @@ -287,10 +288,12 @@ update_qinglong() { cd $dir_root rm -rf $dir_root/build && rm -rf $dir_root/dist cp -rf $ql_static_repo/* $dir_root - echo -e "重启面板中..." - nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf - sleep 1 - reload_pm2 + if [[ $no_restart != "no-restart" ]]; then + echo -e "重启面板中..." + nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf + sleep 1 + reload_pm2 + fi else echo -e "\n更新$dir_root失败,请检查原因...\n" fi @@ -402,7 +405,7 @@ main() { log_path="$dir_log/update/${log_time}_$p1.log" case $p1 in update) - update_qinglong | tee $log_path + update_qinglong "$2" | tee $log_path ;; extra) run_extra_shell | tee -a $log_path From 849883f8d047ddda0d8007a5a71e7eaff1366f5b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 23:20:04 +0800 Subject: [PATCH 096/247] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 10fc670e..05e442de 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -26,7 +26,6 @@ fi echo -e "控制面板启动成功...\n" echo -e "======================5. 启动定时任务========================\n" -cd $dir_root if [[ $(pm2 info schedule 2>/dev/null) ]]; then pm2 reload schedule else From bc0044d1191c9f47b9d553e281052473e4b2f398 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 23:25:43 +0800 Subject: [PATCH 097/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20pm2=20=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index a8f16a2f..dbdbcb7a 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -301,15 +301,13 @@ update_qinglong() { } reload_pm2() { - local app_pid=$(ps -ef | grep "app.js" | grep -v grep) - if [ "$app_pid" != "" ]; then + if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel >/dev/null 2>&1 else pm2 start $dir_root/build/app.js -n panel >/dev/null 2>&1 fi - local schedule_pid=$(ps -ef | grep "schedule.js" | grep -v grep) - if [ "$schedule_pid" != "" ]; then + if [[ $(pm2 info schedule 2>/dev/null) ]]; then pm2 reload schedule >/dev/null 2>&1 else pm2 start $dir_root/build/schedule.js -n schedule >/dev/null 2>&1 From f345f362e4a1328d7495e8a725d16a20f7b7d737 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 23:54:15 +0800 Subject: [PATCH 098/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dentrypoint=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 1 + shell/update.sh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 05e442de..c7c73e49 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -11,6 +11,7 @@ echo echo -e "======================2. 更新源代码========================\n" ql update "no-restart" +pm2 l >/dev/null 2>&1 echo echo -e "======================3. 启动nginx========================\n" diff --git a/shell/update.sh b/shell/update.sh index dbdbcb7a..89ea0c6a 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -301,6 +301,8 @@ update_qinglong() { } reload_pm2() { + pm2 l >/dev/null 2>&1 + if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel >/dev/null 2>&1 else From 4289a238950c5d50d90f5d0c19d27fecee1a5d3f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 16 Jun 2021 23:58:19 +0800 Subject: [PATCH 099/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 76139d2d..e9b3405b 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.2.0-064'; -export const changeLog = 'https://t.me/jiaolongwang/107'; +export const version = 'v2.2.0-065'; +export const changeLog = 'https://t.me/jiaolongwang/108'; From 4f5540f75678c22a85ffdad70211caaa9e3165fd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 17 Jun 2021 20:56:50 +0800 Subject: [PATCH 100/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E6=A0=B7=E5=BC=8F=E5=92=8C=E6=9F=A5=E7=9C=8Bcron?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E5=88=97=E8=A1=A8=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.tsx | 12 +++++++++++- src/pages/crontab/index.tsx | 6 ++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 85911186..116cea28 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -61,6 +61,11 @@ export default function (props: any) { if (props.location.pathname === '/login') { return props.children; } + + const isFirefox = navigator.userAgent.includes('Firefox'); + const isSafari = + navigator.userAgent.includes('Safari') && + !navigator.userAgent.includes('Chrome'); return ( {version} diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 18da79dc..90203d18 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -431,7 +431,7 @@ const Crontab = () => { if (index === -1) { result.push(cron); } else { - result.splice(index + pageSize * (currentPage - 1), 1, { + result.splice(index, 1, { ...cron, }); } @@ -442,9 +442,11 @@ const Crontab = () => { request .get(`${config.apiPrefix}crons/${cron._id}`) .then((data: any) => { + console.log(value); const index = value.findIndex((x) => x._id === cron._id); + console.log(index); const result = [...value]; - result.splice(index + pageSize * (currentPage - 1), 1, { + result.splice(index, 1, { ...cron, ...data.data, }); From 7ed1abde3662d40dc661996befd3c1d3056af8e9 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 17 Jun 2021 21:04:30 +0800 Subject: [PATCH 101/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 6 +++--- src/version.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index a9699cd1..5766d3c9 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -1,6 +1,6 @@ -## Version: v2.2.0-064 -## Date: 2021-06-15 -## Update Content: \n1. 修复TempBlockCookie参数问题\n2. 修复ql raw拉取脚本重复 +## Version: v2.2.0-066 +## Date: 2021-06-17 +## Update Content: \n1. 修复版本号样式\n2. 修复查看日志或者编辑任务后列表异常 ## 上面版本号中,如果第2位数字有变化,那么代表增加了新的参数,如果只有第3位数字有变化,仅代表更新了注释,没有增加新的参数,可更新可不更新 diff --git a/src/version.ts b/src/version.ts index e9b3405b..2300b3d2 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.2.0-065'; -export const changeLog = 'https://t.me/jiaolongwang/108'; +export const version = 'v2.2.0-066'; +export const changeLog = 'https://t.me/jiaolongwang/109'; From 0fade7a5a931e0b857008b85ecb52ec53e326a7c Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 20 Jun 2021 17:47:12 +0800 Subject: [PATCH 102/247] =?UTF-8?q?=E9=87=8D=E6=9E=84=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E7=AE=A1=E7=90=86=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- back/api/config.ts | 52 +++-- back/api/{cookie.ts => env.ts} | 99 ++++---- back/api/index.ts | 6 +- back/api/script.ts | 48 ++++ back/config/index.ts | 18 +- back/data/{cookie.ts => env.ts} | 17 +- back/loaders/initData.ts | 6 +- back/services/cookie.ts | 333 --------------------------- back/services/env.ts | 227 ++++++++++++++++++ package.json | 5 +- sample/config.sample.sh | 100 -------- sample/package.json | 1 - shell/code.sh | 151 ------------ shell/share.sh | 19 +- shell/task.sh | 46 +--- src/app.tsx | 4 +- src/layouts/defaultProps.tsx | 12 +- src/layouts/index.less | 11 +- src/pages/config/index.tsx | 43 +++- src/pages/diff/index.tsx | 4 +- src/pages/diy/index.less | 0 src/pages/diy/index.tsx | 88 ------- src/pages/env/editNameModal.tsx | 77 +++++++ src/pages/{cookie => env}/index.less | 0 src/pages/{cookie => env}/index.tsx | 182 +++++++-------- src/pages/{cookie => env}/modal.tsx | 61 +++-- src/pages/script/index.module.less | 37 +++ src/pages/script/index.tsx | 170 ++++++++++++++ src/utils/http.ts | 4 +- 30 files changed, 848 insertions(+), 976 deletions(-) rename back/api/{cookie.ts => env.ts} (69%) create mode 100644 back/api/script.ts rename back/data/{cookie.ts => env.ts} (53%) delete mode 100644 back/services/cookie.ts create mode 100644 back/services/env.ts delete mode 100755 shell/code.sh delete mode 100644 src/pages/diy/index.less delete mode 100644 src/pages/diy/index.tsx create mode 100644 src/pages/env/editNameModal.tsx rename src/pages/{cookie => env}/index.less (100%) rename src/pages/{cookie => env}/index.tsx (74%) rename src/pages/{cookie => env}/modal.tsx (54%) create mode 100644 src/pages/script/index.module.less create mode 100644 src/pages/script/index.tsx diff --git a/.gitignore b/.gitignore index 5cb8f362..dba9a63f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,5 @@ /config /log /db -/manual_log \ No newline at end of file +/manual_log +/scripts \ No newline at end of file diff --git a/back/api/config.ts b/back/api/config.ts index c52bc637..9da30007 100644 --- a/back/api/config.ts +++ b/back/api/config.ts @@ -5,33 +5,40 @@ import { Logger } from 'winston'; import config from '../config'; import * as fs from 'fs'; import { celebrate, Joi } from 'celebrate'; -import { execSync } from 'child_process'; const route = Router(); export default (app: Router) => { app.use('/', route); + route.get( - '/config/:key', + '/configs/files', async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - let content = '未找到文件'; - switch (req.params.key) { - case 'config': - content = getFileContentByName(config.confFile); - break; - case 'sample': - content = getFileContentByName(config.sampleFile); - break; - case 'crontab': - content = getFileContentByName(config.crontabFile); - break; - case 'extra': - content = getFileContentByName(config.extraFile); - break; - default: - break; - } + const fileList = fs.readdirSync(config.configPath, 'utf-8'); + res.send({ + code: 200, + data: fileList + .filter((x) => !config.blackFileList.includes(x)) + .map((x) => { + return { title: x, value: x }; + }), + }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.get( + '/configs/:file', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const content = getFileContentByName( + `${config.configPath}${req.params.file}`, + ); res.send({ code: 200, data: content }); } catch (e) { logger.error('🔥 error: %o', e); @@ -41,7 +48,7 @@ export default (app: Router) => { ); route.post( - '/save', + '/configs/save', celebrate({ body: Joi.object({ name: Joi.string().required(), @@ -52,11 +59,8 @@ export default (app: Router) => { const logger: Logger = Container.get('logger'); try { const { name, content } = req.body; - const path = (config.fileMap as any)[name]; + const path = `${config.configPath}${name}`; fs.writeFileSync(path, content); - if (name === 'crontab.list') { - execSync(`crontab ${path}`); - } res.send({ code: 200, msg: '保存成功' }); } catch (e) { logger.error('🔥 error: %o', e); diff --git a/back/api/cookie.ts b/back/api/env.ts similarity index 69% rename from back/api/cookie.ts rename to back/api/env.ts index bf75c20f..122a3f7c 100644 --- a/back/api/cookie.ts +++ b/back/api/env.ts @@ -1,6 +1,6 @@ import { Router, Request, Response, NextFunction } from 'express'; import { Container } from 'typedi'; -import CookieService from '../services/cookie'; +import EnvService from '../services/env'; import { Logger } from 'winston'; import { celebrate, Joi } from 'celebrate'; const route = Router(); @@ -8,12 +8,12 @@ const route = Router(); export default (app: Router) => { app.use('/', route); route.get( - '/cookies', + '/envs', async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.cookies('', { position: -1 }, true); + const envService = Container.get(EnvService); + const data = await envService.envs('', { position: -1 }); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -23,15 +23,19 @@ export default (app: Router) => { ); route.post( - '/cookies', + '/envs', celebrate({ - body: Joi.array().items(Joi.string().required()).min(1), + body: Joi.object({ + value: Joi.string().required(), + name: Joi.string().required(), + remarks: Joi.string().optional(), + }), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.create(req.body); + const envService = Container.get(EnvService); + const data = await envService.create(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -41,18 +45,20 @@ export default (app: Router) => { ); route.put( - '/cookies', + '/envs', celebrate({ body: Joi.object({ value: Joi.string().required(), + name: Joi.string().required(), + remarks: Joi.string().optional(), _id: Joi.string().required(), }), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.update(req.body); + const envService = Container.get(EnvService); + const data = await envService.update(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -62,15 +68,15 @@ export default (app: Router) => { ); route.delete( - '/cookies', + '/envs', celebrate({ body: Joi.array().items(Joi.string().required()), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.remove(req.body); + const envService = Container.get(EnvService); + const data = await envService.remove(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -80,7 +86,7 @@ export default (app: Router) => { ); route.put( - '/cookies/:id/move', + '/envs/:id/move', celebrate({ params: Joi.object({ id: Joi.string().required(), @@ -93,28 +99,8 @@ export default (app: Router) => { async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.move(req.params.id, req.body); - return res.send({ code: 200, data }); - } catch (e) { - logger.error('🔥 error: %o', e); - return next(e); - } - }, - ); - - route.get( - '/cookies/:id/refresh', - celebrate({ - params: Joi.object({ - id: Joi.string().required(), - }), - }), - async (req: Request, res: Response, next: NextFunction) => { - const logger: Logger = Container.get('logger'); - try { - const cookieService = Container.get(CookieService); - const data = await cookieService.refreshCookie(req.params.id); + const envService = Container.get(EnvService); + const data = await envService.move(req.params.id, req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -124,15 +110,15 @@ export default (app: Router) => { ); route.put( - '/cookies/disable', + '/envs/disable', celebrate({ body: Joi.array().items(Joi.string().required()), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.disabled(req.body); + const envService = Container.get(EnvService); + const data = await envService.disabled(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -142,15 +128,36 @@ export default (app: Router) => { ); route.put( - '/cookies/enable', + '/envs/enable', celebrate({ body: Joi.array().items(Joi.string().required()), }), async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.enabled(req.body); + const envService = Container.get(EnvService); + const data = await envService.enabled(req.body); + return res.send({ code: 200, data }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.put( + '/envs/name', + celebrate({ + body: Joi.object({ + ids: Joi.array().items(Joi.string().required()), + name: Joi.string().required(), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const envService = Container.get(EnvService); + const data = await envService.updateNames(req.body); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); @@ -160,7 +167,7 @@ export default (app: Router) => { ); route.get( - '/cookies/:id', + '/envs/:id', celebrate({ params: Joi.object({ id: Joi.string().required(), @@ -169,8 +176,8 @@ export default (app: Router) => { async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const cookieService = Container.get(CookieService); - const data = await cookieService.get(req.params.id); + const envService = Container.get(EnvService); + const data = await envService.get(req.params.id); return res.send({ code: 200, data }); } catch (e) { logger.error('🔥 error: %o', e); diff --git a/back/api/index.ts b/back/api/index.ts index 38ba05e3..b200f60f 100644 --- a/back/api/index.ts +++ b/back/api/index.ts @@ -1,17 +1,19 @@ import { Router } from 'express'; import auth from './auth'; -import cookie from './cookie'; +import env from './env'; import config from './config'; import log from './log'; import cron from './cron'; +import script from './script'; export default () => { const app = Router(); auth(app); - cookie(app); + env(app); config(app); log(app); cron(app); + script(app); return app; }; diff --git a/back/api/script.ts b/back/api/script.ts new file mode 100644 index 00000000..c66b11f2 --- /dev/null +++ b/back/api/script.ts @@ -0,0 +1,48 @@ +import { getFileContentByName, getLastModifyFilePath } from '../config/util'; +import { Router, Request, Response, NextFunction } from 'express'; +import { Container } from 'typedi'; +import { Logger } from 'winston'; +import config from '../config'; +import * as fs from 'fs'; +import { celebrate, Joi } from 'celebrate'; +const route = Router(); + +export default (app: Router) => { + app.use('/', route); + + route.get( + '/scripts/files', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + const fileList = fs.readdirSync(config.scriptPath, 'utf-8'); + res.send({ + code: 200, + data: fileList.map((x) => { + return { title: x, value: x, key: x }; + }), + }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); + + route.get( + '/scripts/:file', + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + console.log(req.params.file); + const content = getFileContentByName( + `${config.scriptPath}${req.params.file}`, + ); + res.send({ code: 200, data: content }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); +}; diff --git a/back/config/index.ts b/back/config/index.ts index 6d129ea4..d7eb56ee 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -5,13 +5,15 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development'; const envFound = dotenv.config(); const rootPath = path.resolve(__dirname, '../../'); -const cookieFile = path.join(rootPath, 'config/cookie.sh'); +const envFile = path.join(rootPath, 'config/env.sh'); const confFile = path.join(rootPath, 'config/config.sh'); const sampleFile = path.join(rootPath, 'sample/config.sample.sh'); const crontabFile = path.join(rootPath, 'config/crontab.list'); const confBakDir = path.join(rootPath, 'config/bak/'); const authConfigFile = path.join(rootPath, 'config/auth.json'); const extraFile = path.join(rootPath, 'config/extra.sh'); +const configPath = path.join(rootPath, 'config/'); +const scriptPath = path.join(rootPath, 'scripts/'); const logPath = path.join(rootPath, 'log/'); const authError = '错误的用户名密码,请重试'; const loginFaild = '请先登录!'; @@ -19,7 +21,7 @@ const configString = 'config sample crontab shareCode diy'; const dbPath = path.join(rootPath, 'db/'); const manualLogPath = path.join(rootPath, 'manual_log/'); const cronDbFile = path.join(rootPath, 'db/crontab.db'); -const cookieDbFile = path.join(rootPath, 'db/cookie.db'); +const envDbFile = path.join(rootPath, 'db/env.db'); const configFound = dotenv.config({ path: confFile }); if (envFound.error) { @@ -50,14 +52,12 @@ export default { crontabFile, sampleFile, confFile, - cookieFile, - fileMap: { - 'config.sh': confFile, - 'crontab.list': crontabFile, - 'extra.sh': extraFile, - }, + envFile, dbPath, cronDbFile, - cookieDbFile, + envDbFile, manualLogPath, + configPath, + scriptPath, + blackFileList: ['auth.json', 'config.sh.sample', 'cookie.sh', 'crontab.list'], }; diff --git a/back/data/cookie.ts b/back/data/env.ts similarity index 53% rename from back/data/cookie.ts rename to back/data/env.ts index 62cc3747..bc069ed2 100644 --- a/back/data/cookie.ts +++ b/back/data/env.ts @@ -1,22 +1,25 @@ -export class Cookie { +export class Env { value?: string; timestamp?: string; created?: number; _id?: string; - status?: CookieStatus; + status?: EnvStatus; position?: number; + name?: number; + remarks?: number; - constructor(options: Cookie) { + constructor(options: Env) { this.value = options.value; this._id = options._id; this.created = options.created || new Date().valueOf(); - this.status = options.status || CookieStatus.noacquired; + this.status = options.status || EnvStatus.noacquired; this.timestamp = new Date().toString(); - this.position = options.position; + this.name = options.name; + this.remarks = options.remarks; } } -export enum CookieStatus { +export enum EnvStatus { 'noacquired', 'normal', 'disabled', @@ -24,4 +27,4 @@ export enum CookieStatus { 'abnormal', } -export const initCookiePosition = 9999999999; +export const initEnvPosition = 9999999999; diff --git a/back/loaders/initData.ts b/back/loaders/initData.ts index f7aa9093..88162747 100644 --- a/back/loaders/initData.ts +++ b/back/loaders/initData.ts @@ -2,7 +2,7 @@ import { exec } from 'child_process'; import { Container } from 'typedi'; import { Crontab, CrontabStatus } from '../data/cron'; import CronService from '../services/cron'; -import CookieService from '../services/cookie'; +import EnvService from '../services/env'; const initData = [ { @@ -30,7 +30,7 @@ const initData = [ export default async () => { const cronService = Container.get(CronService); - const cookieService = Container.get(CookieService); + const envService = Container.get(EnvService); const cronDb = cronService.getDb(); cronDb.count({}, async (err, count) => { @@ -97,7 +97,7 @@ export default async () => { // 初始化保存一次ck和定时任务数据 await cronService.autosave_crontab(); - await cookieService.set_cookies(); + await envService.set_envs(); }; function randomSchedule(from: number, to: number) { diff --git a/back/services/cookie.ts b/back/services/cookie.ts deleted file mode 100644 index 016b4052..00000000 --- a/back/services/cookie.ts +++ /dev/null @@ -1,333 +0,0 @@ -import { Service, Inject } from 'typedi'; -import winston from 'winston'; -import fetch from 'node-fetch'; -import { getFileContentByName } from '../config/util'; -import config from '../config'; -import * as fs from 'fs'; -import got from 'got'; -import DataStore from 'nedb'; -import { Cookie, CookieStatus, initCookiePosition } from '../data/cookie'; - -@Service() -export default class CookieService { - private cronDb = new DataStore({ filename: config.cookieDbFile }); - constructor(@Inject('logger') private logger: winston.Logger) { - this.cronDb.loadDatabase((err) => { - if (err) throw err; - }); - } - - public async getCookies() { - const content = getFileContentByName(config.cookieFile); - return this.formatCookie(content.split('\n').filter((x) => !!x)); - } - - public async addCookie(cookies: string[]) { - let content = getFileContentByName(config.cookieFile); - const originCookies = content.split('\n').filter((x) => !!x); - const result = originCookies.concat(cookies); - fs.writeFileSync(config.cookieFile, result.join('\n')); - return ''; - } - - public async updateCookie({ cookie, oldCookie }) { - let content = getFileContentByName(config.cookieFile); - const cookies = content.split('\n'); - const index = cookies.findIndex((x) => x === oldCookie); - if (index !== -1) { - cookies[index] = cookie; - fs.writeFileSync(config.cookieFile, cookies.join('\n')); - return ''; - } else { - return '未找到要原有Cookie'; - } - } - - public async deleteCookie(cookie: string) { - let content = getFileContentByName(config.cookieFile); - const cookies = content.split('\n'); - const index = cookies.findIndex((x) => x === cookie); - if (index !== -1) { - cookies.splice(index, 1); - fs.writeFileSync(config.cookieFile, cookies.join('\n')); - return ''; - } else { - return '未找到要删除的Cookie'; - } - } - - private async formatCookie(data: any[]) { - const result = []; - for (const x of data) { - const { nickname, status } = await this.getJdInfo(x); - if (/pt_pin=(.+?);/.test(x)) { - result.push({ - pin: x.match(/pt_pin=(.+?);/)[1], - cookie: x, - status, - nickname: nickname, - }); - } else { - result.push({ - pin: 'pin未匹配到', - cookie: x, - status, - nickname: nickname, - }); - } - } - return result; - } - - public async refreshCookie(_id: string) { - const current = await this.get(_id); - const { status, nickname } = await this.getJdInfo(current.value); - return { - ...current, - status, - nickname, - }; - } - - private getJdInfo(cookie: string) { - return fetch( - `https://me-api.jd.com/user_new/info/GetJDUserInfoUnion?orgFlag=JD_PinGou_New&callSource=mainorder&channel=4&isHomewhite=0&sceneval=2&_=${Date.now()}&sceneval=2&g_login_type=1&g_ty=ls`, - { - method: 'get', - headers: { - Accept: '*/*', - 'Accept-Encoding': 'gzip, deflate, br', - 'Accept-Language': 'zh-cn', - Connection: 'keep-alive', - Cookie: cookie, - Referer: 'https://home.m.jd.com/myJd/newhome.action', - 'User-Agent': - 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1', - Host: 'me-api.jd.com', - }, - }, - ) - .then((x) => x.json()) - .then((x) => { - if (x.retcode === '0' && x.data && x.data.userInfo) { - return { - nickname: x.data.userInfo.baseInfo.nickname, - status: CookieStatus.normal, - }; - } else if (x.retcode === 13) { - return { status: CookieStatus.invalid, nickname: '-' }; - } - return { status: CookieStatus.abnormal, nickname: '-' }; - }); - } - - private async formatCookies(cookies: Cookie[]) { - const result = []; - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i]; - if (cookie.status !== CookieStatus.disabled) { - const { status, nickname } = await this.getJdInfo(cookie.value); - result.push({ ...cookie, status, nickname }); - } else { - result.push({ ...cookie, nickname: '-' }); - } - } - return result; - } - - public async create(payload: string[]): Promise { - const cookies = await this.cookies(); - let position = initCookiePosition; - if (cookies && cookies.length > 0) { - position = cookies[cookies.length - 1].position; - } - const tabs = payload.map((x) => { - const cookie = new Cookie({ value: x, position }); - position = position / 2; - cookie.position = position; - return cookie; - }); - const docs = await this.insert(tabs); - await this.set_cookies(); - return await this.formatCookies(docs); - } - - public async insert(payload: Cookie[]): Promise { - return new Promise((resolve) => { - this.cronDb.insert(payload, (err, docs) => { - if (err) { - this.logger.error(err); - } else { - resolve(docs); - } - }); - }); - } - - public async update(payload: Cookie): Promise { - const { _id, ...other } = payload; - const doc = await this.get(_id); - const tab = new Cookie({ ...doc, ...other }); - const newDoc = await this.updateDb(tab); - await this.set_cookies(); - const [newCookie] = await this.formatCookies([newDoc]); - return newCookie; - } - - private async updateDb(payload: Cookie): Promise { - return new Promise((resolve) => { - this.cronDb.update( - { _id: payload._id }, - payload, - { returnUpdatedDocs: true }, - (err, num, doc) => { - if (err) { - this.logger.error(err); - } else { - resolve(doc as Cookie); - } - }, - ); - }); - } - - public async remove(ids: string[]) { - return new Promise((resolve: any) => { - this.cronDb.remove( - { _id: { $in: ids } }, - { multi: true }, - async (err) => { - await this.set_cookies(); - resolve(); - }, - ); - }); - } - - public async move( - _id: string, - { - fromIndex, - toIndex, - }: { - fromIndex: number; - toIndex: number; - }, - ) { - let targetPosition: number; - const isUpward = fromIndex > toIndex; - const cookies = await this.cookies(); - if (toIndex === 0 || toIndex === cookies.length - 1) { - targetPosition = isUpward - ? cookies[0].position * 2 - : cookies[toIndex].position / 2; - } else { - targetPosition = isUpward - ? (cookies[toIndex].position + cookies[toIndex - 1].position) / 2 - : (cookies[toIndex].position + cookies[toIndex + 1].position) / 2; - } - this.update({ - _id, - position: targetPosition, - }); - await this.set_cookies(); - } - - public async cookies( - searchText?: string, - sort: any = { position: -1 }, - needDetail: boolean = false, - ): Promise { - let query = {}; - if (searchText) { - const reg = new RegExp(searchText); - query = { - $or: [ - { - name: reg, - }, - { - command: reg, - }, - ], - }; - } - const newDocs = await this.find(query, sort); - if (needDetail) { - return await this.formatCookies(newDocs); - } else { - return newDocs; - } - } - - private async find(query: any, sort: any): Promise { - return new Promise((resolve) => { - this.cronDb - .find(query) - .sort({ ...sort }) - .exec((err, docs) => { - resolve(docs); - }); - }); - } - - public async get(_id: string): Promise { - return new Promise((resolve) => { - this.cronDb.find({ _id }).exec((err, docs) => { - resolve(docs[0]); - }); - }); - } - - public async getBySort(sort: any): Promise { - return new Promise((resolve) => { - this.cronDb - .find({}) - .sort({ ...sort }) - .limit(1) - .exec((err, docs) => { - resolve(docs[0]); - }); - }); - } - - public async disabled(ids: string[]) { - return new Promise((resolve: any) => { - this.cronDb.update( - { _id: { $in: ids } }, - { $set: { status: CookieStatus.disabled } }, - { multi: true }, - async (err) => { - await this.set_cookies(); - resolve(); - }, - ); - }); - } - - public async enabled(ids: string[]) { - return new Promise((resolve: any) => { - this.cronDb.update( - { _id: { $in: ids } }, - { $set: { status: CookieStatus.noacquired } }, - { multi: true }, - async (err, num) => { - await this.set_cookies(); - resolve(); - }, - ); - }); - } - - public async set_cookies() { - const cookies = await this.cookies(); - let cookie_string = ''; - cookies.forEach((tab) => { - if (tab.status !== CookieStatus.disabled) { - cookie_string += tab.value; - cookie_string += '\n'; - } - }); - fs.writeFileSync(config.cookieFile, cookie_string); - } -} diff --git a/back/services/env.ts b/back/services/env.ts new file mode 100644 index 00000000..16ffd178 --- /dev/null +++ b/back/services/env.ts @@ -0,0 +1,227 @@ +import { Service, Inject } from 'typedi'; +import winston from 'winston'; +import { getFileContentByName } from '../config/util'; +import config from '../config'; +import * as fs from 'fs'; +import DataStore from 'nedb'; +import { Env, EnvStatus, initEnvPosition } from '../data/env'; +import _ from 'lodash'; + +@Service() +export default class EnvService { + private cronDb = new DataStore({ filename: config.envDbFile }); + constructor(@Inject('logger') private logger: winston.Logger) { + this.cronDb.loadDatabase((err) => { + if (err) throw err; + }); + } + + public async create(payload: Env): Promise { + const envs = await this.envs(); + let position = initEnvPosition; + if (envs && envs.length > 0) { + position = envs[envs.length - 1].position; + } + const tab = new Env({ ...payload, position: position / 2 }); + const doc = await this.insert(tab); + await this.set_envs(); + return doc; + } + + public async insert(payload: Env): Promise { + return new Promise((resolve) => { + this.cronDb.insert(payload, (err, doc) => { + if (err) { + this.logger.error(err); + } else { + resolve(doc); + } + }); + }); + } + + public async update(payload: Env): Promise { + const { _id, ...other } = payload; + const doc = await this.get(_id); + const tab = new Env({ ...doc, ...other }); + const newDoc = await this.updateDb(tab); + await this.set_envs(); + return newDoc; + } + + private async updateDb(payload: Env): Promise { + return new Promise((resolve) => { + this.cronDb.update( + { _id: payload._id }, + payload, + { returnUpdatedDocs: true }, + (err, num, doc) => { + if (err) { + this.logger.error(err); + } else { + resolve(doc as Env); + } + }, + ); + }); + } + + public async remove(ids: string[]) { + return new Promise((resolve: any) => { + this.cronDb.remove( + { _id: { $in: ids } }, + { multi: true }, + async (err) => { + await this.set_envs(); + resolve(); + }, + ); + }); + } + + public async move( + _id: string, + { + fromIndex, + toIndex, + }: { + fromIndex: number; + toIndex: number; + }, + ) { + let targetPosition: number; + const isUpward = fromIndex > toIndex; + const envs = await this.envs(); + if (toIndex === 0 || toIndex === envs.length - 1) { + targetPosition = isUpward + ? envs[0].position * 2 + : envs[toIndex].position / 2; + } else { + targetPosition = isUpward + ? (envs[toIndex].position + envs[toIndex - 1].position) / 2 + : (envs[toIndex].position + envs[toIndex + 1].position) / 2; + } + this.update({ + _id, + position: targetPosition, + }); + await this.set_envs(); + } + + public async envs( + searchText?: string, + sort: any = { position: -1 }, + query: any = {}, + ): Promise { + let condition = { ...query }; + if (searchText) { + const reg = new RegExp(searchText); + condition = { + $or: [ + { + value: reg, + }, + { + name: reg, + }, + { + remarks: reg, + }, + ], + }; + } + const newDocs = await this.find(condition, sort); + return newDocs; + } + + private async find(query: any, sort: any): Promise { + return new Promise((resolve) => { + this.cronDb + .find(query) + .sort({ ...sort }) + .exec((err, docs) => { + resolve(docs); + }); + }); + } + + public async get(_id: string): Promise { + return new Promise((resolve) => { + this.cronDb.find({ _id }).exec((err, docs) => { + resolve(docs[0]); + }); + }); + } + + public async getBySort(sort: any): Promise { + return new Promise((resolve) => { + this.cronDb + .find({}) + .sort({ ...sort }) + .limit(1) + .exec((err, docs) => { + resolve(docs[0]); + }); + }); + } + + public async disabled(ids: string[]) { + return new Promise((resolve: any) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { status: EnvStatus.disabled } }, + { multi: true }, + async (err) => { + await this.set_envs(); + resolve(); + }, + ); + }); + } + + public async enabled(ids: string[]) { + return new Promise((resolve: any) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { status: EnvStatus.noacquired } }, + { multi: true }, + async (err, num) => { + await this.set_envs(); + resolve(); + }, + ); + }); + } + + public async updateNames({ ids, name }: { ids: string[]; name: string }) { + return new Promise((resolve: any) => { + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { name } }, + { multi: true }, + async (err, num) => { + await this.set_envs(); + resolve(); + }, + ); + }); + } + + public async set_envs() { + const envs = await this.envs( + '', + { position: -1 }, + { status: { $ne: EnvStatus.disabled }, name: { $exists: true } }, + ); + const groups = _.groupBy(envs, 'name'); + console.log(groups); + let env_string = ''; + for (const key in groups) { + if (Object.prototype.hasOwnProperty.call(groups, key)) { + const group = groups[key]; + env_string += `export ${key}="${_.map(group, 'value').join('&')}"\n`; + } + } + fs.writeFileSync(config.envFile, env_string); + } +} diff --git a/package.json b/package.json index f07b5b22..57de9a44 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "dotenv": "^8.2.0", "express": "^4.17.1", "express-jwt": "^6.0.0", - "got": "^11.8.2", "jsonwebtoken": "^8.5.1", "nedb": "^1.8.0", "node-fetch": "^2.6.1", @@ -42,12 +41,13 @@ "winston": "^3.3.3" }, "devDependencies": { - "@ant-design/pro-layout": "^6.5.0", "@ant-design/icons": "^4.6.2", + "@ant-design/pro-layout": "^6.5.0", "@types/cors": "^2.8.10", "@types/express": "^4.17.8", "@types/express-jwt": "^6.0.1", "@types/jsonwebtoken": "^8.5.0", + "@types/lodash": "^4.14.170", "@types/nedb": "^1.8.11", "@types/node": "^14.11.2", "@types/node-fetch": "^2.5.8", @@ -60,6 +60,7 @@ "compression-webpack-plugin": "6.1.1", "darkreader": "^4.9.27", "lint-staged": "^10.0.7", + "lodash": "^4.17.21", "nodemon": "^2.0.4", "prettier": "^2.2.0", "qrcode.react": "^1.0.1", diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 5766d3c9..4d2bbc1b 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -29,16 +29,6 @@ RandomDelay="300" ## 如果你自己会写shell脚本,并且希望在每次运行 ql update 命令时,额外运行你的 shell 脚本,请赋值为 "true",默认为true EnableExtraShell="true" -## 自动按顺序进行账号间互助(选填) 设置为 true 时,将直接导入code最新日志来进行互助 -AutoHelpOther="" - -## 定义 jcode 脚本导出的互助码模板样式(选填) -## 不填 使用“按编号顺序助力模板”,Cookie编号在前的优先助力 -## 填 0 使用“全部一致助力模板”,所有账户要助力的码全部一致 -## 填 1 使用“均等机会助力模板”,所有账户获得助力次数一致 -## 填 2 使用“随机顺序助力模板”,本套脚本内账号间随机顺序助力,每次生成的顺序都不一致。 -HelpType="" - ## 是否自动启动bot,默认不启动,设置为true时自动启动,目前需要自行克隆bot仓库所需代码,存到ql/repo目录下,文件夹命名为dockerbot AutoStartBot="" @@ -117,94 +107,4 @@ export GOBOT_URL="" export GOBOT_TOKEN="" export GOBOT_QQ="" -## 如果只是想要屏蔽某个ck不执行某个脚本,可以参考下面 case 这个命令的例子来控制,脚本名称包含后缀 -## case $1 in -## test.js) -## TempBlockCookie="5" -## ;; -## esac - -## 需组合的环境变量列表,env_name需要和var_name一一对应,如何有新活动按照格式添加(不懂勿动) -env_name=( - JD_COOKIE - FRUITSHARECODES - PETSHARECODES - PLANT_BEAN_SHARECODES - DREAM_FACTORY_SHARE_CODES - DDFACTORY_SHARECODES - JDZZ_SHARECODES - JDJOY_SHARECODES - JXNC_SHARECODES - BOOKSHOP_SHARECODES - JD_CASH_SHARECODES - JDSGMH_SHARECODES - JDCFD_SHARECODES - JDHEALTH_SHARECODES -) -var_name=( - Cookie - ForOtherFruit - ForOtherPet - ForOtherBean - ForOtherDreamFactory - ForOtherJdFactory - ForOtherJdzz - ForOtherJoy - ForOtherJxnc - ForOtherBookShop - ForOtherCash - ForOtherSgmh - ForOtherCfd - ForOtherHealth -) - -## name_js为脚本文件名,如果使用ql repo命令拉取,文件名含有作者名 -## 所有有互助码的活动,把脚本名称列在 name_js 中,对应 config.sh 中互助码后缀列在 name_config 中,中文名称列在 name_chinese 中。 -## name_js、name_config 和 name_chinese 中的三个名称必须一一对应。 -name_js=( - jd_fruit - jd_pet - jd_plantBean - jd_dreamFactory - jd_jdfactory - jd_jdzz - jd_crazy_joy - jd_jxnc - jd_bookshop - jd_cash - jd_sgmh - jd_cfd - jd_health -) -name_config=( - Fruit - Pet - Bean - DreamFactory - JdFactory - Jdzz - Joy - Jxnc - BookShop - Cash - Sgmh - Cfd - Health -) -name_chinese=( - 东东农场 - 东东萌宠 - 京东种豆得豆 - 京喜工厂 - 东东工厂 - 京东赚赚 - crazyJoy任务 - 京喜农场 - 口袋书店 - 签到领现金 - 闪购盲盒 - 京喜财富岛 - 东东健康社区 -) - ## 其他需要的变量,脚本中需要的变量使用 export 变量名= 声明即可 diff --git a/sample/package.json b/sample/package.json index b80b416a..6f56bc9f 100644 --- a/sample/package.json +++ b/sample/package.json @@ -5,7 +5,6 @@ "dependencies": { "crypto-js": "^4.0.0", "download": "^8.0.0", - "got": "^11.5.1", "http-server": "^0.12.3", "qrcode-terminal": "^0.12.0", "request": "^2.88.2", diff --git a/shell/code.sh b/shell/code.sh deleted file mode 100755 index 474ff259..00000000 --- a/shell/code.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env bash - -## 导入通用变量与函数 -dir_shell=/ql/shell -. $dir_shell/share.sh - -## 生成pt_pin清单 -gen_pt_pin_array() { - local tmp1 tmp2 i pt_pin_temp - for ((user_num = 1; user_num <= $user_sum; user_num++)); do - tmp1=Cookie$user_num - tmp2=${!tmp1} - i=$(($user_num - 1)) - pt_pin_temp=$(echo $tmp2 | perl -pe "{s|.*pt_pin=([^; ]+)(?=;?).*|\1|; s|%|\\\x|g}") - [[ $pt_pin_temp == *\\x* ]] && pt_pin[i]=$(printf $pt_pin_temp) || pt_pin[i]=$pt_pin_temp - done -} - -## 导出互助码的通用程序,$1:去掉后缀的脚本名称,$2:config.sh中的后缀,$3:活动中文名称 -export_codes_sub() { - local task_name=$1 - local config_name=$2 - local chinese_name=$3 - local config_name_my=My$config_name - local config_name_for_other=ForOther$config_name - local i j k m n pt_pin_in_log code tmp_grep tmp_my_code tmp_for_other user_num random_num_list - if cd $dir_log/$task_name &>/dev/null && [[ $(ls) ]]; then - ## 寻找所有互助码以及对应的pt_pin - i=0 - pt_pin_in_log=() - code=() - pt_pin_and_code=$(ls -r *.log | xargs awk -v var="的$chinese_name好友互助码" 'BEGIN{FS="[( )】]+"; OFS="&"} $3~var {print $2,$4}') - for line in $pt_pin_and_code; do - pt_pin_in_log[i]=$(echo $line | awk -F "&" '{print $1}') - code[i]=$(echo $line | awk -F "&" '{print $2}') - let i++ - done - - ## 输出My系列变量 - if [[ ${#code[*]} -gt 0 ]]; then - for ((m = 0; m < ${#pt_pin[*]}; m++)); do - tmp_my_code="" - j=$((m + 1)) - for ((n = 0; n < ${#code[*]}; n++)); do - if [[ ${pt_pin[m]} == ${pt_pin_in_log[n]} ]]; then - tmp_my_code=${code[n]} - break - fi - done - echo "$config_name_my$j='$tmp_my_code'" - done - else - echo "## 从日志中未找到任何互助码" - fi - - ## 输出ForOther系列变量 - if [[ ${#code[*]} -gt 0 ]]; then - echo - case $HelpType in - 0) ## 全部一致 - tmp_for_other="" - for ((m = 0; m < ${#pt_pin[*]}; m++)); do - j=$((m + 1)) - tmp_for_other="$tmp_for_other@\${$config_name_my$j}" - done - echo "${config_name_for_other}1=\"$tmp_for_other\"" | perl -pe "s|($config_name_for_other\d+=\")@|\1|" - for ((m = 1; m < ${#pt_pin[*]}; m++)); do - j=$((m + 1)) - echo "$config_name_for_other$j=\"\${${config_name_for_other}1}\"" - done - ;; - - 1) ## 均等助力 - for ((m = 0; m < ${#pt_pin[*]}; m++)); do - tmp_for_other="" - j=$((m + 1)) - for ((n = $m; n < $(($user_sum + $m)); n++)); do - [[ $m -eq $n ]] && continue - if [[ $((n + 1)) -le $user_sum ]]; then - k=$((n + 1)) - else - k=$((n + 1 - $user_sum)) - fi - tmp_for_other="$tmp_for_other@\${$config_name_my$k}" - done - echo "$config_name_for_other$j=\"$tmp_for_other\"" | perl -pe "s|($config_name_for_other\d+=\")@|\1|" - done - ;; - - 2) ## 本套脚本内账号间随机顺序助力 - for ((m = 0; m < ${#pt_pin[*]}; m++)); do - tmp_for_other="" - random_num_list=$(seq $user_sum | sort -R) - j=$((m + 1)) - for n in $random_num_list; do - [[ $j -eq $n ]] && continue - tmp_for_other="$tmp_for_other@\${$config_name_my$n}" - done - echo "$config_name_for_other$j=\"$tmp_for_other\"" | perl -pe "s|($config_name_for_other\d+=\")@|\1|" - done - ;; - - *) ## 按编号优先 - for ((m = 0; m < ${#pt_pin[*]}; m++)); do - tmp_for_other="" - j=$((m + 1)) - for ((n = 0; n < ${#pt_pin[*]}; n++)); do - [[ $m -eq $n ]] && continue - k=$((n + 1)) - tmp_for_other="$tmp_for_other@\${$config_name_my$k}" - done - echo "$config_name_for_other$j=\"$tmp_for_other\"" | perl -pe "s|($config_name_for_other\d+=\")@|\1|" - done - ;; - esac - fi - else - echo "## 未运行过 $task_name.js 脚本,未产生日志" - fi -} - -## 汇总输出 -export_all_codes() { - gen_pt_pin_array - echo -e "\n# 从日志提取互助码,编号和配置文件中Cookie编号完全对应,如果为空就是所有日志中都没有。\n\n# 即使某个MyXxx变量未赋值,也可以将其变量名填在ForOtherXxx中,jtask脚本会自动过滤空值。\n" - echo -n "# 你选择的互助码模板为:" - case $HelpType in - 0) - echo "所有账号助力码全部一致。" - ;; - 1) - echo "所有账号机会均等助力。" - ;; - 2) - echo "本套脚本内账号间随机顺序助力。" - ;; - *) - echo "按账号编号优先。" - ;; - esac - for ((i = 0; i < ${#name_js[*]}; i++)); do - echo -e "\n## ${name_chinese[i]}:" - export_codes_sub "${name_js[i]}" "${name_config[i]}" "${name_chinese[i]}" - done -} - -## 执行并写入日志 -log_time=$(date "+%Y-%m-%d-%H-%M-%S") -log_path="$dir_code/$log_time.log" -make_dir "$dir_code" -export_all_codes | perl -pe "{s|京东种豆|种豆|; s|crazyJoy任务|疯狂的JOY|}" | tee $log_path diff --git a/shell/share.sh b/shell/share.sh index 28ca2c55..3f4bf0c0 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -18,7 +18,7 @@ ql_static_repo=$dir_repo/static ## 文件 file_config_sample=$dir_sample/config.sample.sh -file_cookie=$dir_config/cookie.sh +file_env=$dir_config/env.sh file_sharecode=$dir_config/sharecode.sh file_config_user=$dir_config/config.sh file_auth_sample=$dir_sample/auth.sample.json @@ -53,15 +53,9 @@ original_name=( ## 导入配置文件 import_config() { [ -f $file_config_user ] && . $file_config_user - user_sum=0 - for line in $(cat $file_cookie); do - let user_sum+=1 - eval Cookie${user_sum}="\"${line}\"" - done command_timeout_time=${CommandTimeoutTime:-"1h"} github_proxy_url=${GithubProxyUrl:-""} - block_cookie=${TempBlockCookie:-""} file_extensions=${RepoFileExtensions:-"js py"} } @@ -161,9 +155,9 @@ fix_config() { echo fi - if [ ! -f $file_cookie ]; then - echo -e "检测到config配置目录下不存在cookie.sh,创建一个空文件用于初始化...\n" - touch $file_cookie + if [ ! -f $file_env ]; then + echo -e "检测到config配置目录下不存在env.sh,创建一个空文件用于初始化...\n" + touch $file_env echo fi @@ -289,13 +283,8 @@ git_pull_scripts() { cd $dir_current } -init_env() { - TempBlockCookie="" -} - ## 导入配置文件,检测平台,创建软连接,识别命令,修复配置文件 detect_termux detect_macos define_cmd -init_env import_config $1 diff --git a/shell/task.sh b/shell/task.sh index 0c181557..91c35dad 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -5,41 +5,6 @@ dir_shell=/ql/shell . $dir_shell/share.sh . $dir_shell/api.sh -## 组合Cookie和互助码子程序,$1:要组合的内容 -combine_sub() { - local what_combine=$1 - local combined_all="" - local tmp1 tmp2 - for ((i = 1; i <= $user_sum; i++)); do - for num in $block_cookie; do - [[ $i -eq $num ]] && continue 2 - done - local tmp1=$what_combine$i - local tmp2=${!tmp1} - combined_all="$combined_all&$tmp2" - done - echo $combined_all | perl -pe "{s|^&||; s|^@+||; s|&@|&|g; s|@+&|&|g; s|@+|@|g; s|@+$||}" -} - -## 正常依次运行时,组合所有账号的Cookie与互助码 -combine_all() { - for ((i = 0; i < ${#env_name[*]}; i++)); do - result=$(combine_sub ${var_name[i]}) - if [[ $result ]]; then - export ${env_name[i]}="$result" - fi - done -} - -## 并发运行时,直接申明每个账号的Cookie与互助码,$1:用户Cookie编号 -combine_one() { - local user_num=$1 - for ((i = 0; i < ${#env_name[*]}; i++)); do - local tmp=${var_name[i]}$user_num - export ${env_name[i]}=${!tmp} - done -} - ## 选择python3还是node define_program() { local p1=$1 @@ -118,7 +83,6 @@ run_normal() { random_delay fi fi - combine_all log_time=$(date "+%Y-%m-%d-%H-%M-%S") log_dir_tmp="${p1##*/}" log_dir="$dir_log/${log_dir_tmp%%.*}" @@ -131,18 +95,20 @@ run_normal() { update_cron_status "\"$id\"" "1" } -## 并发执行,因为是并发,所以日志只能直接记录在日志文件中(日志文件以Cookie编号结尾),前台执行并发跑时不会输出日志 ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行 run_concurrent() { local p1=$1 + local p3=$3 + local envs=$(eval echo "\$${p3}") + local array=(${envs//&/}) cd $dir_scripts define_program "$p1" log_dir="$dir_log/${p1%%.*}" make_dir $log_dir log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" - for ((user_num = 1; user_num <= $user_sum; user_num++)); do - combine_one $user_num + for i in "${!array[@]}"; do + export ${p3}=${array[i]} log_path="$log_dir/${log_time}_${user_num}.log" timeout $command_timeout_time $which_program $p1 &>$log_path & done @@ -173,7 +139,7 @@ main() { run_normal $1 $2 ;; conc) - run_concurrent $1 $2 + run_concurrent $1 $2 $3 ;; *) run_else "$@" diff --git a/src/app.tsx b/src/app.tsx index a726a792..71ebfbb2 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -6,9 +6,9 @@ const titleMap: any = { '/': '控制面板', '/login': '登录', '/crontab': '定时任务', - '/cookie': 'Session管理', + '/env': '环境变量', '/config': '配置文件', - '/diy': '自定义脚本', + '/script': '查看脚本', '/diff': '对比工具', '/log': '日志', '/setting': '系统设置', diff --git a/src/layouts/defaultProps.tsx b/src/layouts/defaultProps.tsx index 547d6988..f2019f18 100644 --- a/src/layouts/defaultProps.tsx +++ b/src/layouts/defaultProps.tsx @@ -25,10 +25,10 @@ export default { component: '@/pages/crontab/index', }, { - path: '/cookie', - name: 'Session管理', + path: '/env', + name: '环境变量', icon: , - component: '@/pages/cookie/index', + component: '@/pages/env/index', }, { path: '/config', @@ -37,10 +37,10 @@ export default { component: '@/pages/config/index', }, { - path: '/diy', - name: '自定义脚本', + path: '/script', + name: '查看脚本', icon: , - component: '@/pages/diy/index', + component: '@/pages/script/index', }, { path: '/diff', diff --git a/src/layouts/index.less b/src/layouts/index.less index 8d364b9b..1804cb2a 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -36,7 +36,7 @@ body { } } -.session-wrapper { +.env-wrapper { th { white-space: nowrap; } @@ -51,6 +51,15 @@ body { } } +.config-wrapper { + .config-select { + width: 250px; + } + .ant-page-header-heading-left { + min-width: 100px; + } +} + @media (max-width: 768px) { .ant-pro-grid-content.wide { .ant-pro-page-container-children-content { diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index a0842325..438438da 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -1,5 +1,5 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, message, Modal } from 'antd'; +import { Button, message, Modal, TreeSelect } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { Controlled as CodeMirror } from 'react-codemirror2'; @@ -11,27 +11,42 @@ const Config = () => { const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); const [loading, setLoading] = useState(true); + const [title, setTitle] = useState('config.sh'); + const [select, setSelect] = useState('config.sh'); + const [data, setData] = useState([]); - const getConfig = () => { + const getConfig = (name: string) => { + request.get(`${config.apiPrefix}configs/${name}`).then((data: any) => { + setValue(data.data); + }); + }; + + const getFiles = () => { setLoading(true); request - .get(`${config.apiPrefix}config/config`) + .get(`${config.apiPrefix}configs/files`) .then((data: any) => { - setValue(data.data); + setData(data.data); }) .finally(() => setLoading(false)); }; const updateConfig = () => { request - .post(`${config.apiPrefix}save`, { - data: { content: value, name: 'config.sh' }, + .post(`${config.apiPrefix}configs/save`, { + data: { content: value, name: select }, }) .then((data: any) => { message.success(data.msg); }); }; + const onSelect = (value: any, node: any) => { + setSelect(value); + setTitle(node.value); + getConfig(node.value); + }; + useEffect(() => { if (document.body.clientWidth < 768) { setWidth('auto'); @@ -42,14 +57,24 @@ const Config = () => { setMarginLeft(0); setMarginTop(-72); } - getConfig(); + getFiles(); + getConfig('config.sh'); }, []); return ( , , diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index 6012a695..12b06a96 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -15,7 +15,7 @@ const Crontab = () => { const [loading, setLoading] = useState(true); const getConfig = () => { - request.get(`${config.apiPrefix}config/config`).then((data) => { + request.get(`${config.apiPrefix}configs/config.sh`).then((data) => { setValue(data.data); }); }; @@ -23,7 +23,7 @@ const Crontab = () => { const getSample = () => { setLoading(true); request - .get(`${config.apiPrefix}config/sample`) + .get(`${config.apiPrefix}config/config.sample.sh`) .then((data) => { setSample(data.data); }) diff --git a/src/pages/diy/index.less b/src/pages/diy/index.less deleted file mode 100644 index e69de29b..00000000 diff --git a/src/pages/diy/index.tsx b/src/pages/diy/index.tsx deleted file mode 100644 index a110a01e..00000000 --- a/src/pages/diy/index.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React, { PureComponent, Fragment, useState, useEffect } from 'react'; -import { Button, message, Modal } from 'antd'; -import config from '@/utils/config'; -import { PageContainer } from '@ant-design/pro-layout'; -import { Controlled as CodeMirror } from 'react-codemirror2'; -import { request } from '@/utils/http'; - -const Crontab = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); - const [value, setValue] = useState(''); - const [loading, setLoading] = useState(true); - - const getConfig = () => { - setLoading(true); - request - .get(`${config.apiPrefix}config/extra`) - .then((data) => { - setValue(data.data); - }) - .finally(() => setLoading(false)); - }; - - const updateConfig = () => { - request - .post(`${config.apiPrefix}save`, { - data: { content: value, name: 'extra.sh' }, - }) - .then((data) => { - message.success(data.msg); - }); - }; - - useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - } - getConfig(); - }, []); - - return ( - - 保存 - , - ]} - header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, - }} - > - { - setValue(value); - }} - onChange={(editor, data, value) => {}} - /> - - ); -}; - -export default Crontab; diff --git a/src/pages/env/editNameModal.tsx b/src/pages/env/editNameModal.tsx new file mode 100644 index 00000000..1affc835 --- /dev/null +++ b/src/pages/env/editNameModal.tsx @@ -0,0 +1,77 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, message, Input, Form } from 'antd'; +import { request } from '@/utils/http'; +import config from '@/utils/config'; + +const EditNameModal = ({ + ids, + handleCancel, + visible, +}: { + ids?: string[]; + visible: boolean; + handleCancel: () => void; +}) => { + const [form] = Form.useForm(); + const [loading, setLoading] = useState(false); + + const handleOk = async (values: any) => { + console.log(values); + console.log(ids); + setLoading(true); + const { code, data } = await request.put(`${config.apiPrefix}envs/name`, { + data: { + ids, + name: values.name, + }, + }); + if (code === 200) { + message.success('更新环境变量名称成功'); + } else { + message.error(data); + } + setLoading(false); + handleCancel(); + }; + + useEffect(() => { + form.resetFields(); + }, [ids]); + + return ( + { + form + .validateFields() + .then((values) => { + handleOk(values); + }) + .catch((info) => { + console.log('Validate Failed:', info); + }); + }} + onCancel={() => handleCancel()} + confirmLoading={loading} + destroyOnClose + > +
+ + + + +
+ ); +}; + +export default EditNameModal; diff --git a/src/pages/cookie/index.less b/src/pages/env/index.less similarity index 100% rename from src/pages/cookie/index.less rename to src/pages/env/index.less diff --git a/src/pages/cookie/index.tsx b/src/pages/env/index.tsx similarity index 74% rename from src/pages/cookie/index.tsx rename to src/pages/env/index.tsx index 11c59458..27134f66 100644 --- a/src/pages/cookie/index.tsx +++ b/src/pages/env/index.tsx @@ -19,8 +19,8 @@ import { import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; -import QRCode from 'qrcode.react'; -import CookieModal from './modal'; +import EnvModal from './modal'; +import EditNameModal from './editNameModal'; import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import './index.less'; @@ -28,17 +28,12 @@ import './index.less'; const { Text } = Typography; enum Status { - '未获取', - '正常', + '已启用', '已禁用', - '已失效', - '状态异常', } enum StatusColor { - 'default', 'success', - 'warning', 'error', } @@ -106,7 +101,7 @@ const DragableBodyRow = ({ ); }; -const Config = () => { +const Env = () => { const columns = [ { title: '序号', @@ -116,25 +111,17 @@ const Config = () => { }, }, { - title: '昵称', - dataIndex: 'nickname', - key: 'nickname', + title: '名称', + dataIndex: 'name', + key: 'name', align: 'center' as const, - width: '15%', - render: (text: string, record: any, index: number) => { - const match = record.value.match(/pt_pin=([^; ]+)(?=;?)/); - const val = (match && match[1]) || '未匹配用户名'; - return ( - {record.nickname || val} - ); - }, }, { title: '值', dataIndex: 'value', key: 'value', align: 'center' as const, - width: '50%', + width: '45%', render: (text: string, record: any) => { return ( { display: 'inline-block', wordBreak: 'break-all', cursor: 'text', + width: '100%', }} > {text} @@ -150,28 +138,24 @@ const Config = () => { ); }, }, + { + title: '备注', + dataIndex: 'remarks', + key: 'remarks', + align: 'center' as const, + }, { title: '状态', key: 'status', dataIndex: 'status', align: 'center' as const, - width: '15%', + width: 60, render: (text: string, record: any, index: number) => { return ( - + {Status[record.status]} - {record.status !== Status.已禁用 && ( - - refreshStatus(record, index)}> - - - - )} ); }, @@ -183,12 +167,12 @@ const Config = () => { render: (text: string, record: any, index: number) => ( - editCookie(record, index)}> + editEnv(record, index)}> - enabledOrDisabledCookie(record, index)}> + enabledOrDisabledEnv(record, index)}> {record.status === Status.已禁用 ? ( ) : ( @@ -197,7 +181,7 @@ const Config = () => { - deleteCookie(record, index)}> + deleteEnv(record, index)}> @@ -211,39 +195,27 @@ const Config = () => { const [value, setValue] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); - const [editedCookie, setEditedCookie] = useState(); + const [isEditNameModalVisible, setIsEditNameModalVisible] = useState(false); + const [editedEnv, setEditedEnv] = useState(); const [selectedRowIds, setSelectedRowIds] = useState([]); - const getCookies = () => { + const getEnvs = () => { setLoading(true); request - .get(`${config.apiPrefix}cookies`) + .get(`${config.apiPrefix}envs`) .then((data: any) => { setValue(data.data); }) .finally(() => setLoading(false)); }; - const refreshStatus = (record: any, index: number) => { - request - .get(`${config.apiPrefix}cookies/${record._id}/refresh`) - .then(async (data: any) => { - if (data.data && data.data.value) { - (value as any).splice(index, 1, data.data); - setValue([...(value as any)] as any); - } else { - message.error('更新状态失败'); - } - }); - }; - - const enabledOrDisabledCookie = (record: any, index: number) => { + const enabledOrDisabledEnv = (record: any, index: number) => { Modal.confirm({ title: `确认${record.status === Status.已禁用 ? '启用' : '禁用'}`, content: ( <> 确认{record.status === Status.已禁用 ? '启用' : '禁用'} - Cookie{' '} + Env{' '} {record.value} {' '} @@ -253,7 +225,7 @@ const Config = () => { onOk() { request .put( - `${config.apiPrefix}cookies/${ + `${config.apiPrefix}envs/${ record.status === Status.已禁用 ? 'enable' : 'disable' }`, { @@ -284,22 +256,22 @@ const Config = () => { }); }; - const addCookie = () => { - setEditedCookie(null as any); + const addEnv = () => { + setEditedEnv(null as any); setIsModalVisible(true); }; - const editCookie = (record: any, index: number) => { - setEditedCookie(record); + const editEnv = (record: any, index: number) => { + setEditedEnv(record); setIsModalVisible(true); }; - const deleteCookie = (record: any, index: number) => { + const deleteEnv = (record: any, index: number) => { Modal.confirm({ title: '确认删除', content: ( <> - 确认删除Cookie{' '} + 确认删除Env{' '} {record.value} {' '} @@ -308,7 +280,7 @@ const Config = () => { ), onOk() { request - .delete(`${config.apiPrefix}cookies`, { data: [record._id] }) + .delete(`${config.apiPrefix}envs`, { data: [record._id] }) .then((data: any) => { if (data.code === 200) { message.success('删除成功'); @@ -326,25 +298,25 @@ const Config = () => { }); }; - const handleCancel = (cookies?: any[]) => { + const handleCancel = (env?: any[]) => { setIsModalVisible(false); - if (cookies && cookies.length > 0) { - handleCookies(cookies); - } + handleEnv(env); }; - const handleCookies = (cookies: any[]) => { + const handleEditNameCancel = (env?: any[]) => { + setIsEditNameModalVisible(false); + getEnvs(); + }; + + const handleEnv = (env: any) => { const result = [...value]; - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i]; - const index = value.findIndex((x) => x._id === cookie._id); - if (index === -1) { - result.push(cookie); - } else { - result.splice(index, 1, { - ...cookie, - }); - } + const index = value.findIndex((x) => x._id === env._id); + if (index === -1) { + result.push(env); + } else { + result.splice(index, 1, { + ...env, + }); } setValue(result); }; @@ -366,7 +338,7 @@ const Config = () => { newData.splice(hoverIndex, 0, dragRow); setValue([...newData]); request - .put(`${config.apiPrefix}cookies/${dragRow._id}/move`, { + .put(`${config.apiPrefix}envs/${dragRow._id}/move`, { data: { fromIndex: dragIndex, toIndex: hoverIndex }, }) .then((data: any) => { @@ -387,18 +359,18 @@ const Config = () => { onChange: onSelectChange, }; - const delCookies = () => { + const delEnvs = () => { Modal.confirm({ title: '确认删除', - content: <>确认删除选中的Cookie吗, + content: <>确认删除选中的Env吗, onOk() { request - .delete(`${config.apiPrefix}cookies`, { data: selectedRowIds }) + .delete(`${config.apiPrefix}envs`, { data: selectedRowIds }) .then((data: any) => { if (data.code === 200) { message.success('批量删除成功'); setSelectedRowIds([]); - getCookies(); + getEnvs(); } else { message.error(data); } @@ -410,18 +382,18 @@ const Config = () => { }); }; - const operateCookies = (operationStatus: number) => { + const operateEnvs = (operationStatus: number) => { Modal.confirm({ title: `确认${OperationName[operationStatus]}`, - content: <>确认{OperationName[operationStatus]}选中的Cookie吗, + content: <>确认{OperationName[operationStatus]}选中的Env吗, onOk() { request - .put(`${config.apiPrefix}cookies/${OperationPath[operationStatus]}`, { + .put(`${config.apiPrefix}envs/${OperationPath[operationStatus]}`, { data: selectedRowIds, }) .then((data: any) => { if (data.code === 200) { - getCookies(); + getEnvs(); } else { message.error(data); } @@ -433,6 +405,10 @@ const Config = () => { }); }; + const modifyName = () => { + setIsEditNameModalVisible(true); + }; + useEffect(() => { if (document.body.clientWidth < 768) { setWidth('auto'); @@ -443,16 +419,16 @@ const Config = () => { setMarginLeft(0); setMarginTop(-72); } - getCookies(); + getEnvs(); }, []); return ( addCookie()}> - 添加Cookie + , ]} header={{ @@ -473,20 +449,27 @@ const Config = () => { + , From 173b87a7b1aae188166db8c7245d8d08407216a8 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 21 Jun 2021 17:22:23 +0800 Subject: [PATCH 116/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Denv=E5=90=AF=E7=94=A8?= =?UTF-8?q?=E7=A6=81=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/data/env.ts | 5 +---- back/services/env.ts | 2 +- src/pages/env/index.tsx | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/back/data/env.ts b/back/data/env.ts index f19418f0..5ddb9c3d 100644 --- a/back/data/env.ts +++ b/back/data/env.ts @@ -12,7 +12,7 @@ export class Env { this.value = options.value; this._id = options._id; this.created = options.created || new Date().valueOf(); - this.status = options.status || EnvStatus.noacquired; + this.status = options.status || EnvStatus.normal; this.timestamp = new Date().toString(); this.position = options.position; this.name = options.name; @@ -21,11 +21,8 @@ export class Env { } export enum EnvStatus { - 'noacquired', 'normal', 'disabled', - 'invalid', - 'abnormal', } export const initEnvPosition = 9999999999; diff --git a/back/services/env.ts b/back/services/env.ts index 7288f458..e75553fa 100644 --- a/back/services/env.ts +++ b/back/services/env.ts @@ -183,7 +183,7 @@ export default class EnvService { return new Promise((resolve: any) => { this.cronDb.update( { _id: { $in: ids } }, - { $set: { status: EnvStatus.noacquired } }, + { $set: { status: EnvStatus.normal } }, { multi: true }, async (err, num) => { await this.set_envs(); diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 4d8b582a..753d92f8 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -241,7 +241,7 @@ const Env = () => { `${record.status === Status.已禁用 ? '启用' : '禁用'}成功`, ); const newStatus = - record.status === Status.已禁用 ? Status.未获取 : Status.已禁用; + record.status === Status.已禁用 ? Status.已启用 : Status.已禁用; const result = [...value]; result.splice(index, 1, { ...record, From c9fecae67a42a627e091d2ca52ac5eb006e0f133 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 21 Jun 2021 22:41:19 +0800 Subject: [PATCH 117/247] =?UTF-8?q?ql=20bot=E6=B7=BB=E5=8A=A0=E9=87=8D?= =?UTF-8?q?=E7=BD=AEremote=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/bot.sh | 1 + shell/share.sh | 17 +++++++++++++++++ shell/update.sh | 17 ----------------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/shell/bot.sh b/shell/bot.sh index c6b71d05..373ec42c 100644 --- a/shell/bot.sh +++ b/shell/bot.sh @@ -12,6 +12,7 @@ echo -e "\nbot依赖安装成功...\n" echo -e "2、下载bot所需文件...\n" if [ -d ${repo_path}/.git ]; then + reset_romote_url ${repo_path} "${url}" git_pull_scripts ${repo_path} else rm -rf ${repo_path} diff --git a/shell/share.sh b/shell/share.sh index ef099ca6..704c2b0e 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -299,6 +299,23 @@ git_pull_scripts() { cd $dir_current } +## 重置仓库remote url,docker专用,$1:要重置的目录,$2:要重置为的网址 +reset_romote_url() { + local dir_current=$(pwd) + local dir_work=$1 + local url=$2 + local branch="$3" + + [[ $branch ]] && local cmd="origin/${branch}" + + if [ -d "$dir_work/.git" ]; then + cd $dir_work + git remote set-url origin $url >/dev/null + git reset --hard $cmd >/dev/null + cd $dir_current + fi +} + ## 导入配置文件,检测平台,创建软连接,识别命令,修复配置文件 detect_termux detect_macos diff --git a/shell/update.sh b/shell/update.sh index 5c5ef2d4..9bd267c2 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -7,23 +7,6 @@ dir_shell=/ql/shell send_mark=$dir_shell/send_mark -## 重置仓库remote url,docker专用,$1:要重置的目录,$2:要重置为的网址 -reset_romote_url() { - local dir_current=$(pwd) - local dir_work=$1 - local url=$2 - local branch="$3" - - [[ $branch ]] && local cmd="origin/${branch}" - - if [ -d "$dir_work/.git" ]; then - cd $dir_work - git remote set-url origin $url >/dev/null - git reset --hard $cmd >/dev/null - cd $dir_current - fi -} - ## 检测cron的差异,$1:脚本清单文件路径,$2:cron任务清单文件路径,$3:增加任务清单文件路径,$4:删除任务清单文件路径 diff_cron() { local list_scripts="$1" From 4d4d31431df4bc9d92510b685b473a17e7ae4a7b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 23 Jun 2021 18:58:32 +0800 Subject: [PATCH 118/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=A7=E8=A1=8Cshe?= =?UTF-8?q?ll=E8=84=9A=E6=9C=AC=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 2 ++ shell/update.sh | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index 8e0d264c..71395b12 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -12,6 +12,8 @@ define_program() { which_program="node" elif [[ $p1 == *.py ]]; then which_program="python3" + elif [[ $p1 == *.sh ]]; then + which_program="bash" else which_program="" fi diff --git a/shell/update.sh b/shell/update.sh index 9bd267c2..33cf3f0a 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -426,9 +426,6 @@ main() { rmlog) . $dir_shell/rmlog.sh "$p2" | tee $log_path ;; - code) - . $dir_shell/code.sh - ;; bot) . $dir_shell/bot.sh ;; From e03c64dceb4669ccf1cd10f18c352269d2f3fd2d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 24 Jun 2021 18:55:26 +0800 Subject: [PATCH 119/247] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9F=A5=E7=9C=8B=E6=9C=80=E6=96=B0=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/auth.ts | 11 ++++++----- back/data/cron.ts | 4 +++- back/services/cron.ts | 19 +++++++++++++++++-- shell/task.sh | 3 ++- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/back/api/auth.ts b/back/api/auth.ts index aace6a53..7bcd3a6e 100644 --- a/back/api/auth.ts +++ b/back/api/auth.ts @@ -5,6 +5,7 @@ import * as fs from 'fs'; import config from '../config'; import jwt from 'jsonwebtoken'; import { createPassword } from '../config/util'; +import crypto from 'crypto'; const route = Router(); export default (app: Router) => { @@ -41,11 +42,11 @@ export default (app: Router) => { username == authInfo.username && password == authInfo.password ) { - let token = jwt.sign( - { username, password }, - config.secret as any, - { expiresIn: 60 * 60 * 24 * 7, algorithm: 'HS384' }, - ); + const data = createPassword(50, 100); + let token = jwt.sign({ data }, config.secret as any, { + expiresIn: 60 * 60 * 24 * 3, + algorithm: 'HS384', + }); fs.writeFileSync( config.authConfigFile, JSON.stringify({ diff --git a/back/data/cron.ts b/back/data/cron.ts index 96aabe9f..0b050355 100644 --- a/back/data/cron.ts +++ b/back/data/cron.ts @@ -18,7 +18,9 @@ export class Crontab { this.saved = options.saved; this._id = options._id; this.created = options.created; - this.status = options.status || CrontabStatus.idle; + this.status = CrontabStatus[options.status] + ? options.status + : CrontabStatus.idle; this.timestamp = new Date().toString(); this.isSystem = options.isSystem || 0; this.pid = options.pid; diff --git a/back/services/cron.ts b/back/services/cron.ts index 88f94032..355f1c94 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -8,6 +8,7 @@ import fs from 'fs'; import cron_parser from 'cron-parser'; import { getFileContentByName } from '../config/util'; import PQueue from 'p-queue'; +import { promises, existsSync } from 'fs'; @Service() export default class CronService { @@ -275,8 +276,22 @@ export default class CronService { } public async log(_id: string) { - let logFile = `${config.manualLogPath}${_id}.log`; - return getFileContentByName(logFile); + const doc = await this.get(_id); + const commandStr = doc.command.split(' ')[1]; + const start = + commandStr.lastIndexOf('/') !== -1 ? commandStr.lastIndexOf('/') + 1 : 0; + const end = + commandStr.lastIndexOf('.') !== -1 + ? commandStr.lastIndexOf('.') + : commandStr.length; + const logPath = commandStr.substring(start, end); + let logDir = `${config.logPath}${logPath}`; + if (existsSync(logDir)) { + const files = await promises.readdir(logDir); + return getFileContentByName(`${logDir}/${files[files.length - 1]}`); + } else { + return ''; + } } private make_command(tab: Crontab) { diff --git a/shell/task.sh b/shell/task.sh index 71395b12..4051155e 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -108,7 +108,8 @@ run_concurrent() { local array=($(echo $envs | sed 's/&/ /g')) cd $dir_scripts define_program "$p1" - log_dir="$dir_log/${p1%%.*}" + log_dir_tmp="${p1##*/}" + log_dir="$dir_log/${log_dir_tmp%%.*}" make_dir $log_dir log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" From e11d0c25f3b68c7f6f2486bdb0294a186cdd50c9 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 24 Jun 2021 18:56:22 +0800 Subject: [PATCH 120/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 029c8b38..e6a656a3 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0'; -export const changeLog = 'https://t.me/jiaolongwang/110'; +export const version = 'v2.8.0-061'; +export const changeLog = 'https://t.me/jiaolongwang/111'; From ce3543779e5ffbc3e0f51ddfb6a83f26535a8340 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 24 Jun 2021 23:46:02 +0800 Subject: [PATCH 121/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E4=BB=BB=E5=8A=A1=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/config/index.ts | 2 -- back/services/cron.ts | 55 +++++++------------------------------------ shell/share.sh | 2 -- shell/task.sh | 7 +++++- 4 files changed, 14 insertions(+), 52 deletions(-) diff --git a/back/config/index.ts b/back/config/index.ts index d7eb56ee..af297c63 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -19,7 +19,6 @@ const authError = '错误的用户名密码,请重试'; const loginFaild = '请先登录!'; const configString = 'config sample crontab shareCode diy'; const dbPath = path.join(rootPath, 'db/'); -const manualLogPath = path.join(rootPath, 'manual_log/'); const cronDbFile = path.join(rootPath, 'db/crontab.db'); const envDbFile = path.join(rootPath, 'db/env.db'); const configFound = dotenv.config({ path: confFile }); @@ -56,7 +55,6 @@ export default { dbPath, cronDbFile, envDbFile, - manualLogPath, configPath, scriptPath, blackFileList: ['auth.json', 'config.sh.sample', 'cookie.sh', 'crontab.list'], diff --git a/back/services/cron.ts b/back/services/cron.ts index 355f1c94..4dcd522a 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -187,12 +187,6 @@ export default class CronService { this.logger.silly('ID: ' + _id); this.logger.silly('Original command: ' + command); - let logFile = `${config.manualLogPath}${_id}.log`; - fs.writeFileSync( - logFile, - `开始执行... ${new Date().toLocaleString()}\n\n`, - ); - let cmdStr = command; if (!cmdStr.includes('task ') && !cmdStr.includes('ql ')) { cmdStr = `task ${cmdStr}`; @@ -200,50 +194,17 @@ export default class CronService { if (cmdStr.endsWith('.js')) { cmdStr = `${cmdStr} now`; } - const cmd = spawn(cmdStr, { shell: true }); - + const cp = exec(cmdStr, (err, stdout, stderr) => { + this.cronDb.update( + { _id }, + { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, + ); + resolve(); + }); this.cronDb.update( { _id }, - { $set: { status: CrontabStatus.running, pid: cmd.pid } }, + { $set: { status: CrontabStatus.running, pid: cp.pid } }, ); - - cmd.stdout.on('data', (data) => { - this.logger.silly(`stdout: ${data}`); - fs.appendFileSync(logFile, data); - }); - - cmd.stderr.on('data', (data) => { - this.logger.silly(`stderr: ${data}`); - fs.appendFileSync(logFile, data); - }); - - cmd.on('close', (code) => { - this.logger.silly(`child process exited with code ${code}`); - this.cronDb.update( - { _id }, - { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, - ); - }); - - cmd.on('error', (err) => { - this.logger.info(err); - fs.appendFileSync(logFile, err.stack); - }); - - cmd.on('exit', (code: number, signal: any) => { - this.logger.silly(`cmd exit ${code}`); - this.cronDb.update( - { _id }, - { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, - ); - fs.appendFileSync(logFile, `\n执行结束...`); - resolve(); - }); - - process.on('SIGINT', function () { - fs.appendFileSync(logFile, `\n执行结束...`); - resolve(); - }); }); } diff --git a/shell/share.sh b/shell/share.sh index 704c2b0e..23b7482f 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -10,7 +10,6 @@ dir_repo=$dir_root/repo dir_raw=$dir_root/raw dir_log=$dir_root/log dir_db=$dir_root/db -dir_manual_log=$dir_root/manual_log dir_list_tmp=$dir_log/.tmp dir_code=$dir_log/code dir_update_log=$dir_log/update @@ -146,7 +145,6 @@ fix_config() { make_dir $dir_config make_dir $dir_log make_dir $dir_db - make_dir $dir_manual_log make_dir $dir_scripts make_dir $dir_list_tmp make_dir $dir_repo diff --git a/shell/task.sh b/shell/task.sh index 4051155e..5a36604d 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -89,10 +89,15 @@ run_normal() { make_dir "$log_dir" local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | xargs | sed 's/ /","/g') + local begin_time=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "开始执行... $begin_time\n" >> $log_path update_cron_status "\"$id\"" "0" - timeout $command_timeout_time $which_program $p1 2>&1 | tee $log_path + timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path . $file_task_after update_cron_status "\"$id\"" "1" + local end_time=$(date '+%Y-%m-%d %H:%M:%S') + local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) + echo -e "\n执行结束... $end_time 耗时 $diff_time 秒" >> $log_path } ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行 From 86e5f208fb056c8c43e9cbeb5e9796d5c0b765d5 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 25 Jun 2021 15:50:04 +0800 Subject: [PATCH 122/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 30 +++++++++++++++++++++--------- shell/update.sh | 27 +++++++++++++++++++-------- src/pages/crontab/logModal.tsx | 7 ++++++- 3 files changed, 46 insertions(+), 18 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 4dcd522a..f6d76865 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -238,23 +238,35 @@ export default class CronService { public async log(_id: string) { const doc = await this.get(_id); - const commandStr = doc.command.split(' ')[1]; - const start = - commandStr.lastIndexOf('/') !== -1 ? commandStr.lastIndexOf('/') + 1 : 0; - const end = - commandStr.lastIndexOf('.') !== -1 - ? commandStr.lastIndexOf('.') - : commandStr.length; - const logPath = commandStr.substring(start, end); + const [, commandStr, url] = doc.command.split(' '); + let logPath = this.getKey(commandStr); + const isQlCommand = doc.command.startsWith('ql '); + const key = this.getKey(url) || logPath; + if (isQlCommand) { + logPath = 'update'; + } let logDir = `${config.logPath}${logPath}`; if (existsSync(logDir)) { - const files = await promises.readdir(logDir); + let files = await promises.readdir(logDir); + if (isQlCommand) { + files = files.filter((x) => x.includes(key)); + } return getFileContentByName(`${logDir}/${files[files.length - 1]}`); } else { return ''; } } + private getKey(command: string) { + const start = + command.lastIndexOf('/') !== -1 ? command.lastIndexOf('/') + 1 : 0; + const end = + command.lastIndexOf('.') !== -1 + ? command.lastIndexOf('.') + : command.length; + return command.substring(start, end); + } + private make_command(tab: Crontab) { const crontab_job_string = `ID=${tab._id} ${tab.command}`; return crontab_job_string; diff --git a/shell/update.sh b/shell/update.sh index 33cf3f0a..cade8f08 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -392,21 +392,25 @@ main() { local p4=$4 local p5=$5 local p6=$6 - log_time=$(date "+%Y-%m-%d-%H-%M-%S") - log_path="$dir_log/update/${log_time}_$p1.log" + local log_time=$(date "+%Y-%m-%d-%H-%M-%S") + local log_path="$dir_log/update/${log_time}_$p1.log" + local begin_time=$(date '+%Y-%m-%d %H:%M:%S') case $p1 in update) - update_qinglong "$2" | tee $log_path + echo -e "开始执行... $begin_time\n" >> $log_path + update_qinglong "$2" | tee -a $log_path ;; extra) + echo -e "开始执行... $begin_time\n" >> $log_path run_extra_shell | tee -a $log_path ;; repo) get_user_info local name=$(echo "${p2##*/}" | awk -F "." '{print $1}') log_path="$dir_log/update/${log_time}_$name.log" + echo -e "开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then - update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee $log_path + update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee -a $log_path else echo -e "命令输入错误...\n" usage @@ -416,27 +420,34 @@ main() { get_user_info local name=$(echo "${p2##*/}" | awk -F "." '{print $1}') log_path="$dir_log/update/${log_time}_$name.log" + echo -e "开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then - update_raw "$p2" | tee $log_path + update_raw "$p2" | tee -a $log_path else echo -e "命令输入错误...\n" usage fi ;; rmlog) - . $dir_shell/rmlog.sh "$p2" | tee $log_path + echo -e "开始执行... $begin_time\n" >> $log_path + . $dir_shell/rmlog.sh "$p2" | tee -a $log_path ;; bot) - . $dir_shell/bot.sh + echo -e "开始执行... $begin_time\n" >> $log_path + . $dir_shell/bot.sh | tee -a $log_path ;; reset) - . $dir_shell/reset.sh + echo -e "开始执行... $begin_time\n" >> $log_path + . $dir_shell/reset.sh | tee -a $log_path ;; *) echo -e "命令输入错误...\n" usage ;; esac + local end_time=$(date '+%Y-%m-%d %H:%M:%S') + local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) + echo -e "\n执行结束... $end_time 耗时 $diff_time 秒" >> $log_path } main "$@" diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 2cb32d7d..015a3e99 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -108,10 +108,15 @@ const CronLogModal = ({

Date: Fri, 25 Jun 2021 15:58:14 +0800
Subject: [PATCH 123/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E5=BF=97?=
 =?UTF-8?q?=E5=8F=82=E6=95=B0=E8=8E=B7=E5=8F=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 back/services/cron.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/back/services/cron.ts b/back/services/cron.ts
index f6d76865..b866a4ba 100644
--- a/back/services/cron.ts
+++ b/back/services/cron.ts
@@ -241,7 +241,7 @@ export default class CronService {
     const [, commandStr, url] = doc.command.split(' ');
     let logPath = this.getKey(commandStr);
     const isQlCommand = doc.command.startsWith('ql ');
-    const key = this.getKey(url) || logPath;
+    const key = (url && this.getKey(url)) || logPath;
     if (isQlCommand) {
       logPath = 'update';
     }

From f3aca5575c87de98df3e19179101e919ca1f7571 Mon Sep 17 00:00:00 2001
From: hanhh <18330117883@163.com>
Date: Fri, 25 Jun 2021 16:06:12 +0800
Subject: [PATCH 124/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E5=BF=97?=
 =?UTF-8?q?=E7=BB=93=E6=9D=9F=E6=A0=87=E8=AF=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 shell/task.sh   |  4 ++--
 shell/update.sh | 16 ++++++++--------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/shell/task.sh b/shell/task.sh
index 5a36604d..b16e778a 100755
--- a/shell/task.sh
+++ b/shell/task.sh
@@ -90,14 +90,14 @@ run_normal() {
 
     local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | xargs | sed 's/ /","/g')
     local begin_time=$(date '+%Y-%m-%d %H:%M:%S')
-    echo -e "开始执行... $begin_time\n" >> $log_path
+    echo -e "## 开始执行... $begin_time\n" >> $log_path
     update_cron_status "\"$id\"" "0"
     timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path
     . $file_task_after
     update_cron_status "\"$id\"" "1"
     local end_time=$(date '+%Y-%m-%d %H:%M:%S')
     local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time")))
-    echo -e "\n执行结束... $end_time  耗时 $diff_time 秒" >> $log_path
+    echo -e "\n## 执行结束... $end_time  耗时 $diff_time 秒" >> $log_path
 }
 
 ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行
diff --git a/shell/update.sh b/shell/update.sh
index cade8f08..d6a7f779 100755
--- a/shell/update.sh
+++ b/shell/update.sh
@@ -397,18 +397,18 @@ main() {
     local begin_time=$(date '+%Y-%m-%d %H:%M:%S')
     case $p1 in
     update)
-        echo -e "开始执行... $begin_time\n" >> $log_path
+        echo -e "## 开始执行... $begin_time\n" >> $log_path
         update_qinglong "$2" | tee -a $log_path
         ;;
     extra)
-        echo -e "开始执行... $begin_time\n" >> $log_path
+        echo -e "## 开始执行... $begin_time\n" >> $log_path
         run_extra_shell | tee -a $log_path
         ;;
     repo)
         get_user_info
         local name=$(echo "${p2##*/}" | awk -F "." '{print $1}')
         log_path="$dir_log/update/${log_time}_$name.log"
-        echo -e "开始执行... $begin_time\n" >> $log_path
+        echo -e "## 开始执行... $begin_time\n" >> $log_path
         if [[ -n $p2 ]]; then
             update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee -a $log_path
         else
@@ -420,7 +420,7 @@ main() {
         get_user_info
         local name=$(echo "${p2##*/}" | awk -F "." '{print $1}')
         log_path="$dir_log/update/${log_time}_$name.log"
-        echo -e "开始执行... $begin_time\n" >> $log_path
+        echo -e "## 开始执行... $begin_time\n" >> $log_path
         if [[ -n $p2 ]]; then
             update_raw "$p2" | tee -a $log_path
         else
@@ -429,15 +429,15 @@ main() {
         fi
         ;;
     rmlog)
-        echo -e "开始执行... $begin_time\n" >> $log_path
+        echo -e "## 开始执行... $begin_time\n" >> $log_path
         . $dir_shell/rmlog.sh "$p2" | tee -a $log_path
         ;;
     bot)
-        echo -e "开始执行... $begin_time\n" >> $log_path
+        echo -e "## 开始执行... $begin_time\n" >> $log_path
         . $dir_shell/bot.sh | tee -a $log_path
         ;;
     reset)
-        echo -e "开始执行... $begin_time\n" >> $log_path
+        echo -e "## 开始执行... $begin_time\n" >> $log_path
         . $dir_shell/reset.sh | tee -a $log_path
         ;;
     *)
@@ -447,7 +447,7 @@ main() {
     esac
     local end_time=$(date '+%Y-%m-%d %H:%M:%S')
     local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time")))
-    echo -e "\n执行结束... $end_time  耗时 $diff_time 秒" >> $log_path
+    echo -e "\n## 执行结束... $end_time  耗时 $diff_time 秒" >> $log_path
 }
 
 main "$@"

From 0753ef9ce932d0aa24f21388af532d829dd14cb2 Mon Sep 17 00:00:00 2001
From: hanhh <18330117883@163.com>
Date: Sat, 26 Jun 2021 15:56:15 +0800
Subject: [PATCH 125/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0Readme?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md                   | 38 ++++++++++++-------------------------
 src/pages/crontab/index.tsx |  2 +-
 2 files changed, 13 insertions(+), 27 deletions(-)

diff --git a/README.md b/README.md
index 938b850a..05bd42f8 100644
--- a/README.md
+++ b/README.md
@@ -8,25 +8,27 @@
 
 
-python和javaScript的定时任务管理面板 +Python 和 JavaScript 定时任务管理面板 -[![donate][donate-image]][donate-url] [![build status][build-status-image]][build-status-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker version][docker-version-image]][docker-version-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url] +[![docker version][docker-version-image]][docker-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url] [![donate][donate-image]][donate-url] -[donate-image]: https://img.shields.io/badge/donate-wechat-green?style=for-the-badge +[donate-image]: https://img.shields.io/badge/donate-wechat-green?style=flat [donate-url]: https://qinglong.whyour.cn/nice.png -[build-status-image]: https://img.shields.io/docker/cloud/build/whyour/qinglong?style=for-the-badge -[build-status-url]: https://img.shields.io/docker/cloud/build/whyour/qinglong -[docker-pulls-image]: https://img.shields.io/docker/pulls/whyour/qinglong?style=for-the-badge +[docker-pulls-image]: https://img.shields.io/docker/pulls/whyour/qinglong?style=flat [docker-pulls-url]: https://hub.docker.com/r/whyour/qinglong -[docker-version-image]: https://img.shields.io/docker/v/whyour/qinglong?style=for-the-badge +[docker-version-image]: https://img.shields.io/docker/v/whyour/qinglong?style=flat [docker-version-url]: https://hub.docker.com/r/whyour/qinglong/tags?page=1&ordering=last_updated -[docker-stars-image]: https://img.shields.io/docker/stars/whyour/qinglong?style=for-the-badge +[docker-stars-image]: https://img.shields.io/docker/stars/whyour/qinglong?style=flat [docker-stars-url]: https://hub.docker.com/r/whyour/qinglong -[docker-image-size-image]: https://img.shields.io/docker/image-size/whyour/qinglong?style=for-the-badge +[docker-image-size-image]: https://img.shields.io/docker/image-size/whyour/qinglong?style=flat [docker-image-size-url]: https://hub.docker.com/r/whyour/qinglong -
+

+ + +

+ 青龙,又名苍龙,在中国传统文化中是四象之一、[天之四灵](https://zh.wikipedia.org/wiki/%E5%A4%A9%E4%B9%8B%E5%9B%9B%E7%81%B5)之一,根据五行学说,它是代表东方的灵兽,为青色的龙,五行属木,代表的季节是春季,八卦主震。苍龙与应龙一样,都是身具羽翼。《张果星宗》称“又有辅翼,方为真龙”。 《后汉书·律历志下》记载:日周于天,一寒一暑,四时备成,万物毕改,摄提迁次,青龙移辰,谓之岁。 @@ -46,19 +48,3 @@ python和javaScript的定时任务管理面板 * [Umijs3.0](https://umijs.org) * [darkreader](https://github.com/darkreader/darkreader) - -## 免责声明 - -1. 此仓储脚本仅用于学习研究,不保证其合法性、准确性、有效性,请根据情况自行判断,本人对此不承担任何保证责任。 - -2. 由于此仓储脚本仅用于学习研究,您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。 - -3. 请勿将此仓储脚本用于任何商业或非法目的,若违反规定请自行对此负责。 - -4. 此仓储脚本涉及应用与本人无关,本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。 - -5. 本人对任何脚本引发的问题概不负责,包括但不限于由脚本错误引起的任何损失和损害。 - -6. 如果任何单位或个人认为此仓储脚本可能涉嫌侵犯其权利,应及时通知并提供身份证明,所有权证明,我们将在收到认证文件确认后删除此仓储脚本。 - -7. 所有直接或间接使用、查看此仓储脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此仓储脚本,即视为您已接受此免责声明。 diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 90203d18..f527d688 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -558,7 +558,7 @@ const Crontab = () => { onSearch={onSearch} />, , ]} header={{ From eb2390135ff787885edabf54911cdbcf357ceb03 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 26 Jun 2021 15:57:44 +0800 Subject: [PATCH 126/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0Readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 05bd42f8..5638a8b3 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ Python 和 JavaScript 定时任务管理面板

- - + +

青龙,又名苍龙,在中国传统文化中是四象之一、[天之四灵](https://zh.wikipedia.org/wiki/%E5%A4%A9%E4%B9%8B%E5%9B%9B%E7%81%B5)之一,根据五行学说,它是代表东方的灵兽,为青色的龙,五行属木,代表的季节是春季,八卦主震。苍龙与应龙一样,都是身具羽翼。《张果星宗》称“又有辅翼,方为真龙”。 From 0abf657a9cc74922a3a46e0ba380d9c4b9665baf Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 26 Jun 2021 16:00:19 +0800 Subject: [PATCH 127/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0Readme=E5=9B=BE?= =?UTF-8?q?=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5638a8b3..1fd29cb8 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ Python 和 JavaScript 定时任务管理面板

- - + +

青龙,又名苍龙,在中国传统文化中是四象之一、[天之四灵](https://zh.wikipedia.org/wiki/%E5%A4%A9%E4%B9%8B%E5%9B%9B%E7%81%B5)之一,根据五行学说,它是代表东方的灵兽,为青色的龙,五行属木,代表的季节是春季,八卦主震。苍龙与应龙一样,都是身具羽翼。《张果星宗》称“又有辅翼,方为真龙”。 From 49088f0d3ac900635b77aa15eb988f7dd33ea0ae Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 26 Jun 2021 20:27:25 +0800 Subject: [PATCH 128/247] =?UTF-8?q?=E8=BF=87=E6=BB=A4env=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/env.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/back/services/env.ts b/back/services/env.ts index e75553fa..a20ad249 100644 --- a/back/services/env.ts +++ b/back/services/env.ts @@ -218,7 +218,9 @@ export default class EnvService { for (const key in groups) { if (Object.prototype.hasOwnProperty.call(groups, key)) { const group = groups[key]; - env_string += `export ${key}="${_.map(group, 'value').join('&')}"\n`; + env_string += `export ${key}="${_.map(group, 'value') + .join('&') + .replaceAll(' ', '')}"\n`; } } fs.writeFileSync(config.envFile, env_string); From b78b382ba1376711f22f1d6d5a669b10cc6b7d39 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 26 Jun 2021 20:32:29 +0800 Subject: [PATCH 129/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8DreplaceAll=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/services/env.ts b/back/services/env.ts index a20ad249..a8e601e0 100644 --- a/back/services/env.ts +++ b/back/services/env.ts @@ -220,7 +220,7 @@ export default class EnvService { const group = groups[key]; env_string += `export ${key}="${_.map(group, 'value') .join('&') - .replaceAll(' ', '')}"\n`; + .replace(/ /g, '')}"\n`; } } fs.writeFileSync(config.envFile, env_string); From ecb035d0b4bf5f3a0e06bed73277cb7b59b583a8 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 26 Jun 2021 23:08:38 +0800 Subject: [PATCH 130/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=97=A5=E5=BF=97log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index b866a4ba..8adcfa5a 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -241,7 +241,9 @@ export default class CronService { const [, commandStr, url] = doc.command.split(' '); let logPath = this.getKey(commandStr); const isQlCommand = doc.command.startsWith('ql '); - const key = (url && this.getKey(url)) || logPath; + const key = + (url && ['repo', 'raw'].includes(commandStr) && this.getKey(url)) || + logPath; if (isQlCommand) { logPath = 'update'; } From 9f5c8fa70a51ead0c177491b0741c9468895ea8d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 26 Jun 2021 23:37:54 +0800 Subject: [PATCH 131/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/env/index.tsx | 4 ++-- src/pages/env/modal.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 753d92f8..99f227e6 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -303,7 +303,7 @@ const Env = () => { const handleCancel = (env?: any[]) => { setIsModalVisible(false); - handleEnv(env); + env && handleEnv(env); }; const handleEditNameCancel = (env?: any[]) => { @@ -445,7 +445,7 @@ const Env = () => { onSearch={onSearch} />, , ]} header={{ diff --git a/src/pages/env/modal.tsx b/src/pages/env/modal.tsx index 6c623bf5..86003855 100644 --- a/src/pages/env/modal.tsx +++ b/src/pages/env/modal.tsx @@ -23,7 +23,7 @@ const EnvModal = ({ data: payload, }); if (code === 200) { - message.success(env ? '更新Env成功' : '添加Env成功'); + message.success(env ? '更新变量成功' : '添加变量成功'); } else { message.error(data); } @@ -37,7 +37,7 @@ const EnvModal = ({ return ( { From 0a6c7e371973ae8d7be078e28ca3fffe77a075ca Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 27 Jun 2021 00:19:48 +0800 Subject: [PATCH 132/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BC=B9=E5=87=BA?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=8D=E9=87=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 10 ++++++++++ src/pages/crontab/modal.tsx | 16 ++++++++-------- src/pages/env/editNameModal.tsx | 10 ++-------- src/pages/env/index.tsx | 6 +++--- src/pages/env/modal.tsx | 11 ++--------- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index 1804cb2a..f276b33e 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -60,6 +60,16 @@ body { } } +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +input:-webkit-autofill:active { + transition-delay: 99999s; + transition: color 99999s ease-out, background-color 99999s ease-out; + -webkit-transition-delay: 99999s; + -webkit-transition: color 99999s ease-out, background-color 99999s ease-out; +} + @media (max-width: 768px) { .ant-pro-grid-content.wide { .ant-pro-page-container-children-content { diff --git a/src/pages/crontab/modal.tsx b/src/pages/crontab/modal.tsx index f365ee3e..38146192 100644 --- a/src/pages/crontab/modal.tsx +++ b/src/pages/crontab/modal.tsx @@ -36,12 +36,8 @@ const CronModal = ({ }; useEffect(() => { - if (cron) { - form.setFieldsValue(cron); - } else { - form.resetFields(); - } - }, [cron]); + form.resetFields(); + }, [cron, visible]); return ( handleCancel()} confirmLoading={loading} - destroyOnClose > -
+ diff --git a/src/pages/env/editNameModal.tsx b/src/pages/env/editNameModal.tsx index 4e0c7e08..b13a3a09 100644 --- a/src/pages/env/editNameModal.tsx +++ b/src/pages/env/editNameModal.tsx @@ -34,7 +34,7 @@ const EditNameModal = ({ useEffect(() => { form.resetFields(); - }, [ids]); + }, [ids, visible]); return ( handleCancel()} confirmLoading={loading} - destroyOnClose > - + { title: '确认删除', content: ( <> - 确认删除Env{' '} + 确认删除变量{' '} {record.value} {' '} @@ -365,7 +365,7 @@ const Env = () => { const delEnvs = () => { Modal.confirm({ title: '确认删除', - content: <>确认删除选中的Env吗, + content: <>确认删除选中的变量吗, onOk() { request .delete(`${config.apiPrefix}envs`, { data: selectedRowIds }) @@ -388,7 +388,7 @@ const Env = () => { const operateEnvs = (operationStatus: number) => { Modal.confirm({ title: `确认${OperationName[operationStatus]}`, - content: <>确认{OperationName[operationStatus]}选中的Env吗, + content: <>确认{OperationName[operationStatus]}选中的变量吗, onOk() { request .put(`${config.apiPrefix}envs/${OperationPath[operationStatus]}`, { diff --git a/src/pages/env/modal.tsx b/src/pages/env/modal.tsx index 86003855..f0a5ff6c 100644 --- a/src/pages/env/modal.tsx +++ b/src/pages/env/modal.tsx @@ -33,7 +33,7 @@ const EnvModal = ({ useEffect(() => { form.resetFields(); - }, [env]); + }, [env, visible]); return ( handleCancel()} confirmLoading={loading} - destroyOnClose > - + Date: Sun, 27 Jun 2021 17:23:13 +0800 Subject: [PATCH 133/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E9=AB=98=E4=BA=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .umirc.ts | 6 ++++-- src/layouts/index.tsx | 1 - src/pages/config/index.tsx | 1 + src/pages/log/index.tsx | 1 - src/pages/script/index.tsx | 30 ++++++++++++++++++++---------- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/.umirc.ts b/.umirc.ts index 94e49782..976e87d6 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -34,8 +34,10 @@ export default defineConfig({ scripts: [ 'https://gw.alipayobjects.com/os/lib/react/16.13.1/umd/react.production.min.js', 'https://gw.alipayobjects.com/os/lib/react-dom/16.13.1/umd/react-dom.production.min.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.60.0/lib/codemirror.min.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/lib/codemirror.min.js', 'https://cdn.jsdelivr.net/npm/darkreader@4.9.27/darkreader.min.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.60.0/mode/shell/shell.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/shell/shell.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/python/python.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/javascript/javascript.js', ], }); diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 116cea28..1717dbd2 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -10,7 +10,6 @@ import defaultProps from './defaultProps'; import { Link, history } from 'umi'; import { LogoutOutlined } from '@ant-design/icons'; import config from '@/utils/config'; -import 'codemirror/mode/shell/shell.js'; import { request } from '@/utils/http'; import './index.less'; import vhCheck from 'vh-check'; diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 438438da..34fb9215 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -65,6 +65,7 @@ const Config = () => { { lineWrapping: true, styleActiveLine: true, matchBrackets: true, - mode: 'shell', readOnly: true, }} onBeforeChange={(editor, data, value) => { diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 8d84a0a4..ca419f83 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -19,6 +19,12 @@ function getFilterData(keyword: string, data: any) { return { tree: data }; } +const LangMap: any = { + '.py': 'python', + '.js': 'javascript', + '.sh': 'shell', +}; + const Script = () => { const [width, setWidth] = useState('100%'); const [marginLeft, setMarginLeft] = useState(0); @@ -30,25 +36,28 @@ const Script = () => { const [filterData, setFilterData] = useState([]); const [loading, setLoading] = useState(false); const [isPhone, setIsPhone] = useState(false); + const [mode, setMode] = useState(''); const getScripts = () => { - request.get(`${config.apiPrefix}scripts/files`).then((data) => { - setData(data.data); - setFilterData(data.data); - }); - }; - - const getDetail = (node: any) => { setLoading(true); request - .get(`${config.apiPrefix}scripts/${node.value}`) + .get(`${config.apiPrefix}scripts/files`) .then((data) => { - setValue(data.data); + setData(data.data); + setFilterData(data.data); }) .finally(() => setLoading(false)); }; + const getDetail = (node: any) => { + request.get(`${config.apiPrefix}scripts/${node.value}`).then((data) => { + setValue(data.data); + }); + }; + const onSelect = (value: any, node: any) => { + const newMode = LangMap[value.slice(-3)] || ''; + setMode(newMode); setSelect(value); setTitle(node.parent || node.value); getDetail(node); @@ -86,6 +95,7 @@ const Script = () => { { lineWrapping: true, styleActiveLine: true, matchBrackets: true, - mode: 'shell', + mode, readOnly: true, }} onBeforeChange={(editor, data, value) => { From c77eb3d28d9153edd6f26e3b4b206d6e9ce551f7 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 29 Jun 2021 00:05:37 +0800 Subject: [PATCH 134/247] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ql=20check=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E7=8E=AF=E5=A2=83=E7=9B=91=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 8 +-- shell/check.sh | 110 ++++++++++++++++++++++++++++++++++++ shell/reset.sh | 30 ---------- shell/share.sh | 1 - shell/task.sh | 8 +-- shell/update.sh | 14 ++--- 6 files changed, 124 insertions(+), 47 deletions(-) create mode 100644 shell/check.sh delete mode 100644 shell/reset.sh diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index c7c73e49..8f223ef8 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -20,17 +20,17 @@ echo -e "nginx启动成功...\n" echo -e "======================4. 启动控制面板========================\n" if [[ $(pm2 info panel 2>/dev/null) ]]; then - pm2 reload panel + pm2 reload panel --source-map-support --time else - pm2 start $dir_root/build/app.js -n panel + pm2 start $dir_root/build/app.js -n panel --source-map-support --time fi echo -e "控制面板启动成功...\n" echo -e "======================5. 启动定时任务========================\n" if [[ $(pm2 info schedule 2>/dev/null) ]]; then - pm2 reload schedule + pm2 reload schedule --source-map-support --time else - pm2 start $dir_root/build/schedule.js -n schedule + pm2 start $dir_root/build/schedule.js -n schedule --source-map-support --time fi echo -e "定时任务启动成功...\n" diff --git a/shell/check.sh b/shell/check.sh new file mode 100644 index 00000000..0847c902 --- /dev/null +++ b/shell/check.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bash + +dir_shell=/ql/shell +. $dir_shell/share.sh +. $dir_shell/api.sh +get_token + +panelLogPath="/root/.pm2/logs/panel-error.log" + +reset_env() { + echo -e "---> 1. 开始检测配置文件\n" + fix_config + echo -e "---> 配置文件检测完成\n" + + echo -e "---> 2. 开始安装青龙依赖\n" + npm_install_2 $dir_root + echo -e "---> 青龙依赖安装完成\n" + + echo -e "---> 3. 开始安装脚本依赖\n" + cp -f $dir_sample/package.json $dir_scripts/package.json + npm_install_2 $dir_scripts + echo -e "---> 脚本依赖安装完成\n" + + echo -e "---> 4. 复制通知文件\n" + echo -e "---> 复制一份 $file_notify_py_sample 为 $file_notify_py\n" + cp -fv $file_notify_py_sample $file_notify_py + echo + echo -e "---> 复制一份 $file_notify_js_sample 为 $file_notify_js\n" + cp -fv $file_notify_js_sample $file_notify_js + echo -e "---> 通知文件复制完成\n" +} + +reload_pm2() { + pm2 l >/dev/null 2>&1 + + if [[ $(pm2 info panel 2>/dev/null) ]]; then + pm2 reload panel --source-map-support --time >/dev/null 2>&1 + else + pm2 start $dir_root/build/app.js -n panel --source-map-support --time >/dev/null 2>&1 + fi + + if [[ $(pm2 info schedule 2>/dev/null) ]]; then + pm2 reload schedule --source-map-support --time >/dev/null 2>&1 + else + pm2 start $dir_root/build/schedule.js -n schedule --source-map-support --time >/dev/null 2>&1 + fi +} + +pm2_log() { + echo -e "---> pm2日志" + local panelOut="/root/.pm2/logs/panel-out.log" + local panelError="/root/.pm2/logs/panel-error.log" + tail -n 10 "$panelOut" + tail -n 10 "$panelError" +} + +check_nginx() { + local nginxPid=$(ps -ef | grep nginx | grep -v grep) + echo -e "---> nginx服务\n$nginxPid" + if [[ $nginxPid ]]; then + echo -e "\n=====> nginx服务正常\n" + else + echo -e "\n=====> nginx服务异常,重新启动nginx\n" + nginx -c /etc/nginx/nginx.conf + fi +} + +check_ql() { + local api=$(curl -s "http://localhost:5700") + echo -e "\n=====> 检测面板\n\n$api\n" + if [[ $api =~ "
" ]]; then + echo -e "=====> 面板服务启动正常\n" + check_nginx + else + echo -e "=====> 面板服务异常,重置基础环境\n" + reset_env + fi +} + +check_pm2() { + pm2_log + local currentTimeStamp=$(date +%s) + local api=$( + curl -s "http://localhost:5600/api/user?t=$currentTimeStamp" \ + -H 'Accept: */*' \ + -H "Authorization: Bearer $token" \ + -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36' \ + -H 'Referer: http://localhost:5700/crontab' \ + -H 'Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7' \ + --compressed + ) + echo -e "\n=====> 检测后台\n\n$api\n" + if [[ $api =~ "{\"code\"" ]]; then + echo -e "=====> 后台服务启动正常\n" + else + echo -e "=====> 后台服务异常,重启后台\n" + reload_pm2 + fi +} + +main() { + echo -e "=====> 开始检测" + check_ql + check_pm2 + echo -e "\n=====> 检测结束\n" +} + +main + +exit diff --git a/shell/reset.sh b/shell/reset.sh deleted file mode 100644 index 376c7225..00000000 --- a/shell/reset.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash - -# 导入通用变量与函数 -dir_shell=/ql/shell -. $dir_shell/share.sh - -echo -e "1. 开始检测配置文件\n" -fix_config -echo -e "配置文件检测完成\n" - -echo -e "2. 开始安装青龙依赖\n" -npm_install_2 $dir_root -echo -e "青龙依赖安装完成\n" - -echo -e "3. 开始安装脚本依赖\n" -cp -f $dir_sample/package.json $dir_scripts/package.json -npm_install_2 $dir_scripts -echo -e "脚本依赖安装完成\n" - -echo -e "4. 复制通知文件\n" -echo -e "复制一份 $file_notify_py_sample 为 $file_notify_py\n" -cp -fv $file_notify_py_sample $file_notify_py -echo - -echo -e "复制一份 $file_notify_js_sample 为 $file_notify_js\n" -cp -fv $file_notify_js_sample $file_notify_js - -echo -e "通知文件复制完成\n" - -exit 0 diff --git a/shell/share.sh b/shell/share.sh index 23b7482f..7a9e51cd 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -213,7 +213,6 @@ npm_install_sub() { elif ! type pnpm >/dev/null 2>&1; then npm install --production --no-save --registry=https://registry.npm.taobao.org || npm install --production --no-save else - echo -e "检测到本机安装了 pnpm,使用 pnpm 替代 ...\n" pnpm install --prod fi } diff --git a/shell/task.sh b/shell/task.sh index b16e778a..70d44bdd 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -90,14 +90,14 @@ run_normal() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | xargs | sed 's/ /","/g') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" >> $log_path - update_cron_status "\"$id\"" "0" + echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + [[ $id ]] && update_cron_status "\"$id\"" "0" timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path . $file_task_after - update_cron_status "\"$id\"" "1" + [[ $id ]] && update_cron_status "\"$id\"" "1" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" >> $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path } ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行 diff --git a/shell/update.sh b/shell/update.sh index d6a7f779..073ca4f4 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -242,8 +242,6 @@ update_qinglong() { echo fi - fix_config - [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" git_pull_scripts $dir_root @@ -295,15 +293,15 @@ reload_pm2() { pm2 l >/dev/null 2>&1 if [[ $(pm2 info panel 2>/dev/null) ]]; then - pm2 reload panel >/dev/null 2>&1 + pm2 reload panel --source-map-support --time >/dev/null 2>&1 else - pm2 start $dir_root/build/app.js -n panel >/dev/null 2>&1 + pm2 start $dir_root/build/app.js -n panel --source-map-support --time >/dev/null 2>&1 fi if [[ $(pm2 info schedule 2>/dev/null) ]]; then - pm2 reload schedule >/dev/null 2>&1 + pm2 reload schedule --source-map-support --time >/dev/null 2>&1 else - pm2 start $dir_root/build/schedule.js -n schedule >/dev/null 2>&1 + pm2 start $dir_root/build/schedule.js -n schedule --source-map-support --time >/dev/null 2>&1 fi } @@ -436,9 +434,9 @@ main() { echo -e "## 开始执行... $begin_time\n" >> $log_path . $dir_shell/bot.sh | tee -a $log_path ;; - reset) + check) echo -e "## 开始执行... $begin_time\n" >> $log_path - . $dir_shell/reset.sh | tee -a $log_path + . $dir_shell/check.sh | tee -a $log_path ;; *) echo -e "命令输入错误...\n" From 2f8d31658b3f9ffe288c860b080d797d825d38f9 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 29 Jun 2021 00:05:52 +0800 Subject: [PATCH 135/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index e6a656a3..3c6c5762 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-061'; -export const changeLog = 'https://t.me/jiaolongwang/111'; +export const version = 'v2.8.0-062'; +export const changeLog = 'https://t.me/jiaolongwang/112'; From 6c3f848b2c2fd064a988663cb29b8bf5df75df50 Mon Sep 17 00:00:00 2001 From: Xinglin Qiang Date: Tue, 29 Jun 2021 10:48:01 +0800 Subject: [PATCH 136/247] =?UTF-8?q?=E5=85=BC=E5=AE=B9=E4=BD=BF=E7=94=A8for?= =?UTF-8?q?ce=20update=E7=9A=84repo=20(#341)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker/Dockerfile b/docker/Dockerfile index 599379c2..3d25a854 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -30,6 +30,9 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && touch ~/.bashrc \ && mkdir /run/nginx \ && git clone -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} \ + && git config --global user.email "qinglong@@users.noreply.github.com" \ + && git config --global user.name "qinglong" \ + && git config --global pull.rebase true \ && cd ${QL_DIR} \ && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ From 2049cf9aa986c1ea00e94c99da1524e1d65d6bf2 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 29 Jun 2021 10:51:27 +0800 Subject: [PATCH 137/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ql=20check=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/check.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/shell/check.sh b/shell/check.sh index 0847c902..e830fd31 100644 --- a/shell/check.sh +++ b/shell/check.sh @@ -5,8 +5,6 @@ dir_shell=/ql/shell . $dir_shell/api.sh get_token -panelLogPath="/root/.pm2/logs/panel-error.log" - reset_env() { echo -e "---> 1. 开始检测配置文件\n" fix_config @@ -50,8 +48,8 @@ pm2_log() { echo -e "---> pm2日志" local panelOut="/root/.pm2/logs/panel-out.log" local panelError="/root/.pm2/logs/panel-error.log" - tail -n 10 "$panelOut" - tail -n 10 "$panelError" + tail -n 20 "$panelOut" + tail -n 20 "$panelError" } check_nginx() { @@ -98,8 +96,20 @@ check_pm2() { fi } +init_git() { + local dir_current=$(pwd) + + cd $dir_root + git config --global user.email "qinglong@@users.noreply.github.com" + git config --global user.name "qinglong" + git config --global pull.rebase true + + cd $dir_current +} + main() { echo -e "=====> 开始检测" + init_git check_ql check_pm2 echo -e "\n=====> 检测结束\n" From b1bee910b2a000b994004fb928b7d819b343f3f0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 29 Jun 2021 12:06:15 +0800 Subject: [PATCH 138/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20check=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/check.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/check.sh b/shell/check.sh index e830fd31..995b5b54 100644 --- a/shell/check.sh +++ b/shell/check.sh @@ -91,8 +91,8 @@ check_pm2() { if [[ $api =~ "{\"code\"" ]]; then echo -e "=====> 后台服务启动正常\n" else - echo -e "=====> 后台服务异常,重启后台\n" - reload_pm2 + echo -e "=====> 后台服务异常,重置基础环境并重启后台\n" + reset_env fi } @@ -112,6 +112,7 @@ main() { init_git check_ql check_pm2 + reload_pm2 echo -e "\n=====> 检测结束\n" } From e7aff6d1d6bc5475298c511d7690e9df0ac94f64 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 12:16:05 +0800 Subject: [PATCH 139/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtoken=E5=94=AF?= =?UTF-8?q?=E4=B8=80=E6=80=A7=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/auth.ts | 6 +++--- back/config/index.ts | 3 ++- back/config/util.ts | 2 +- back/loaders/express.ts | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/back/api/auth.ts b/back/api/auth.ts index 7bcd3a6e..329d4340 100644 --- a/back/api/auth.ts +++ b/back/api/auth.ts @@ -4,7 +4,7 @@ import { Logger } from 'winston'; import * as fs from 'fs'; import config from '../config'; import jwt from 'jsonwebtoken'; -import { createPassword } from '../config/util'; +import { createRandomString } from '../config/util'; import crypto from 'crypto'; const route = Router(); @@ -25,7 +25,7 @@ export default (app: Router) => { authInfo.username === 'admin' && authInfo.password === 'adminadmin' ) { - const newPassword = createPassword(16, 22); + const newPassword = createRandomString(16, 22); fs.writeFileSync( config.authConfigFile, JSON.stringify({ @@ -42,7 +42,7 @@ export default (app: Router) => { username == authInfo.username && password == authInfo.password ) { - const data = createPassword(50, 100); + const data = createRandomString(50, 100); let token = jwt.sign({ data }, config.secret as any, { expiresIn: 60 * 60 * 24 * 3, algorithm: 'HS384', diff --git a/back/config/index.ts b/back/config/index.ts index af297c63..44053157 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -1,5 +1,6 @@ import dotenv from 'dotenv'; import path from 'path'; +import { createRandomString } from './util'; process.env.NODE_ENV = process.env.NODE_ENV || 'development'; @@ -34,7 +35,7 @@ if (configFound.error) { export default { port: parseInt(process.env.PORT as string, 10), cronPort: parseInt(process.env.CRON_PORT as string, 10), - secret: process.env.SECRET, + secret: process.env.SECRET || createRandomString(16, 32), logs: { level: process.env.LOG_LEVEL || 'silly', }, diff --git a/back/config/util.ts b/back/config/util.ts index bc87ee91..e8cc5b46 100644 --- a/back/config/util.ts +++ b/back/config/util.ts @@ -27,7 +27,7 @@ export function getLastModifyFilePath(dir: string) { return filePath; } -export function createPassword(min: number, max: number): string { +export function createRandomString(min: number, max: number): string { const num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; const english = [ 'a', diff --git a/back/loaders/express.ts b/back/loaders/express.ts index 35b16192..d5cd316a 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -18,7 +18,7 @@ export default ({ app }: { app: Application }) => { }), ); app.use((req, res, next) => { - if (req.url && req.url.includes('/api/login')) { + if (req.url && req.path.includes('/api/login')) { return next(); } const data = fs.readFileSync(config.authConfigFile, 'utf8'); From ef16622a7eaff82a3d68faab9fd345a366662d7f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 12:16:40 +0800 Subject: [PATCH 140/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 3c6c5762..744014b5 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-062'; -export const changeLog = 'https://t.me/jiaolongwang/112'; +export const version = 'v2.8.0-063'; +export const changeLog = 'https://t.me/jiaolongwang/113'; From 0c3b3c206efeab981d2a4e24eba2115044098329 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 12:20:42 +0800 Subject: [PATCH 141/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtoken=E9=AA=8C?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/config/util.ts | 8 ++++++++ back/loaders/express.ts | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/back/config/util.ts b/back/config/util.ts index e8cc5b46..6d747449 100644 --- a/back/config/util.ts +++ b/back/config/util.ts @@ -111,3 +111,11 @@ export function createRandomString(min: number, max: number): string { return newArr.join(''); } + +export function getToken(req: any) { + const { authorization } = req.headers; + if (authorization && authorization.split(' ')[0] === 'Bearer') { + return authorization.split(' ')[1]; + } + return ''; +} diff --git a/back/loaders/express.ts b/back/loaders/express.ts index d5cd316a..fc882bce 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -5,6 +5,7 @@ import routes from '../api'; import config from '../config'; import jwt from 'express-jwt'; import fs from 'fs'; +import { getToken } from '../config/util'; export default ({ app }: { app: Application }) => { app.enable('trust proxy'); @@ -22,10 +23,10 @@ export default ({ app }: { app: Application }) => { return next(); } const data = fs.readFileSync(config.authConfigFile, 'utf8'); - const authHeader = req.headers.authorization; + const headerToken = getToken(req); if (data) { const { token } = JSON.parse(data); - if (token && authHeader.includes(token)) { + if (token && headerToken === token) { return next(); } } From ebcf8f96c8324e4b8901de7dc7049f9282090cf9 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 12:26:54 +0800 Subject: [PATCH 142/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtoken=E9=AA=8C?= =?UTF-8?q?=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/express.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/back/loaders/express.ts b/back/loaders/express.ts index fc882bce..bd47572c 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -19,9 +19,6 @@ export default ({ app }: { app: Application }) => { }), ); app.use((req, res, next) => { - if (req.url && req.path.includes('/api/login')) { - return next(); - } const data = fs.readFileSync(config.authConfigFile, 'utf8'); const headerToken = getToken(req); if (data) { @@ -30,6 +27,9 @@ export default ({ app }: { app: Application }) => { return next(); } } + if (!headerToken && req.url && req.path === '/api/login') { + return next(); + } const err: any = new Error('UnauthorizedError'); err['status'] = 401; next(err); From 5b7621335436d644f1b6ce8ebcb85935f542a874 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 22:38:19 +0800 Subject: [PATCH 143/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcheck=E5=91=BD?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/check.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/check.sh b/shell/check.sh index 995b5b54..7e75b57d 100644 --- a/shell/check.sh +++ b/shell/check.sh @@ -54,7 +54,7 @@ pm2_log() { check_nginx() { local nginxPid=$(ps -ef | grep nginx | grep -v grep) - echo -e "---> nginx服务\n$nginxPid" + echo -e "=====> 检测nginx服务\n$nginxPid" if [[ $nginxPid ]]; then echo -e "\n=====> nginx服务正常\n" else @@ -68,7 +68,6 @@ check_ql() { echo -e "\n=====> 检测面板\n\n$api\n" if [[ $api =~ "
" ]]; then echo -e "=====> 面板服务启动正常\n" - check_nginx else echo -e "=====> 面板服务异常,重置基础环境\n" reset_env @@ -111,6 +110,7 @@ main() { echo -e "=====> 开始检测" init_git check_ql + check_nginx check_pm2 reload_pm2 echo -e "\n=====> 检测结束\n" From 2a1adb2e0ececb9ce322e4753bd963248ce4f122 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 23:02:22 +0800 Subject: [PATCH 144/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0action=20yml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 2 +- .github/workflows/docker.yml | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 1a4d9bf8..79fa51e1 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -1,4 +1,4 @@ -name: build static +name: Build Static on: push: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 517507a9..1464ced1 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,8 +1,9 @@ name: Publish Docker Image on: push: - tags: + branches: - v* + - master jobs: build: @@ -14,10 +15,8 @@ jobs: with: fetch-depth: 0 - # https://github.com/docker/setup-qemu-action - name: Set up QEMU uses: docker/setup-qemu-action@v1 - # https://github.com/docker/setup-buildx-action - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 @@ -35,19 +34,19 @@ jobs: run: | docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ - - name: Replace tag without `v` - if: startsWith(github.ref, 'refs/tags/') + - name: Replace branch without `v` + if: startsWith(github.ref, 'refs/heads/') uses: actions/github-script@v1 id: version with: script: | - return context.payload.ref.replace(/\/?refs\/tags\/v/, '') + return context.payload.ref.replace(/\/?refs\/heads\/v/, '') result-encoding: string - name: Docker buildx image and push on release env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - if: startsWith(github.ref, 'refs/tags/') + if: startsWith(github.ref, 'refs/heads/') run: | docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:${{steps.version.outputs.result}} docker/ docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ From 2fe8c382935bc5161c59a3db2d7b0507a3fecf19 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 23:38:46 +0800 Subject: [PATCH 145/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=95=9C=E5=83=8F?= =?UTF-8?q?=E6=89=93=E5=8C=85=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 3 +-- back/services/env.ts | 2 +- docker/Dockerfile | 5 +++++ docker/docker-entrypoint.sh | 17 +++++++++-------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 1464ced1..dd661c43 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -46,7 +46,6 @@ jobs: - name: Docker buildx image and push on release env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - if: startsWith(github.ref, 'refs/heads/') + if: startsWith(github.ref, 'refs/heads/') && github.ref != 'refs/heads/master' run: | docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:${{steps.version.outputs.result}} docker/ - docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ diff --git a/back/services/env.ts b/back/services/env.ts index a8e601e0..98f40638 100644 --- a/back/services/env.ts +++ b/back/services/env.ts @@ -19,7 +19,7 @@ export default class EnvService { public async create(payload: Env): Promise { const envs = await this.envs(); let position = initEnvPosition; - if (envs && envs.length > 0) { + if (envs && envs.length > 0 && envs[envs.length - 1].position) { position = envs[envs.length - 1].position; } const tab = new Env({ ...payload, position: position / 2 }); diff --git a/docker/Dockerfile b/docker/Dockerfile index 3d25a854..046c1ded 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -37,6 +37,11 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ && chmod 777 ${QL_DIR}/docker/*.sh \ + && yarn install \ + && yarn build \ + && yarn build-back \ + && yarn cache clean \ + && rm -rf node_modules \ && npm install -g pm2 \ && npm install -g pnpm \ && rm -rf /root/.npm \ diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 8f223ef8..478b71bf 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -7,18 +7,14 @@ link_shell echo -e "======================1. 检测配置文件========================\n" fix_config cp -fv $dir_root/docker/front.conf /etc/nginx/conf.d/front.conf -echo - -echo -e "======================2. 更新源代码========================\n" -ql update "no-restart" pm2 l >/dev/null 2>&1 echo -echo -e "======================3. 启动nginx========================\n" +echo -e "======================2. 启动nginx========================\n" nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf echo -e "nginx启动成功...\n" -echo -e "======================4. 启动控制面板========================\n" +echo -e "======================3. 启动控制面板========================\n" if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel --source-map-support --time else @@ -26,7 +22,7 @@ else fi echo -e "控制面板启动成功...\n" -echo -e "======================5. 启动定时任务========================\n" +echo -e "======================4. 启动定时任务========================\n" if [[ $(pm2 info schedule 2>/dev/null) ]]; then pm2 reload schedule --source-map-support --time else @@ -35,10 +31,15 @@ fi echo -e "定时任务启动成功...\n" if [[ $AutoStartBot == true ]]; then - echo -e "======================6. 启动bot========================\n" + echo -e "======================5. 启动bot========================\n" ql bot fi +if [[ $EnableExtraShell == true ]]; then + echo -e "======================6. 执行自定义脚本========================\n" + ql extra +fi + echo -e "############################################################\n" echo -e "容器启动成功..." echo -e "\n请先访问5700端口,登录成功面板之后再执行添加定时任务..." From 1aaa0f0fa6d9f392d1a13454fee9eba03fcb99cf Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 30 Jun 2021 23:52:39 +0800 Subject: [PATCH 146/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddocker=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index dd661c43..08714198 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -35,7 +35,7 @@ jobs: docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ - name: Replace branch without `v` - if: startsWith(github.ref, 'refs/heads/') + if: startsWith(github.ref, 'refs/heads/') && github.ref != 'refs/heads/master' uses: actions/github-script@v1 id: version with: From a35c0cb64eb334107d7f0b5c578828029bec6838 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 1 Jul 2021 00:12:32 +0800 Subject: [PATCH 147/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 046c1ded..36e814b8 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -37,7 +37,7 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ && chmod 777 ${QL_DIR}/docker/*.sh \ - && yarn install \ + && yarn install --network-timeout 100000 \ && yarn build \ && yarn build-back \ && yarn cache clean \ From 7d417a11c9b4093b9cfd2d9d125192cda5ad7155 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 1 Jul 2021 00:38:33 +0800 Subject: [PATCH 148/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 7 +-- pnpm-lock.yaml | 146 ++++++---------------------------------------- 2 files changed, 21 insertions(+), 132 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 36e814b8..c9f15b61 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -37,10 +37,9 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ && chmod 777 ${QL_DIR}/docker/*.sh \ - && yarn install --network-timeout 100000 \ - && yarn build \ - && yarn build-back \ - && yarn cache clean \ + && pnpm install \ + && pnpm build \ + && pnpm build-back \ && rm -rf node_modules \ && npm install -g pm2 \ && npm install -g pnpm \ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8559c4c..89bf8207 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ specifiers: '@types/express': ^4.17.8 '@types/express-jwt': ^6.0.1 '@types/jsonwebtoken': ^8.5.0 + '@types/lodash': ^4.14.170 '@types/nedb': ^1.8.11 '@types/node': ^14.11.2 '@types/node-fetch': ^2.5.8 @@ -25,9 +26,9 @@ specifiers: dotenv: ^8.2.0 express: ^4.17.1 express-jwt: ^6.0.0 - got: ^11.8.2 jsonwebtoken: ^8.5.1 lint-staged: ^10.0.7 + lodash: ^4.17.21 nedb: ^1.8.0 node-fetch: ^2.6.1 node-schedule: ^2.0.0 @@ -60,8 +61,8 @@ dependencies: dotenv: 8.6.0 express: 4.17.1 express-jwt: 6.0.0 - got: 11.8.2 jsonwebtoken: 8.5.1 + lodash: 4.17.21 nedb: 1.8.0 node-fetch: 2.6.1 node-schedule: 2.0.0 @@ -77,6 +78,7 @@ devDependencies: '@types/express': 4.17.11 '@types/express-jwt': 6.0.1 '@types/jsonwebtoken': 8.5.1 + '@types/lodash': 4.14.170 '@types/nedb': 1.8.11 '@types/node': 14.14.45 '@types/node-fetch': 2.5.10 @@ -907,11 +909,6 @@ packages: engines: {node: '>=6'} dev: true - /@sindresorhus/is/4.0.1: - resolution: {integrity: sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==} - engines: {node: '>=10'} - dev: false - /@sinonjs/commons/1.8.3: resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==} dependencies: @@ -931,13 +928,6 @@ packages: defer-to-connect: 1.1.3 dev: true - /@szmarczak/http-timer/4.0.5: - resolution: {integrity: sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==} - engines: {node: '>=10'} - dependencies: - defer-to-connect: 2.0.1 - dev: false - /@types/babel__core/7.1.14: resolution: {integrity: sha512-zGZJzzBUVDo/eV6KgbE0f0ZI7dInEYvo12Rb70uNQDshC3SkRMb67ja0GgRHZgAX3Za6rhaWlvbDO8rrGyAb1g==} dependencies: @@ -974,15 +964,6 @@ packages: '@types/node': 14.14.45 dev: true - /@types/cacheable-request/6.0.1: - resolution: {integrity: sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==} - dependencies: - '@types/http-cache-semantics': 4.0.0 - '@types/keyv': 3.1.1 - '@types/node': 14.14.45 - '@types/responselike': 1.0.0 - dev: false - /@types/connect/3.4.34: resolution: {integrity: sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==} dependencies: @@ -1051,10 +1032,6 @@ packages: resolution: {integrity: sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==} dev: true - /@types/http-cache-semantics/4.0.0: - resolution: {integrity: sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==} - dev: false - /@types/istanbul-lib-coverage/2.0.3: resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==} dev: true @@ -1088,11 +1065,9 @@ packages: '@types/node': 14.14.45 dev: true - /@types/keyv/3.1.1: - resolution: {integrity: sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==} - dependencies: - '@types/node': 14.14.45 - dev: false + /@types/lodash/4.14.170: + resolution: {integrity: sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==} + dev: true /@types/mime/1.3.2: resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} @@ -1113,6 +1088,7 @@ packages: /@types/node/14.14.45: resolution: {integrity: sha512-DssMqTV9UnnoxDWu959sDLZzfvqCF0qDNRjaWeYSui9xkFe61kKo4l1TWNTQONpuXEm+gLMRvdlzvNHBamzmEw==} + dev: true /@types/normalize-package-data/2.4.0: resolution: {integrity: sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==} @@ -1202,12 +1178,6 @@ packages: csstype: 3.0.8 dev: true - /@types/responselike/1.0.0: - resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} - dependencies: - '@types/node': 14.14.45 - dev: false - /@types/scheduler/0.16.1: resolution: {integrity: sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==} dev: true @@ -2359,11 +2329,6 @@ packages: unset-value: 1.0.0 dev: true - /cacheable-lookup/5.0.4: - resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} - engines: {node: '>=10.6.0'} - dev: false - /cacheable-request/6.1.0: resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} engines: {node: '>=8'} @@ -2377,19 +2342,6 @@ packages: responselike: 1.0.2 dev: true - /cacheable-request/7.0.1: - resolution: {integrity: sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==} - engines: {node: '>=8'} - dependencies: - clone-response: 1.0.2 - get-stream: 5.2.0 - http-cache-semantics: 4.1.0 - keyv: 4.0.3 - lowercase-keys: 2.0.0 - normalize-url: 4.5.0 - responselike: 2.0.0 - dev: false - /call-bind/1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: @@ -2587,6 +2539,7 @@ packages: resolution: {integrity: sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=} dependencies: mimic-response: 1.0.1 + dev: true /co/4.6.0: resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=} @@ -3094,13 +3047,6 @@ packages: mimic-response: 1.0.1 dev: true - /decompress-response/6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - dependencies: - mimic-response: 3.1.0 - dev: false - /dedent/0.7.0: resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=} dev: true @@ -3128,11 +3074,6 @@ packages: resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} dev: true - /defer-to-connect/2.0.1: - resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} - engines: {node: '>=10'} - dev: false - /define-properties/1.1.3: resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} engines: {node: '>= 0.4'} @@ -3333,6 +3274,7 @@ packages: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 + dev: true /enhanced-resolve/5.8.2: resolution: {integrity: sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==} @@ -3915,6 +3857,7 @@ packages: engines: {node: '>=8'} dependencies: pump: 3.0.0 + dev: true /get-value/2.0.6: resolution: {integrity: sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=} @@ -3961,23 +3904,6 @@ packages: engines: {node: '>=4'} dev: true - /got/11.8.2: - resolution: {integrity: sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==} - engines: {node: '>=10.19.0'} - dependencies: - '@sindresorhus/is': 4.0.1 - '@szmarczak/http-timer': 4.0.5 - '@types/cacheable-request': 6.0.1 - '@types/responselike': 1.0.0 - cacheable-lookup: 5.0.4 - cacheable-request: 7.0.1 - decompress-response: 6.0.0 - http2-wrapper: 1.0.3 - lowercase-keys: 2.0.0 - p-cancelable: 2.1.1 - responselike: 2.0.0 - dev: false - /got/9.6.0: resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} engines: {node: '>=8.6'} @@ -4158,6 +4084,7 @@ packages: /http-cache-semantics/4.1.0: resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} + dev: true /http-errors/1.7.2: resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==} @@ -4190,14 +4117,6 @@ packages: sshpk: 1.16.1 dev: true - /http2-wrapper/1.0.3: - resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} - engines: {node: '>=10.19.0'} - dependencies: - quick-lru: 5.1.1 - resolve-alpn: 1.1.2 - dev: false - /https-browserify/1.0.0: resolution: {integrity: sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=} dev: true @@ -5354,10 +5273,6 @@ packages: resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=} dev: true - /json-buffer/3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: false - /json-parse-better-errors/1.0.2: resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} dev: true @@ -5446,12 +5361,6 @@ packages: json-buffer: 3.0.0 dev: true - /keyv/4.0.3: - resolution: {integrity: sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==} - dependencies: - json-buffer: 3.0.1 - dev: false - /kind-of/3.2.2: resolution: {integrity: sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=} engines: {node: '>=0.10.0'} @@ -5691,6 +5600,7 @@ packages: /lowercase-keys/2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} + dev: true /lru-cache/4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} @@ -5828,11 +5738,7 @@ packages: /mimic-response/1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} - - /mimic-response/3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - dev: false + dev: true /mini-create-react-context/0.4.1_prop-types@15.7.2+react@16.14.0: resolution: {integrity: sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==} @@ -6141,6 +6047,7 @@ packages: /normalize-url/4.5.0: resolution: {integrity: sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==} engines: {node: '>=8'} + dev: true /normalize.css/7.0.0: resolution: {integrity: sha1-q/sd2CRwZ04DIrU86xqvQSk45L8=} @@ -6241,6 +6148,7 @@ packages: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} dependencies: wrappy: 1.0.2 + dev: true /one-time/1.0.0: resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} @@ -6276,11 +6184,6 @@ packages: engines: {node: '>=6'} dev: true - /p-cancelable/2.1.1: - resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} - engines: {node: '>=8'} - dev: false - /p-each-series/2.2.0: resolution: {integrity: sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==} engines: {node: '>=8'} @@ -6961,6 +6864,7 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 + dev: true /punycode/1.3.2: resolution: {integrity: sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=} @@ -7042,11 +6946,6 @@ packages: engines: {node: '>=0.4.x'} dev: true - /quick-lru/5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} - dev: false - /raf/3.4.1: resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} dependencies: @@ -8058,10 +7957,6 @@ packages: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} dev: true - /resolve-alpn/1.1.2: - resolution: {integrity: sha512-8OyfzhAtA32LVUsJSke3auIyINcwdh5l3cvYKdKO0nvsYSKuiLfTM5i78PJswFPT8y6cPW+L1v6/hE95chcpDA==} - dev: false - /resolve-cwd/3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -8106,12 +8001,6 @@ packages: lowercase-keys: 1.0.1 dev: true - /responselike/2.0.0: - resolution: {integrity: sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==} - dependencies: - lowercase-keys: 2.0.0 - dev: false - /restore-cursor/3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -9701,6 +9590,7 @@ packages: /wrappy/1.0.2: resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + dev: true /write-file-atomic/2.4.1: resolution: {integrity: sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==} From f9c1dfc8cb5ac6f99016f6ae5e4f063fec5bc991 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 1 Jul 2021 00:40:20 +0800 Subject: [PATCH 149/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c9f15b61..e568cca2 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -37,13 +37,13 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ && chmod 777 ${QL_DIR}/docker/*.sh \ + && npm install -g pm2 \ + && npm install -g pnpm \ + && rm -rf /root/.npm \ && pnpm install \ && pnpm build \ && pnpm build-back \ && rm -rf node_modules \ - && npm install -g pm2 \ - && npm install -g pnpm \ - && rm -rf /root/.npm \ && pnpm install --prod \ && rm -rf /root/.pnpm-store ENTRYPOINT ["./docker/docker-entrypoint.sh"] From 4bc1deda42ec3d7aac184258e43fb3b7d594dde2 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 1 Jul 2021 11:49:44 +0800 Subject: [PATCH 150/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dreq=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/express.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/loaders/express.ts b/back/loaders/express.ts index bd47572c..4cdd7f12 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -27,7 +27,7 @@ export default ({ app }: { app: Application }) => { return next(); } } - if (!headerToken && req.url && req.path === '/api/login') { + if (!headerToken && req.path && req.path === '/api/login') { return next(); } const err: any = new Error('UnauthorizedError'); From 7ecd38ad1fcdd11c719346cb03a6e1fc5b98f6ef Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 1 Jul 2021 15:27:13 +0800 Subject: [PATCH 151/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 21 +-------------------- docker/Dockerfile | 9 ++++----- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 08714198..4330e547 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,9 +1,6 @@ name: Publish Docker Image on: - push: - branches: - - v* - - master + workflow_dispatch: jobs: build: @@ -33,19 +30,3 @@ jobs: if: github.ref == 'refs/heads/master' run: | docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ - - - name: Replace branch without `v` - if: startsWith(github.ref, 'refs/heads/') && github.ref != 'refs/heads/master' - uses: actions/github-script@v1 - id: version - with: - script: | - return context.payload.ref.replace(/\/?refs\/heads\/v/, '') - result-encoding: string - - - name: Docker buildx image and push on release - env: - SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - if: startsWith(github.ref, 'refs/heads/') && github.ref != 'refs/heads/master' - run: | - docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:${{steps.version.outputs.result}} docker/ diff --git a/docker/Dockerfile b/docker/Dockerfile index e568cca2..ab61085d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -29,21 +29,20 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && echo "Asia/Shanghai" > /etc/timezone \ && touch ~/.bashrc \ && mkdir /run/nginx \ + && git clone -b ${QL_BRANCH} https://github.com/whyour/qinglong-static.git /static \ && git clone -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} \ && git config --global user.email "qinglong@@users.noreply.github.com" \ && git config --global user.name "qinglong" \ && git config --global pull.rebase true \ && cd ${QL_DIR} \ + && cp -rf /static/* ./ \ + && rm -rf /static \ && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ && chmod 777 ${QL_DIR}/docker/*.sh \ && npm install -g pm2 \ && npm install -g pnpm \ && rm -rf /root/.npm \ - && pnpm install \ - && pnpm build \ - && pnpm build-back \ - && rm -rf node_modules \ && pnpm install --prod \ && rm -rf /root/.pnpm-store -ENTRYPOINT ["./docker/docker-entrypoint.sh"] +ENTRYPOINT ["./docker/docker-entrypoint.sh"] \ No newline at end of file From a14a8cc0679947ead55600750a201833f17b4d20 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 1 Jul 2021 18:52:50 +0800 Subject: [PATCH 152/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dentrypoint=E6=AD=A5?= =?UTF-8?q?=E9=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 8 ++++---- docker/docker-entrypoint.sh | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index ab61085d..951ca658 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -29,14 +29,11 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && echo "Asia/Shanghai" > /etc/timezone \ && touch ~/.bashrc \ && mkdir /run/nginx \ - && git clone -b ${QL_BRANCH} https://github.com/whyour/qinglong-static.git /static \ && git clone -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} \ && git config --global user.email "qinglong@@users.noreply.github.com" \ && git config --global user.name "qinglong" \ && git config --global pull.rebase true \ && cd ${QL_DIR} \ - && cp -rf /static/* ./ \ - && rm -rf /static \ && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ && chmod 777 ${QL_DIR}/docker/*.sh \ @@ -44,5 +41,8 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && npm install -g pnpm \ && rm -rf /root/.npm \ && pnpm install --prod \ - && rm -rf /root/.pnpm-store + && rm -rf /root/.pnpm-store \ + && git clone -b ${QL_BRANCH} https://github.com/whyour/qinglong-static.git /static \ + && cp -rf /static/* ${QL_DIR} \ + && rm -rf /static ENTRYPOINT ["./docker/docker-entrypoint.sh"] \ No newline at end of file diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 478b71bf..2e10c422 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -10,11 +10,15 @@ cp -fv $dir_root/docker/front.conf /etc/nginx/conf.d/front.conf pm2 l >/dev/null 2>&1 echo -echo -e "======================2. 启动nginx========================\n" +echo -e "======================2. 安装依赖========================\n" +update_depend +echo + +echo -e "======================3. 启动nginx========================\n" nginx -s reload 2>/dev/null || nginx -c /etc/nginx/nginx.conf echo -e "nginx启动成功...\n" -echo -e "======================3. 启动控制面板========================\n" +echo -e "======================4. 启动控制面板========================\n" if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel --source-map-support --time else @@ -22,7 +26,7 @@ else fi echo -e "控制面板启动成功...\n" -echo -e "======================4. 启动定时任务========================\n" +echo -e "======================5. 启动定时任务========================\n" if [[ $(pm2 info schedule 2>/dev/null) ]]; then pm2 reload schedule --source-map-support --time else @@ -31,12 +35,12 @@ fi echo -e "定时任务启动成功...\n" if [[ $AutoStartBot == true ]]; then - echo -e "======================5. 启动bot========================\n" + echo -e "======================6. 启动bot========================\n" ql bot fi if [[ $EnableExtraShell == true ]]; then - echo -e "======================6. 执行自定义脚本========================\n" + echo -e "======================7. 执行自定义脚本========================\n" ql extra fi From 356f8db728f709504cae993da84070b158cbd422 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 1 Jul 2021 21:32:54 +0800 Subject: [PATCH 153/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcurl=20proxy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 12 ++++++------ shell/check.sh | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index d2c1d410..d9bebf94 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -17,7 +17,7 @@ add_cron_api() { fi local api=$( - curl -s "http://localhost:5600/api/crons?t=$currentTimeStamp" \ + curl -s --noproxy "*" "http://localhost:5600/api/crons?t=$currentTimeStamp" \ -H "Accept: application/json" \ -H "Authorization: Bearer $token" \ -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36" \ @@ -52,7 +52,7 @@ update_cron_api() { fi local api=$( - curl -s "http://localhost:5600/api/crons?t=$currentTimeStamp" \ + curl -s --noproxy "*" "http://localhost:5600/api/crons?t=$currentTimeStamp" \ -X 'PUT' \ -H "Accept: application/json" \ -H "Authorization: Bearer $token" \ @@ -84,7 +84,7 @@ update_cron_command_api() { fi local api=$( - curl -s "http://localhost:5600/api/crons?t=$currentTimeStamp" \ + curl -s --noproxy "*" "http://localhost:5600/api/crons?t=$currentTimeStamp" \ -X 'PUT' \ -H "Accept: application/json" \ -H "Authorization: Bearer $token" \ @@ -109,7 +109,7 @@ del_cron_api() { local ids=$1 local currentTimeStamp=$(date +%s) local api=$( - curl -s "http://localhost:5600/api/crons?t=$currentTimeStamp" \ + curl -s --noproxy "*" "http://localhost:5600/api/crons?t=$currentTimeStamp" \ -X 'DELETE' \ -H "Accept: application/json" \ -H "Authorization: Bearer $token" \ @@ -133,7 +133,7 @@ del_cron_api() { get_user_info() { local currentTimeStamp=$(date +%s) local api=$( - curl -s "http://localhost:5600/api/user?t=$currentTimeStamp" \ + curl -s --noproxy "*" "http://localhost:5600/api/user?t=$currentTimeStamp" \ -H 'Accept: */*' \ -H "Authorization: Bearer $token" \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36' \ @@ -153,7 +153,7 @@ update_cron_status() { local status=$2 local currentTimeStamp=$(date +%s) local api=$( - curl -s "http://localhost:5600/api/crons/status?t=$currentTimeStamp" \ + curl -s --noproxy "*" "http://localhost:5600/api/crons/status?t=$currentTimeStamp" \ -X 'PUT' \ -H "Accept: application/json" \ -H "Authorization: Bearer $token" \ diff --git a/shell/check.sh b/shell/check.sh index 7e75b57d..85b75926 100644 --- a/shell/check.sh +++ b/shell/check.sh @@ -64,7 +64,7 @@ check_nginx() { } check_ql() { - local api=$(curl -s "http://localhost:5700") + local api=$(curl -s --noproxy "*" "http://localhost:5700") echo -e "\n=====> 检测面板\n\n$api\n" if [[ $api =~ "
" ]]; then echo -e "=====> 面板服务启动正常\n" @@ -78,7 +78,7 @@ check_pm2() { pm2_log local currentTimeStamp=$(date +%s) local api=$( - curl -s "http://localhost:5600/api/user?t=$currentTimeStamp" \ + curl -s --noproxy "*" "http://localhost:5600/api/user?t=$currentTimeStamp" \ -H 'Accept: */*' \ -H "Authorization: Bearer $token" \ -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36' \ From 41c3f218637164273ea8c6eab9a572b4bc6b849c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=99=E5=96=84=E6=98=8E?= Date: Thu, 1 Jul 2021 21:51:58 +0800 Subject: [PATCH 154/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E6=8F=90=E5=8F=96=20cron=20=E6=97=B6=E9=97=B4=20(#373)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/update.sh b/shell/update.sh index 073ca4f4..e598a5c9 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -120,6 +120,7 @@ add_cron() { cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" [[ -z $cron_line ]] && cron_line=$(grep "cron:" $file | awk -F ":" '{print $2}' | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron " $file | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" result=$(add_cron_api "$cron_line:$cmd_task $file:$cron_name") echo -e "$result" @@ -193,6 +194,7 @@ update_raw() { cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$raw_file_name" [[ -z $cron_line ]] && cron_line=$(grep "cron:" $raw_file_name | awk -F ":" '{print $2}' | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron " $raw_file_name | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" if [[ -z $cron_id ]]; then result=$(add_cron_api "$cron_line:$cmd_task $filename:$cron_name") From 53123af832102badb7286e6b11433f6bbdc9e2eb Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 3 Jul 2021 16:25:13 +0800 Subject: [PATCH 155/247] =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=80=BC=E8=B6=85=E5=87=BA=E6=98=BE=E7=A4=BA...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/initData.ts | 6 ++-- src/layouts/index.less | 11 ++++++ src/pages/crontab/index.tsx | 63 +++++++++++++++++---------------- src/pages/env/index.tsx | 70 +++++++++++++++++++------------------ 4 files changed, 83 insertions(+), 67 deletions(-) diff --git a/back/loaders/initData.ts b/back/loaders/initData.ts index 06d35d42..243e9513 100644 --- a/back/loaders/initData.ts +++ b/back/loaders/initData.ts @@ -12,13 +12,13 @@ const initData = [ 6, 1, ).toString()} * * *`, - status: CrontabStatus.disabled, + isDisabled: 1, }, { name: '删除日志', command: 'ql rmlog 7', schedule: '30 7 */7 * *', - status: CrontabStatus.disabled, + isDisabled: 1, }, ]; @@ -29,7 +29,7 @@ export default async () => { cronDb.count({}, async (err, count) => { if (count === 0) { - const data = initData.map((x) => { + const data = initData.map((x: any) => { const tab = new Crontab(x); tab.created = new Date().valueOf(); tab.saved = false; diff --git a/src/layouts/index.less b/src/layouts/index.less index f276b33e..d5f2460c 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -36,6 +36,17 @@ body { } } +.ant-table-cell-ellipsis { + text-align: left !important; +} + +.ant-tooltip { + max-width: 500px; + .ant-tooltip-inner { + word-break: break-all; + } +} + .env-wrapper { th { white-space: nowrap; diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index f527d688..23b3f318 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -137,42 +137,45 @@ const Crontab = () => { title: '操作', key: 'action', align: 'center' as const, - render: (text: string, record: any, index: number) => ( - - {record.status === CrontabStatus.idle && ( - + render: (text: string, record: any, index: number) => { + const isPc = width === '100%'; + return ( + + {record.status === CrontabStatus.idle && ( + + { + runCron(record, index); + }} + > + + + + )} + {record.status !== CrontabStatus.idle && ( + + { + stopCron(record, index); + }} + > + + + + )} + { - runCron(record, index); + setLogCron({ ...record, timestamp: Date.now() }); }} > - + - )} - {record.status !== CrontabStatus.idle && ( - - { - stopCron(record, index); - }} - > - - - - )} - - { - setLogCron({ ...record, timestamp: Date.now() }); - }} - > - - - - - - ), + + + ); + }, }, ]; diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 2e9e134b..78ee6b2f 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -124,19 +124,14 @@ const Env = () => { key: 'value', align: 'center' as const, width: '45%', + ellipsis: { + showTitle: false, + }, render: (text: string, record: any) => { return ( - - {text} - + + {text} + ); }, }, @@ -166,29 +161,36 @@ const Env = () => { title: '操作', key: 'action', align: 'center' as const, - render: (text: string, record: any, index: number) => ( - - - editEnv(record, index)}> - - - - - enabledOrDisabledEnv(record, index)}> - {record.status === Status.已禁用 ? ( - - ) : ( - - )} - - - - deleteEnv(record, index)}> - - - - - ), + render: (text: string, record: any, index: number) => { + const isPc = width === '100%'; + return ( + + + editEnv(record, index)}> + + + + + enabledOrDisabledEnv(record, index)}> + {record.status === Status.已禁用 ? ( + + ) : ( + + )} + + + + deleteEnv(record, index)}> + + + + + ); + }, }, ]; const [width, setWidth] = useState('100%'); From 5c2bbc941fb39be61500d2d24c4aa783204be0f1 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 3 Jul 2021 16:49:02 +0800 Subject: [PATCH 156/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=8E=B7=E5=8F=96sam?= =?UTF-8?q?ple=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/config.ts | 13 ++++++++++--- back/config/index.ts | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/back/api/config.ts b/back/api/config.ts index 9da30007..175478a2 100644 --- a/back/api/config.ts +++ b/back/api/config.ts @@ -36,9 +36,16 @@ export default (app: Router) => { async (req: Request, res: Response, next: NextFunction) => { const logger: Logger = Container.get('logger'); try { - const content = getFileContentByName( - `${config.configPath}${req.params.file}`, - ); + let content = ''; + if (req.params.file.includes('sample')) { + content = getFileContentByName( + `${config.samplePath}${req.params.file}`, + ); + } else { + content = getFileContentByName( + `${config.configPath}${req.params.file}`, + ); + } res.send({ code: 200, data: content }); } catch (e) { logger.error('🔥 error: %o', e); diff --git a/back/config/index.ts b/back/config/index.ts index 44053157..96bee0b4 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -15,6 +15,7 @@ const authConfigFile = path.join(rootPath, 'config/auth.json'); const extraFile = path.join(rootPath, 'config/extra.sh'); const configPath = path.join(rootPath, 'config/'); const scriptPath = path.join(rootPath, 'scripts/'); +const samplePath = path.join(rootPath, 'sample/'); const logPath = path.join(rootPath, 'log/'); const authError = '错误的用户名密码,请重试'; const loginFaild = '请先登录!'; @@ -58,5 +59,6 @@ export default { envDbFile, configPath, scriptPath, + samplePath, blackFileList: ['auth.json', 'config.sh.sample', 'cookie.sh', 'crontab.list'], }; From f6630d84abe06dc69465c98955c8e599efc2b565 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 3 Jul 2021 16:49:29 +0800 Subject: [PATCH 157/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 744014b5..bf5a7b8a 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-063'; -export const changeLog = 'https://t.me/jiaolongwang/113'; +export const version = 'v2.8.0-064'; +export const changeLog = 'https://t.me/jiaolongwang/114'; From b1d55422ac56e43d66e5de92f93ebf05703049b0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 3 Jul 2021 17:17:08 +0800 Subject: [PATCH 158/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8Ftooltip=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index d5f2460c..b9fbd075 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -41,9 +41,9 @@ body { } .ant-tooltip { - max-width: 500px; + max-width: 500px !important; .ant-tooltip-inner { - word-break: break-all; + word-break: break-all !important; } } From c1a3ac6e4dae6bc2117a91af1e384c788baeefbd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 3 Jul 2021 18:38:02 +0800 Subject: [PATCH 159/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8Ftooltip?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 5 +++++ src/pages/env/index.tsx | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index b9fbd075..fab9c03b 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -88,6 +88,7 @@ input:-webkit-autofill:active { height: calc(100vh - var(--vh-offset, 0px) - 144px); } } + .ql-container-wrapper { &.crontab-wrapper, &.log-wrapper { @@ -108,4 +109,8 @@ input:-webkit-autofill:active { height: calc(100vh - var(--vh-offset, 0px) - 176px); } } + + .ant-tooltip { + max-width: 250px !important; + } } diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 78ee6b2f..833be0b1 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -123,7 +123,7 @@ const Env = () => { dataIndex: 'value', key: 'value', align: 'center' as const, - width: '45%', + width: '40%', ellipsis: { showTitle: false, }, @@ -164,7 +164,7 @@ const Env = () => { render: (text: string, record: any, index: number) => { const isPc = width === '100%'; return ( - + editEnv(record, index)}> From a8a2a54bea4b9e05371c9cf7b885efa518318a85 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 4 Jul 2021 19:00:02 +0800 Subject: [PATCH 160/247] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/cron.ts | 3 +++ back/data/cron.ts | 2 ++ back/services/cron.ts | 47 +++++++++++++++++++++++++++----------- shell/api.sh | 14 +++++++----- shell/task.sh | 53 ++++++++++++++++++++++++++++++++++--------- shell/update.sh | 6 ++--- 6 files changed, 92 insertions(+), 33 deletions(-) diff --git a/back/api/cron.ts b/back/api/cron.ts index 5206c6b6..a4374047 100644 --- a/back/api/cron.ts +++ b/back/api/cron.ts @@ -232,6 +232,8 @@ export default (app: Router) => { body: Joi.object({ ids: Joi.array().items(Joi.string().required()), status: Joi.string().required(), + pid: Joi.string().optional(), + log_path: Joi.string().optional(), }), }), async (req: Request, res: Response, next: NextFunction) => { @@ -241,6 +243,7 @@ export default (app: Router) => { const data = await cronService.status({ ...req.body, status: parseInt(req.body.status), + pid: parseInt(req.body.pid) || '', }); return res.send({ code: 200, data }); } catch (e) { diff --git a/back/data/cron.ts b/back/data/cron.ts index 0b050355..64b9823f 100644 --- a/back/data/cron.ts +++ b/back/data/cron.ts @@ -10,6 +10,7 @@ export class Crontab { isSystem?: 1 | 0; pid?: number; isDisabled?: 1 | 0; + log_path?: string; constructor(options: Crontab) { this.name = options.name; @@ -25,6 +26,7 @@ export class Crontab { this.isSystem = options.isSystem || 0; this.pid = options.pid; this.isDisabled = options.isDisabled || 0; + this.log_path = options.log_path || ''; } } diff --git a/back/services/cron.ts b/back/services/cron.ts index 8adcfa5a..25cfcfc0 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -87,11 +87,18 @@ export default class CronService { public async status({ ids, status, + pid, + log_path, }: { ids: string[]; status: CrontabStatus; + pid: number; + log_path: string; }) { - this.cronDb.update({ _id: { $in: ids } }, { $set: { status } }); + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { status, pid, log_path } }, + ); } public async remove(ids: string[]) { @@ -158,17 +165,26 @@ export default class CronService { public async stop(ids: string[]) { return new Promise((resolve: any) => { this.cronDb.find({ _id: { $in: ids } }).exec((err, docs: Crontab[]) => { + for (const doc of docs) { + if (doc.pid) { + try { + process.kill(-doc.pid); + } catch (error) { + this.logger.silly(error); + } + } + if (doc.log_path) { + fs.appendFileSync( + `${config.logPath}${doc.log_path}`, + `\n## 执行结束... ${new Date().toLocaleString()} `, + ); + } + } this.cronDb.update( { _id: { $in: ids } }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, ); - const pids = docs - .map((x) => x.pid) - .filter((x) => !!x) - .join('\n'); - exec(`echo - e "${pids}" | xargs kill - 9`, (err) => { - resolve(); - }); + resolve(); }); }); } @@ -194,17 +210,19 @@ export default class CronService { if (cmdStr.endsWith('.js')) { cmdStr = `${cmdStr} now`; } - const cp = exec(cmdStr, (err, stdout, stderr) => { + + const cp = spawn(cmdStr, { shell: true, detached: true }); + this.cronDb.update( + { _id }, + { $set: { status: CrontabStatus.running, pid: cp.pid } }, + ); + cp.on('close', (code) => { this.cronDb.update( { _id }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, ); resolve(); }); - this.cronDb.update( - { _id }, - { $set: { status: CrontabStatus.running, pid: cp.pid } }, - ); }); } @@ -238,6 +256,9 @@ export default class CronService { public async log(_id: string) { const doc = await this.get(_id); + if (doc.log_path) { + return getFileContentByName(`${config.logPath}/${doc.log_path}`); + } const [, commandStr, url] = doc.command.split(' '); let logPath = this.getKey(commandStr); const isQlCommand = doc.command.startsWith('ql '); diff --git a/shell/api.sh b/shell/api.sh index d9bebf94..bf486612 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -148,9 +148,11 @@ get_user_info() { fi } -update_cron_status() { - local ids=$1 - local status=$2 +update_cron() { + local ids="$1" + local status="$2" + local pid="${3:-''}" + local logPath="$4" local currentTimeStamp=$(date +%s) local api=$( curl -s --noproxy "*" "http://localhost:5600/api/crons/status?t=$currentTimeStamp" \ @@ -162,15 +164,15 @@ update_cron_status() { -H "Origin: http://localhost:5700" \ -H "Referer: http://localhost:5700/crontab" \ -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \ - --data-raw "{\"ids\":[$ids],\"status\":\"$status\"}" \ + --data-raw "{\"ids\":[$ids],\"status\":\"$status\",\"pid\":\"$pid\",\"log_path\":\"$logPath\"}" \ --compressed ) code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "更新任务状态成功" + echo -e "更新任务状态成功" | tee -a $log_path else - echo -e "更新任务状态失败(${message})" + echo -e "更新任务状态失败(${message})" | tee -a $log_path fi } diff --git a/shell/task.sh b/shell/task.sh index 70d44bdd..490af7f3 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -76,7 +76,6 @@ run_normal() { local p1=$1 cd $dir_scripts define_program "$p1" - . $file_task_before if [[ $p1 == *.js ]]; then if [[ $# -eq 1 ]]; then random_delay @@ -88,13 +87,16 @@ run_normal() { log_path="$log_dir/$log_time.log" make_dir "$log_dir" - local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | xargs | sed 's/ /","/g') + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path - [[ $id ]] && update_cron_status "\"$id\"" "0" + [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" + . $file_task_before + timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path + . $file_task_after - [[ $id ]] && update_cron_status "\"$id\"" "1" + [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path @@ -113,25 +115,54 @@ run_concurrent() { local array=($(echo $envs | sed 's/&/ /g')) cd $dir_scripts define_program "$p1" + log_time=$(date "+%Y-%m-%d-%H-%M-%S") log_dir_tmp="${p1##*/}" log_dir="$dir_log/${log_dir_tmp%%.*}" + log_path="$log_dir/$log_time.log" make_dir $log_dir - log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") - echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" + + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') + local begin_time=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" + . $file_task_before + echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -a $log_path + + single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") for i in "${!array[@]}"; do export ${p3}=${array[i]} - log_path="$log_dir/${log_time}_$((i+1)).log" - timeout $command_timeout_time $which_program $p1 &>$log_path & + single_log_path="$log_dir/${single_log_time}_$((i+1)).log" + timeout $command_timeout_time $which_program $p1 &>$single_log_path & done + + . $file_task_after + [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" + local end_time=$(date '+%Y-%m-%d %H:%M:%S') + local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path } ## 运行其他命令 run_else() { local log_time=$(date "+%Y-%m-%d-%H-%M-%S") - local log_dir="$dir_log/$1" - local log_path="$log_dir/$log_time.log" + local log_dir_tmp="${1##*/}" + local log_dir="$dir_log/${log_dir_tmp%%.*}" + log_path="$log_dir/$log_time.log" make_dir "$log_dir" - timeout $command_timeout_time "$@" 2>&1 | tee $log_path + + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') + local begin_time=$(date '+%Y-%m-%d %H:%M:%S') + echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" + . $file_task_before + + timeout $command_timeout_time "$@" 2>&1 | tee -a $log_path + + . $file_task_after + [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" + local end_time=$(date '+%Y-%m-%d %H:%M:%S') + local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path } ## 命令检测 diff --git a/shell/update.sh b/shell/update.sh index e598a5c9..28443695 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -72,7 +72,7 @@ del_cron() { local ids="" echo -e "开始尝试自动删除失效的定时任务...\n" for cron in $(cat $list_drop); do - local id=$(cat $list_crontab_user | grep -E "$cmd_task $cron" | perl -pe "s|.*ID=(.*) $cmd_task $cron|\1|" | xargs | sed 's/ /","/g' | head -1) + local id=$(cat $list_crontab_user | grep -E "$cmd_task $cron" | perl -pe "s|.*ID=(.*) $cmd_task $cron\.*|\1|" | head -1 | head -1 | awk -F " " '{print $1}') if [[ $ids ]]; then ids="$ids,\"$id\"" else @@ -179,7 +179,7 @@ update_raw() { echo -e "下载 ${raw_file_name} 成功...\n" cd $dir_raw local filename="raw_${raw_file_name}" - local cron_id=$(cat $list_crontab_user | grep -E "$cmd_task $filename" | perl -pe "s|.*ID=(.*) $cmd_task $filename\.*|\1|" | head -1) + local cron_id=$(cat $list_crontab_user | grep -E "$cmd_task $filename" | perl -pe "s|.*ID=(.*) $cmd_task $filename\.*|\1|" | head -1 | head -1 | awk -F " " '{print $1}') cp -f $raw_file_name $dir_scripts/${filename} cron_line=$( perl -ne "{ @@ -376,7 +376,7 @@ gen_list_repo() { filename=$(basename $file) cp -f $file $dir_scripts/${repo}_${filename} echo ${repo}_${filename} >>"$dir_list_tmp/${repo}_scripts.list" - cron_id=$(cat $list_crontab_user | grep -E "$cmd_task ${author}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|" | head -1) + cron_id=$(cat $list_crontab_user | grep -E "$cmd_task ${author}_${filename}" | perl -pe "s|.*ID=(.*) $cmd_task ${author}_${filename}\.*|\1|" | head -1 | awk -F " " '{print $1}') if [[ $cron_id ]]; then result=$(update_cron_command_api "$cmd_task ${repo}_${filename}:$cron_id") fi From e687511f3272b9dee5f07c5a448320d912a8f641 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 4 Jul 2021 19:12:45 +0800 Subject: [PATCH 161/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dshell=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1id=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 2 +- shell/task.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 25cfcfc0..35fd55ad 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -257,7 +257,7 @@ export default class CronService { public async log(_id: string) { const doc = await this.get(_id); if (doc.log_path) { - return getFileContentByName(`${config.logPath}/${doc.log_path}`); + return getFileContentByName(`${doc.log_path}`); } const [, commandStr, url] = doc.command.split(' '); let logPath = this.getKey(commandStr); diff --git a/shell/task.sh b/shell/task.sh index 490af7f3..ee922618 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -87,7 +87,7 @@ run_normal() { log_path="$log_dir/$log_time.log" make_dir "$log_dir" - local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" @@ -121,7 +121,7 @@ run_concurrent() { log_path="$log_dir/$log_time.log" make_dir $log_dir - local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" @@ -150,7 +150,7 @@ run_else() { log_path="$log_dir/$log_time.log" make_dir "$log_dir" - local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1$" | perl -pe "s|.*ID=(.*) $cmd_task $p1$|\1|" | head -1 | awk -F " " '{print $1}') + local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" From 0728f1f231da7c111562f30f0dab28e0e645f846 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 4 Jul 2021 19:15:09 +0800 Subject: [PATCH 162/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E4=BB=BB=E5=8A=A1=E6=97=A5=E5=BF=97=E7=9B=AE?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 35fd55ad..fbccceaf 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -175,7 +175,7 @@ export default class CronService { } if (doc.log_path) { fs.appendFileSync( - `${config.logPath}${doc.log_path}`, + `${doc.log_path}`, `\n## 执行结束... ${new Date().toLocaleString()} `, ); } From f26d6f1449838f6865ce4b5dedfa7910db0a0e92 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 4 Jul 2021 19:25:40 +0800 Subject: [PATCH 163/247] =?UTF-8?q?=E5=8E=BB=E9=99=A4console.log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/crontab/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 23b3f318..175e021c 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -445,9 +445,7 @@ const Crontab = () => { request .get(`${config.apiPrefix}crons/${cron._id}`) .then((data: any) => { - console.log(value); const index = value.findIndex((x) => x._id === cron._id); - console.log(index); const result = [...value]; result.splice(index, 1, { ...cron, From f554a5b1a046a3ab7e5a206a88e26b35a02e8c6e Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 4 Jul 2021 19:26:47 +0800 Subject: [PATCH 164/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index bf5a7b8a..d4e841e3 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-064'; -export const changeLog = 'https://t.me/jiaolongwang/114'; +export const version = 'v2.8.0-065'; +export const changeLog = 'https://t.me/jiaolongwang/115'; From 7b7d62760e258b651d64f378b03a71aa44b2bcc8 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sun, 4 Jul 2021 19:35:35 +0800 Subject: [PATCH 165/247] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=BB=BB=E5=8A=A1=E4=B8=BA=E7=A9=BA=E9=97=B2=E7=8A=B6?= =?UTF-8?q?=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/initData.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/back/loaders/initData.ts b/back/loaders/initData.ts index 243e9513..f96b695f 100644 --- a/back/loaders/initData.ts +++ b/back/loaders/initData.ts @@ -45,16 +45,11 @@ export default async () => { } }); - // patch更新面板任务状态 - cronDb.find({ name: '更新面板' }).exec((err, docs) => { - const doc = docs[0]; - if (doc && doc.status === CrontabStatus.running) { - cronDb.update( - { name: '更新面板' }, - { $set: { status: CrontabStatus.idle } }, - ); - } - }); + // 初始化更新所有任务状态为空闲 + cronDb.update( + { status: CrontabStatus.running }, + { $set: { status: CrontabStatus.idle } }, + ); // 初始化时执行一次所有的ql repo 任务 cronDb From 71d7d3818fd56eb7b48d7a406d9ec40b1e2057ed Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 6 Jul 2021 13:42:25 +0800 Subject: [PATCH 166/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=8A=B6=E6=80=81=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index bf486612..aeaa545f 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -170,9 +170,9 @@ update_cron() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "更新任务状态成功" | tee -a $log_path + echo -e "## 更新任务状态成功" | tee -a $log_path else - echo -e "更新任务状态失败(${message})" | tee -a $log_path + echo -e "## 更新任务状态失败(${message})" | tee -a $log_path fi } From 517fdcc8ec2beb0f0174009f6bc9b3c90e465d75 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 7 Jul 2021 18:26:56 +0800 Subject: [PATCH 167/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dspawn=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E4=B8=AD=E6=96=AD=EF=BC=8C=E4=BF=AE=E5=A4=8Dtoken?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E4=BB=BB=E5=8A=A1=E7=8A=B6=E6=80=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/express.ts | 7 +++++++ back/services/cron.ts | 11 +++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/back/loaders/express.ts b/back/loaders/express.ts index 4cdd7f12..92714249 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -30,6 +30,13 @@ export default ({ app }: { app: Application }) => { if (!headerToken && req.path && req.path === '/api/login') { return next(); } + const remoteAddress = req.socket.remoteAddress; + if ( + remoteAddress === '::ffff:127.0.0.1' && + req.path === '/api/crons/status' + ) { + return next(); + } const err: any = new Error('UnauthorizedError'); err['status'] = 401; next(err); diff --git a/back/services/cron.ts b/back/services/cron.ts index fbccceaf..23fc0941 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -211,18 +211,17 @@ export default class CronService { cmdStr = `${cmdStr} now`; } - const cp = spawn(cmdStr, { shell: true, detached: true }); - this.cronDb.update( - { _id }, - { $set: { status: CrontabStatus.running, pid: cp.pid } }, - ); - cp.on('close', (code) => { + const cp = exec(cmdStr, (err, stdout, stderr) => { this.cronDb.update( { _id }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, ); resolve(); }); + this.cronDb.update( + { _id }, + { $set: { status: CrontabStatus.running, pid: cp.pid } }, + ); }); } From 22a23fe05e6cf8a35063b9baed986f8789ef26b3 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 7 Jul 2021 18:27:19 +0800 Subject: [PATCH 168/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index d4e841e3..848e850d 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-065'; -export const changeLog = 'https://t.me/jiaolongwang/115'; +export const version = 'v2.8.0-066'; +export const changeLog = 'https://t.me/jiaolongwang/116'; From 6cd0feaaceadd6b0664a6378c0930c55aef0c00f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 8 Jul 2021 10:24:40 +0800 Subject: [PATCH 169/247] =?UTF-8?q?=E6=92=A4=E9=94=80spawn=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 23fc0941..fbccceaf 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -211,17 +211,18 @@ export default class CronService { cmdStr = `${cmdStr} now`; } - const cp = exec(cmdStr, (err, stdout, stderr) => { + const cp = spawn(cmdStr, { shell: true, detached: true }); + this.cronDb.update( + { _id }, + { $set: { status: CrontabStatus.running, pid: cp.pid } }, + ); + cp.on('close', (code) => { this.cronDb.update( { _id }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, ); resolve(); }); - this.cronDb.update( - { _id }, - { $set: { status: CrontabStatus.running, pid: cp.pid } }, - ); }); } From ed95d66441f9e5e8a7aec3afff9f09348bde6553 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 8 Jul 2021 13:05:39 +0800 Subject: [PATCH 170/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jd-panel | 1 + shell/update.sh | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 160000 jd-panel diff --git a/jd-panel b/jd-panel new file mode 160000 index 00000000..2d546742 --- /dev/null +++ b/jd-panel @@ -0,0 +1 @@ +Subproject commit 2d5467420e63c842d306718493cf8edbf7d6c804 diff --git a/shell/update.sh b/shell/update.sh index 28443695..e1003f2f 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash -# 导入通用变量与函数 dir_shell=/ql/shell . $dir_shell/share.sh . $dir_shell/api.sh From 23db56df579733bdc1bc20622c96aa5051fb4ef4 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 8 Jul 2021 18:15:25 +0800 Subject: [PATCH 171/247] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=B4=E6=97=B6?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jd-panel | 1 - 1 file changed, 1 deletion(-) delete mode 160000 jd-panel diff --git a/jd-panel b/jd-panel deleted file mode 160000 index 2d546742..00000000 --- a/jd-panel +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2d5467420e63c842d306718493cf8edbf7d6c804 From c960717d921b25af4dda10c2565d99fbe4880877 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 8 Jul 2021 18:52:48 +0800 Subject: [PATCH 172/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9workflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ build.yml | 2 +- .github/workflows/docker.yml | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ build.yml b/.github/workflows/ build.yml index 79fa51e1..57df786a 100644 --- a/.github/workflows/ build.yml +++ b/.github/workflows/ build.yml @@ -1,4 +1,4 @@ -name: Build Static +name: BuildStatic on: push: diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4330e547..26a7c265 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,6 +1,12 @@ -name: Publish Docker Image +name: PublishDockerImage on: - workflow_dispatch: + workflow_run: + workflows: + - BuildStatic + branches: + - master + types: + - completed jobs: build: From dd2d3127a0b2b410217ac3765c71a2a18e01c3cc Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 8 Jul 2021 19:13:00 +0800 Subject: [PATCH 173/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/{ build.yml => build.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{ build.yml => build.yml} (100%) diff --git a/.github/workflows/ build.yml b/.github/workflows/build.yml similarity index 100% rename from .github/workflows/ build.yml rename to .github/workflows/build.yml From 8336434d3fb803d1de8d638d4fd5829368d45748 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 8 Jul 2021 23:11:00 +0800 Subject: [PATCH 174/247] =?UTF-8?q?=E5=AE=B9=E5=99=A8=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E6=97=B6bot=E5=92=8C=E8=87=AA=E5=AE=9A=E4=B9=89=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E6=94=B9=E6=88=90=E5=90=8E=E5=8F=B0=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-entrypoint.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 2e10c422..e6da124f 100755 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -36,12 +36,14 @@ echo -e "定时任务启动成功...\n" if [[ $AutoStartBot == true ]]; then echo -e "======================6. 启动bot========================\n" - ql bot + nohup ql bot >>$dir_log/start.log 2>&1 & + echo -e "bot后台启动中...\n" fi if [[ $EnableExtraShell == true ]]; then echo -e "======================7. 执行自定义脚本========================\n" - ql extra + nohup ql extra >>$dir_log/start.log 2>&1 & + echo -e "自定义脚本后台执行中...\n" fi echo -e "############################################################\n" From 72240a783430e8c52b1d21e507524cfd702cd443 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 8 Jul 2021 23:17:52 +0800 Subject: [PATCH 175/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B72.8.0-067?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 848e850d..2d37a635 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-066'; -export const changeLog = 'https://t.me/jiaolongwang/116'; +export const version = 'v2.8.0-067'; +export const changeLog = 'https://t.me/jiaolongwang/117'; From 602ffdcd5a3248adfd3a1d9f1bed3183c85ac08d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 15:22:10 +0800 Subject: [PATCH 176/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9docker=20build?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 26a7c265..790d97e8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,6 +12,7 @@ jobs: build: name: Build runs-on: ubuntu-latest + if: "contains(github.event.head_commit.message, '版本号')" steps: - name: Checkout base uses: actions/checkout@v2 From 6c63fb83eff24e9e72c44da007e230bd5e320c0b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 18:28:06 +0800 Subject: [PATCH 177/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E6=97=B6task=5Fbefore=E5=87=BA=E9=94=99?= =?UTF-8?q?=E9=80=A0=E6=88=90=E4=BB=BB=E5=8A=A1=E6=97=A5=E5=BF=97=E4=B8=AD?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index ee922618..565eb300 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -91,11 +91,15 @@ run_normal() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + echo -e "\n## task_before开始\n" | tee -a $log_path + . $file_task_before 2>&1 | tee -a $log_path + echo -e "\n## task_before结束" | tee -a $log_path timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path - . $file_task_after + echo -e "\n## task_after开始\n" | tee -a $log_path + . $file_task_after 2>&1 | tee -a $log_path + echo -e "\n## task_after结束\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) From 381427fd6094a22095dbbccdc4849a1b1aaaf688 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 18:30:35 +0800 Subject: [PATCH 178/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=202.8.0-068?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 2d37a635..54e24c6a 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-067'; -export const changeLog = 'https://t.me/jiaolongwang/117'; +export const version = 'v2.8.0-068'; +export const changeLog = 'https://t.me/jiaolongwang/118'; From bbb1fc4e1b4a819fe6370cb96ab28122bf6042f5 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 18:35:33 +0800 Subject: [PATCH 179/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95docker=E6=89=93?= =?UTF-8?q?=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 790d97e8..2b323d0a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,7 +12,7 @@ jobs: build: name: Build runs-on: ubuntu-latest - if: "contains(github.event.head_commit.message, '版本号')" + if: "contains(github.event.head_commit.message, 'docker')" steps: - name: Checkout base uses: actions/checkout@v2 From 105073ec23c283e545b52b99608eb9a87022f66d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 18:42:21 +0800 Subject: [PATCH 180/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 2b323d0a..ca5c8fd5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,7 +12,7 @@ jobs: build: name: Build runs-on: ubuntu-latest - if: "contains(github.event.head_commit.message, 'docker')" + if: "contains(github.event.head_commit.message, '版本号')" steps: - name: Checkout base uses: actions/checkout@v2 @@ -34,6 +34,6 @@ jobs: - name: Docker buildx image and push on master branch env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - if: github.ref == 'refs/heads/master' + if: "contains(github.event.head_commit.message, '版本号')" run: | docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ From 7bc24a4b622c71aa7f8869249704b7cd3977042f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 18:42:40 +0800 Subject: [PATCH 181/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ca5c8fd5..b5b4151d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -12,7 +12,6 @@ jobs: build: name: Build runs-on: ubuntu-latest - if: "contains(github.event.head_commit.message, '版本号')" steps: - name: Checkout base uses: actions/checkout@v2 From 5e52398a43c7ec4430d81c8a4bf373fddbced5cd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 18:48:22 +0800 Subject: [PATCH 182/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95docker=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b5b4151d..2ecab5a4 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -28,11 +28,12 @@ jobs: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: | + echo ${{ github.event.head_commit.message }} echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin - name: Docker buildx image and push on master branch env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - if: "contains(github.event.head_commit.message, '版本号')" + if: "contains(github.event.head_commit.message, 'docker')" run: | docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ From f7e1c2ae5e096ef4ea5d377634553ae9950f5c23 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 18:52:29 +0800 Subject: [PATCH 183/247] =?UTF-8?q?=E6=9A=82=E6=97=B6=E7=A7=BB=E9=99=A4doc?= =?UTF-8?q?ker=20action=20=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 2ecab5a4..473d4cfb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -28,12 +28,10 @@ jobs: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} run: | - echo ${{ github.event.head_commit.message }} echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin - name: Docker buildx image and push on master branch env: SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - if: "contains(github.event.head_commit.message, 'docker')" run: | docker buildx build --build-arg SSH_PRIVATE_KEY="${SSH_PRIVATE_KEY}" --output "type=image,push=true" --platform=linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x --tag whyour/qinglong:latest docker/ From 0214c6f81ba1e2056f710eb371f517e930f1dbe0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 9 Jul 2021 22:39:54 +0800 Subject: [PATCH 184/247] =?UTF-8?q?=E6=92=A4=E5=9B=9Etask=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index 565eb300..ee922618 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -91,15 +91,11 @@ run_normal() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - echo -e "\n## task_before开始\n" | tee -a $log_path - . $file_task_before 2>&1 | tee -a $log_path - echo -e "\n## task_before结束" | tee -a $log_path + . $file_task_before timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path - echo -e "\n## task_after开始\n" | tee -a $log_path - . $file_task_after 2>&1 | tee -a $log_path - echo -e "\n## task_after结束\n" | tee -a $log_path + . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) From dd424237e2a985ecbd80717b2d50cc5a3fc394b7 Mon Sep 17 00:00:00 2001 From: Licardo <1014660822@qq.com> Date: Mon, 12 Jul 2021 20:17:11 +0800 Subject: [PATCH 185/247] =?UTF-8?q?=E6=B7=BB=E5=8A=A0bark=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E6=B6=88=E6=81=AF=E5=88=86=E7=BB=84=20(#479)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sample/config.sample.sh | 2 ++ sample/notify.js | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sample/config.sample.sh b/sample/config.sample.sh index 01084dd6..568e69dc 100644 --- a/sample/config.sample.sh +++ b/sample/config.sample.sh @@ -46,6 +46,8 @@ export PUSH_KEY="" export BARK_PUSH="" ## 下方填写推送声音设置,例如choo,具体值请在bark-推送铃声-查看所有铃声 export BARK_SOUND="" +## 下方填写推送消息分组,默认为"QingLong" +export BARK_GROUP="QingLong" ## 3. Telegram ## 下方填写自己申请@BotFather的Token,如10xxx4:AAFcqxxxxgER5uw diff --git a/sample/notify.js b/sample/notify.js index 4ca59b21..b21b33a0 100644 --- a/sample/notify.js +++ b/sample/notify.js @@ -32,6 +32,8 @@ let SCKEY = ''; let BARK_PUSH = ''; //BARK app推送铃声,铃声列表去APP查看复制填写 let BARK_SOUND = ''; +//BARK app推送消息的分组, 默认为"QingLong" +let BARK_GROUP = 'QingLong'; // =======================================telegram机器人通知设置区域=========================================== //此处填你telegram bot 的Token,telegram机器人通知推送必填项.例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw @@ -117,6 +119,9 @@ if (process.env.BARK_PUSH) { if (process.env.BARK_SOUND) { BARK_SOUND = process.env.BARK_SOUND; } + if (process.env.BARK_GROUP) { + BARK_GROUP = process.env.BARK_GROUP; + } } else { if ( BARK_PUSH && @@ -371,7 +376,7 @@ function BarkNotify(text, desp, params = {}) { const options = { url: `${BARK_PUSH}/${encodeURIComponent(text)}/${encodeURIComponent( desp, - )}?sound=${BARK_SOUND}&${querystring.stringify(params)}`, + )}?sound=${BARK_SOUND}&group=${BARK_GROUP}&${querystring.stringify(params)}`, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, From cad1d86caff547d4aee1812c2f448916bf99fdb2 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 12 Jul 2021 23:18:17 +0800 Subject: [PATCH 186/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtask=5Fbefore?= =?UTF-8?q?=E5=87=BA=E9=94=99=E4=BB=BB=E5=8A=A1=E4=B8=AD=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 15 +++++++------- back/loaders/express.ts | 2 +- docker/Dockerfile | 4 +++- shell/task.sh | 38 ++++++++++++++++++++++++++++++------ shell/update.sh | 29 ++++++++++++++++----------- 5 files changed, 62 insertions(+), 26 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 473d4cfb..d05ef027 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,12 +1,13 @@ name: PublishDockerImage on: - workflow_run: - workflows: - - BuildStatic - branches: - - master - types: - - completed + workflow_dispatch: + # workflow_run: + # workflows: + # - BuildStatic + # branches: + # - master + # types: + # - completed jobs: build: diff --git a/back/loaders/express.ts b/back/loaders/express.ts index 92714249..3ef5cf83 100644 --- a/back/loaders/express.ts +++ b/back/loaders/express.ts @@ -15,7 +15,7 @@ export default ({ app }: { app: Application }) => { app.use(bodyParser.urlencoded({ limit: '50mb', extended: true })); app.use( jwt({ secret: config.secret as string, algorithms: ['HS384'] }).unless({ - path: ['/api/login'], + path: ['/api/login', '/api/crons/status'], }), ); app.use((req, res, next) => { diff --git a/docker/Dockerfile b/docker/Dockerfile index 951ca658..80315c16 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -37,8 +37,10 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && cp -f .env.example .env \ && chmod 777 ${QL_DIR}/shell/*.sh \ && chmod 777 ${QL_DIR}/docker/*.sh \ - && npm install -g pm2 \ && npm install -g pnpm \ + && pnpm install -g pm2 \ + && pnpm install -g ts-node \ + && pnpm i -g typescript \ && rm -rf /root/.npm \ && pnpm install --prod \ && rm -rf /root/.pnpm-store \ diff --git a/shell/task.sh b/shell/task.sh index ee922618..a4dbfb95 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -14,6 +14,8 @@ define_program() { which_program="python3" elif [[ $p1 == *.sh ]]; then which_program="bash" + elif [[ $p1 == *.ts ]]; then + which_program="ts-node" else which_program="" fi @@ -91,11 +93,19 @@ run_normal() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + if [[ $(. $file_task_before) ]]; then + . $file_task_before + else + echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + fi timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path - . $file_task_after + if [[ $(. $file_task_after) ]]; then + . $file_task_after + else + echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -125,7 +135,11 @@ run_concurrent() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + if [[ $(. $file_task_before) ]]; then + . $file_task_before + else + echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + fi echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -a $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") @@ -135,7 +149,11 @@ run_concurrent() { timeout $command_timeout_time $which_program $p1 &>$single_log_path & done - . $file_task_after + if [[ $(. $file_task_after) ]]; then + . $file_task_after + else + echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -154,11 +172,19 @@ run_else() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + if [[ $(. $file_task_before) ]]; then + . $file_task_before + else + echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + fi timeout $command_timeout_time "$@" 2>&1 | tee -a $log_path - . $file_task_after + if [[ $(. $file_task_after) ]]; then + . $file_task_after + else + echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) diff --git a/shell/update.sh b/shell/update.sh index e1003f2f..423fa46e 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -234,15 +234,9 @@ usage() { ## 更新qinglong update_qinglong() { - local no_restart="$1" - echo -e "--------------------------------------------------------------\n" - if [ -f /ql/db/cookie.db ]; then - echo -e "检测到旧的db文件,拷贝为新db...\n" - mv /ql/db/cookie.db /ql/db/env.db - rm /ql/db/cookie.db - echo - fi + patch_version + local no_restart="$1" [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" git_pull_scripts $dir_root @@ -272,9 +266,8 @@ update_qinglong() { fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新$ql_static_repo成功...\n" - cd $ql_static_repo - commit_id=$(git rev-parse --short HEAD) - echo -e "\n当前静态资源版本 $commit_id...\n" + local static_version=$(cat /ql/src/version.ts | perl -pe "s|.*\'(.*)\';\.*|\1|" | head -1) + echo -e "\n当前版本 $static_version...\n" cd $dir_root rm -rf $dir_root/build && rm -rf $dir_root/dist cp -rf $ql_static_repo/* $dir_root @@ -290,6 +283,20 @@ update_qinglong() { } +patch_version() { + if [ -f /ql/db/cookie.db ]; then + echo -e "检测到旧的db文件,拷贝为新db...\n" + mv /ql/db/cookie.db /ql/db/env.db + rm /ql/db/cookie.db + echo + fi + + if ! type ts-node >/dev/null 2>&1; then + pnpm i -g ts-node + pnpm i -g typescript + fi +} + reload_pm2() { pm2 l >/dev/null 2>&1 From faf982b15669afe050d75bd31bcc9c63b7d5cba5 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 12 Jul 2021 23:18:56 +0800 Subject: [PATCH 187/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 54e24c6a..f9541295 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-068'; -export const changeLog = 'https://t.me/jiaolongwang/118'; +export const version = 'v2.8.0-069'; +export const changeLog = 'https://t.me/jiaolongwang/119'; From 52490bf320aba6c4e7054a3317979feeebdd18cd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 12 Jul 2021 23:32:07 +0800 Subject: [PATCH 188/247] =?UTF-8?q?=E5=9B=9E=E9=80=80task=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index a4dbfb95..ce2c3c98 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -93,19 +93,11 @@ run_normal() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ $(. $file_task_before) ]]; then - . $file_task_before - else - echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path - fi + . $file_task_before timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path - if [[ $(. $file_task_after) ]]; then - . $file_task_after - else - echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path - fi + . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -135,11 +127,8 @@ run_concurrent() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ $(. $file_task_before) ]]; then - . $file_task_before - else - echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path - fi + . $file_task_before + echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -a $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") @@ -149,11 +138,7 @@ run_concurrent() { timeout $command_timeout_time $which_program $p1 &>$single_log_path & done - if [[ $(. $file_task_after) ]]; then - . $file_task_after - else - echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path - fi + . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -172,19 +157,11 @@ run_else() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ $(. $file_task_before) ]]; then - . $file_task_before - else - echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path - fi + . $file_task_before timeout $command_timeout_time "$@" 2>&1 | tee -a $log_path - if [[ $(. $file_task_after) ]]; then - . $file_task_after - else - echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path - fi + . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) From 49045c39c7c083ff3c33b51a52c44332002ba259 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 13 Jul 2021 10:53:17 +0800 Subject: [PATCH 189/247] =?UTF-8?q?=E5=BF=BD=E7=95=A5ts=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=E8=AF=AD=E6=B3=95=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/task.sh b/shell/task.sh index ce2c3c98..3041d6fd 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -15,7 +15,7 @@ define_program() { elif [[ $p1 == *.sh ]]; then which_program="bash" elif [[ $p1 == *.ts ]]; then - which_program="ts-node" + which_program="ts-node-transpile-only" else which_program="" fi From 9ab702e344a7d436e4c3d42a2f3156e38e610b58 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 13 Jul 2021 17:43:41 +0800 Subject: [PATCH 190/247] =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=85=A8=E5=B1=80=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/Dockerfile | 3 +-- sample/extra.sample.sh | 2 ++ shell/share.sh | 22 +++++----------------- shell/update.sh | 3 +-- 4 files changed, 9 insertions(+), 21 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 80315c16..758fbb54 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -39,8 +39,7 @@ RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && chmod 777 ${QL_DIR}/docker/*.sh \ && npm install -g pnpm \ && pnpm install -g pm2 \ - && pnpm install -g ts-node \ - && pnpm i -g typescript \ + && pnpm install -g ts-node typescript tslib \ && rm -rf /root/.npm \ && pnpm install --prod \ && rm -rf /root/.pnpm-store \ diff --git a/sample/extra.sample.sh b/sample/extra.sample.sh index 6aea52b0..ac1597df 100644 --- a/sample/extra.sample.sh +++ b/sample/extra.sample.sh @@ -1,3 +1,5 @@ #!/usr/bin/env bash ## 添加你需要重启自动执行的任意命令,比如 ql repo +## 安装node依赖使用 pnpm install -g xxx xxx +## 安装python依赖使用 pip3 install xxx diff --git a/shell/share.sh b/shell/share.sh index 7a9e51cd..aa9aedc6 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -52,7 +52,10 @@ original_name=( notify.sh ) -## 导入配置文件 +init_env() { + export NODE_PATH=/usr/local/bin:/usr/local/pnpm-global/5/node_modules:/usr/local/lib/node_modules +} + import_config() { [ -f $file_config_user ] && . $file_config_user [ -f $file_env ] && . $file_env @@ -62,7 +65,6 @@ import_config() { file_extensions=${RepoFileExtensions:-"js py"} } -## 创建目录,$1:目录的绝对路径 make_dir() { local dir=$1 if [[ ! -d $dir ]]; then @@ -70,7 +72,6 @@ make_dir() { fi } -## 检测termux detect_termux() { if [[ ${ANDROID_RUNTIME_ROOT}${ANDROID_ROOT} ]] || [[ $PATH == *com.termux* ]]; then is_termux=1 @@ -79,18 +80,15 @@ detect_termux() { fi } -## 检测macos detect_macos() { [[ $(uname -s) == Darwin ]] && is_macos=1 || is_macos=0 } -## 生成随机数,$1:用来求余的数字 gen_random_num() { local divi=$1 echo $((${RANDOM} % $divi)) } -## 创建软连接的子函数,$1:软连接文件路径,$2:要连接的对象 link_shell_sub() { local link_path="$1" local original_path="$2" @@ -100,7 +98,6 @@ link_shell_sub() { fi } -## 创建软连接 link_shell() { if [[ $is_termux -eq 1 ]]; then local path="/data/data/com.termux/files/usr/bin/" @@ -117,7 +114,6 @@ link_shell() { fi } -## 定义各命令 define_cmd() { local cmd_prefix cmd_suffix if type task >/dev/null 2>&1; then @@ -140,7 +136,6 @@ define_cmd() { done } -## 修复配置文件 fix_config() { make_dir $dir_config make_dir $dir_log @@ -206,7 +201,6 @@ fix_config() { fi } -## npm install 子程序,判断是否为安卓,判断是否安装有pnpm npm_install_sub() { if [ $is_termux -eq 1 ]; then npm install --production --no-save --no-bin-links --registry=https://registry.npm.taobao.org || npm install --production --no-bin-links --no-save @@ -217,7 +211,6 @@ npm_install_sub() { fi } -## npm install,$1:package.json文件所在路径 npm_install_1() { local dir_current=$(pwd) local dir_work=$1 @@ -243,7 +236,6 @@ npm_install_2() { cd $dir_current } -## 比对两个文件,$1比$2新时,将$1复制为$2 diff_and_copy() { local copy_source=$1 local copy_to=$2 @@ -252,7 +244,6 @@ diff_and_copy() { fi } -## 更新依赖 update_depend() { local dir_current=$(pwd) @@ -270,7 +261,6 @@ update_depend() { cd $dir_current } -## 克隆脚本,$1:仓库地址,$2:仓库保存路径,$3:分支(可省略) git_clone_scripts() { local url=$1 local dir=$2 @@ -281,7 +271,6 @@ git_clone_scripts() { exit_status=$? } -## 更新脚本,$1:仓库保存路径 git_pull_scripts() { local dir_current=$(pwd) local dir_work="$1" @@ -296,7 +285,6 @@ git_pull_scripts() { cd $dir_current } -## 重置仓库remote url,docker专用,$1:要重置的目录,$2:要重置为的网址 reset_romote_url() { local dir_current=$(pwd) local dir_work=$1 @@ -313,7 +301,7 @@ reset_romote_url() { fi } -## 导入配置文件,检测平台,创建软连接,识别命令,修复配置文件 +init_env detect_termux detect_macos define_cmd diff --git a/shell/update.sh b/shell/update.sh index 423fa46e..04cad346 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -292,8 +292,7 @@ patch_version() { fi if ! type ts-node >/dev/null 2>&1; then - pnpm i -g ts-node - pnpm i -g typescript + pnpm i -g ts-node typescript tslib fi } From a6319698e2483d6290965840f98ad728a3535215 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 13 Jul 2021 17:44:01 +0800 Subject: [PATCH 191/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index f9541295..f8940d7f 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-069'; -export const changeLog = 'https://t.me/jiaolongwang/119'; +export const version = 'v2.8.0-070'; +export const changeLog = 'https://t.me/jiaolongwang/120'; From 1f42d0245cfd7b7ab2272d2f4205833e1ba9f1f0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 13 Jul 2021 17:54:10 +0800 Subject: [PATCH 192/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtask=5Fbefore?= =?UTF-8?q?=E5=BD=B1=E5=93=8D=E4=BB=BB=E5=8A=A1=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index 3041d6fd..a3db82c2 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -93,11 +93,19 @@ run_normal() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + if [[ ! $(. $file_task_before) ]]; then + . $file_task_before + else + echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + fi timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path - . $file_task_after + if [[ ! $(. $file_task_after) ]]; then + . $file_task_after + else + echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -127,8 +135,11 @@ run_concurrent() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before - + if [[ ! $(. $file_task_before) ]]; then + . $file_task_before + else + echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + fi echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -a $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") @@ -138,7 +149,11 @@ run_concurrent() { timeout $command_timeout_time $which_program $p1 &>$single_log_path & done - . $file_task_after + if [[ ! $(. $file_task_after) ]]; then + . $file_task_after + else + echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -157,11 +172,19 @@ run_else() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + if [[ ! $(. $file_task_before) ]]; then + . $file_task_before + else + echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + fi timeout $command_timeout_time "$@" 2>&1 | tee -a $log_path - . $file_task_after + if [[ ! $(. $file_task_after) ]]; then + . $file_task_after + else + echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) From dac694776d2c355ed2807830b7f49b342739aefa Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 14 Jul 2021 15:13:17 +0800 Subject: [PATCH 193/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9spawn=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index fbccceaf..1676274b 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -211,7 +211,7 @@ export default class CronService { cmdStr = `${cmdStr} now`; } - const cp = spawn(cmdStr, { shell: true, detached: true }); + const cp = spawn(cmdStr, { shell: '/bin/bash' }); this.cronDb.update( { _id }, { $set: { status: CrontabStatus.running, pid: cp.pid } }, From cc238dedbc743644815f58db8d6d844d23bbe9a4 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 14 Jul 2021 15:40:59 +0800 Subject: [PATCH 194/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9tee=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 4 ++-- shell/task.sh | 30 +++++++++++++++--------------- shell/update.sh | 14 +++++++------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index aeaa545f..b21bec24 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -170,9 +170,9 @@ update_cron() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "## 更新任务状态成功" | tee -a $log_path + echo -e "## 更新任务状态成功" | tee --output-error=warn -a $log_path else - echo -e "## 更新任务状态失败(${message})" | tee -a $log_path + echo -e "## 更新任务状态失败(${message})" | tee --output-error=warn -a $log_path fi } diff --git a/shell/task.sh b/shell/task.sh index a3db82c2..6d3d5e19 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -91,25 +91,25 @@ run_normal() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + echo -e "## 开始执行... $begin_time\n" | tee --output-error=warn -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" if [[ ! $(. $file_task_before) ]]; then . $file_task_before else - echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + echo -e "## task_before执行失败,自行检查\n" | tee --output-error=warn -a $log_path fi - timeout $command_timeout_time $which_program $p1 2>&1 | tee -a $log_path + timeout $command_timeout_time $which_program $p1 2>&1 | tee --output-error=warn -a $log_path if [[ ! $(. $file_task_after) ]]; then . $file_task_after else - echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + echo -e "## task_after执行失败,自行检查\n" | tee --output-error=warn -a $log_path fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee --output-error=warn -a $log_path } ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行 @@ -133,14 +133,14 @@ run_concurrent() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + echo -e "## 开始执行... $begin_time\n" | tee --output-error=warn -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" if [[ ! $(. $file_task_before) ]]; then . $file_task_before else - echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + echo -e "## task_before执行失败,自行检查\n" | tee --output-error=warn -a $log_path fi - echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -a $log_path + echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee --output-error=warn -a $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") for i in "${!array[@]}"; do @@ -152,12 +152,12 @@ run_concurrent() { if [[ ! $(. $file_task_after) ]]; then . $file_task_after else - echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + echo -e "## task_after执行失败,自行检查\n" | tee --output-error=warn -a $log_path fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee --output-error=warn -a $log_path } ## 运行其他命令 @@ -170,25 +170,25 @@ run_else() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee -a $log_path + echo -e "## 开始执行... $begin_time\n" | tee --output-error=warn -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" if [[ ! $(. $file_task_before) ]]; then . $file_task_before else - echo -e "## task_before执行失败,自行检查\n" | tee -a $log_path + echo -e "## task_before执行失败,自行检查\n" | tee --output-error=warn -a $log_path fi - timeout $command_timeout_time "$@" 2>&1 | tee -a $log_path + timeout $command_timeout_time "$@" 2>&1 | tee --output-error=warn -a $log_path if [[ ! $(. $file_task_after) ]]; then . $file_task_after else - echo -e "## task_after执行失败,自行检查\n" | tee -a $log_path + echo -e "## task_after执行失败,自行检查\n" | tee --output-error=warn -a $log_path fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee --output-error=warn -a $log_path } ## 命令检测 diff --git a/shell/update.sh b/shell/update.sh index 04cad346..9250cca5 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -403,11 +403,11 @@ main() { case $p1 in update) echo -e "## 开始执行... $begin_time\n" >> $log_path - update_qinglong "$2" | tee -a $log_path + update_qinglong "$2" | tee --output-error=warn -a $log_path ;; extra) echo -e "## 开始执行... $begin_time\n" >> $log_path - run_extra_shell | tee -a $log_path + run_extra_shell | tee --output-error=warn -a $log_path ;; repo) get_user_info @@ -415,7 +415,7 @@ main() { log_path="$dir_log/update/${log_time}_$name.log" echo -e "## 开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then - update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee -a $log_path + update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee --output-error=warn -a $log_path else echo -e "命令输入错误...\n" usage @@ -427,7 +427,7 @@ main() { log_path="$dir_log/update/${log_time}_$name.log" echo -e "## 开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then - update_raw "$p2" | tee -a $log_path + update_raw "$p2" | tee --output-error=warn -a $log_path else echo -e "命令输入错误...\n" usage @@ -435,15 +435,15 @@ main() { ;; rmlog) echo -e "## 开始执行... $begin_time\n" >> $log_path - . $dir_shell/rmlog.sh "$p2" | tee -a $log_path + . $dir_shell/rmlog.sh "$p2" | tee --output-error=warn -a $log_path ;; bot) echo -e "## 开始执行... $begin_time\n" >> $log_path - . $dir_shell/bot.sh | tee -a $log_path + . $dir_shell/bot.sh | tee --output-error=warn -a $log_path ;; check) echo -e "## 开始执行... $begin_time\n" >> $log_path - . $dir_shell/check.sh | tee -a $log_path + . $dir_shell/check.sh | tee --output-error=warn -a $log_path ;; *) echo -e "命令输入错误...\n" From 66266fd545cc62020730a948180d385bdfed4f24 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 16 Jul 2021 01:00:40 +0800 Subject: [PATCH 195/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20repo=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E6=96=87=E4=BB=B6=E7=9B=AE=E5=BD=95=E5=B5=8C=E5=A5=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 9250cca5..bd52a1b0 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -375,7 +375,12 @@ gen_list_repo() { files=$(echo "$files" | egrep -v $blackword) fi if [[ $dependence ]]; then - eval $cmd | sed 's/^..//' | egrep $dependence | xargs -i cp {} $dir_scripts + results=$(eval $cmd | sed 's/^..//' | egrep $dependence) + for _file in ${results}; do + file_path=$(dirname $_file) + make_dir "${dir_scripts}/${file_path}" + cp -f $_file "${dir_scripts}/${file_path}" + done fi for file in ${files}; do filename=$(basename $file) @@ -403,11 +408,11 @@ main() { case $p1 in update) echo -e "## 开始执行... $begin_time\n" >> $log_path - update_qinglong "$2" | tee --output-error=warn -a $log_path + update_qinglong "$2" | tee -p -a $log_path ;; extra) echo -e "## 开始执行... $begin_time\n" >> $log_path - run_extra_shell | tee --output-error=warn -a $log_path + run_extra_shell | tee -p -a $log_path ;; repo) get_user_info @@ -415,7 +420,7 @@ main() { log_path="$dir_log/update/${log_time}_$name.log" echo -e "## 开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then - update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee --output-error=warn -a $log_path + update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee -p -a $log_path else echo -e "命令输入错误...\n" usage @@ -427,7 +432,7 @@ main() { log_path="$dir_log/update/${log_time}_$name.log" echo -e "## 开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then - update_raw "$p2" | tee --output-error=warn -a $log_path + update_raw "$p2" | tee -p -a $log_path else echo -e "命令输入错误...\n" usage @@ -435,15 +440,15 @@ main() { ;; rmlog) echo -e "## 开始执行... $begin_time\n" >> $log_path - . $dir_shell/rmlog.sh "$p2" | tee --output-error=warn -a $log_path + . $dir_shell/rmlog.sh "$p2" | tee -p -a $log_path ;; bot) echo -e "## 开始执行... $begin_time\n" >> $log_path - . $dir_shell/bot.sh | tee --output-error=warn -a $log_path + . $dir_shell/bot.sh | tee -p -a $log_path ;; check) echo -e "## 开始执行... $begin_time\n" >> $log_path - . $dir_shell/check.sh | tee --output-error=warn -a $log_path + . $dir_shell/check.sh | tee -p -a $log_path ;; *) echo -e "命令输入错误...\n" From 9d8c592e694e637ed833c2f085ce37601b2f746e Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 17 Jul 2021 00:01:16 +0800 Subject: [PATCH 196/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E4=BB=BB=E5=8A=A1=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/loaders/initData.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/back/loaders/initData.ts b/back/loaders/initData.ts index f96b695f..732c5d64 100644 --- a/back/loaders/initData.ts +++ b/back/loaders/initData.ts @@ -47,19 +47,21 @@ export default async () => { // 初始化更新所有任务状态为空闲 cronDb.update( - { status: CrontabStatus.running }, + { status: { $in: [CrontabStatus.running, CrontabStatus.queued] } }, { $set: { status: CrontabStatus.idle } }, + { multi: true }, ); // 初始化时执行一次所有的ql repo 任务 cronDb .find({ command: /ql (repo|raw)/, + isDisabled: { $ne: 1 }, }) .exec((err, docs) => { for (let i = 0; i < docs.length; i++) { const doc = docs[i]; - if (doc && doc.isDisabled !== 1) { + if (doc) { exec(doc.command); } } From 20ddb5a3cf3628d5113b313ca13b79fe7a97d92d Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 17 Jul 2021 01:33:10 +0800 Subject: [PATCH 197/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtask=5Fbefore,=20task?= =?UTF-8?q?=5Fafter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 4 ++-- shell/task.sh | 42 +++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index b21bec24..a9ed9e06 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -170,9 +170,9 @@ update_cron() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "## 更新任务状态成功" | tee --output-error=warn -a $log_path + echo -e "## 更新任务状态成功" | tee -p -a $log_path else - echo -e "## 更新任务状态失败(${message})" | tee --output-error=warn -a $log_path + echo -e "## 更新任务状态失败(${message})" | tee -p -a $log_path fi } diff --git a/shell/task.sh b/shell/task.sh index 6d3d5e19..1bfb6fc6 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -91,25 +91,25 @@ run_normal() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee --output-error=warn -a $log_path + echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ ! $(. $file_task_before) ]]; then + if [[ ! $(. $file_task_before 1>/dev/null) ]]; then . $file_task_before else - echo -e "## task_before执行失败,自行检查\n" | tee --output-error=warn -a $log_path + echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path fi - timeout $command_timeout_time $which_program $p1 2>&1 | tee --output-error=warn -a $log_path + timeout $command_timeout_time $which_program $p1 2>&1 | tee -p -a $log_path - if [[ ! $(. $file_task_after) ]]; then + if [[ ! $(. $file_task_after 1>/dev/null) ]]; then . $file_task_after else - echo -e "## task_after执行失败,自行检查\n" | tee --output-error=warn -a $log_path + echo -e "## task_after执行失败,自行检查\n" | tee -p -a $log_path fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee --output-error=warn -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -p -a $log_path } ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行 @@ -133,14 +133,14 @@ run_concurrent() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee --output-error=warn -a $log_path + echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ ! $(. $file_task_before) ]]; then + if [[ ! $(. $file_task_before 1>/dev/null) ]]; then . $file_task_before else - echo -e "## task_before执行失败,自行检查\n" | tee --output-error=warn -a $log_path + echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path fi - echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee --output-error=warn -a $log_path + echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -p -a $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") for i in "${!array[@]}"; do @@ -149,15 +149,15 @@ run_concurrent() { timeout $command_timeout_time $which_program $p1 &>$single_log_path & done - if [[ ! $(. $file_task_after) ]]; then + if [[ ! $(. $file_task_after 1>/dev/null) ]]; then . $file_task_after else - echo -e "## task_after执行失败,自行检查\n" | tee --output-error=warn -a $log_path + echo -e "## task_after执行失败,自行检查\n" | tee -p -a $log_path fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee --output-error=warn -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -p -a $log_path } ## 运行其他命令 @@ -170,25 +170,25 @@ run_else() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee --output-error=warn -a $log_path + echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ ! $(. $file_task_before) ]]; then + if [[ ! $(. $file_task_before 1>/dev/null) ]]; then . $file_task_before else - echo -e "## task_before执行失败,自行检查\n" | tee --output-error=warn -a $log_path + echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path fi - timeout $command_timeout_time "$@" 2>&1 | tee --output-error=warn -a $log_path + timeout $command_timeout_time "$@" 2>&1 | tee -p -a $log_path - if [[ ! $(. $file_task_after) ]]; then + if [[ ! $(. $file_task_after 1>/dev/null) ]]; then . $file_task_after else - echo -e "## task_after执行失败,自行检查\n" | tee --output-error=warn -a $log_path + echo -e "## task_after执行失败,自行检查\n" | tee -p -a $log_path fi [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee --output-error=warn -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -p -a $log_path } ## 命令检测 From ecdfdff50d9d73e65422e53a85749f31a3a3c4cc Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 17 Jul 2021 22:20:08 +0800 Subject: [PATCH 198/247] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.tsx | 4 +-- src/layouts/defaultProps.tsx | 4 +-- src/layouts/index.less | 43 +++++++++++++++++++++++++++--- src/pages/crontab/index.tsx | 1 + src/pages/env/index.tsx | 5 ++-- src/pages/log/index.module.less | 2 +- src/pages/log/index.tsx | 39 ++++++++++++++++----------- src/pages/script/index.module.less | 2 +- src/pages/script/index.tsx | 10 +++++-- 9 files changed, 80 insertions(+), 30 deletions(-) diff --git a/src/app.tsx b/src/app.tsx index 5130b5f0..53313350 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -8,9 +8,9 @@ const titleMap: any = { '/crontab': '定时任务', '/env': '环境变量', '/config': '配置文件', - '/script': '查看脚本', + '/script': '脚本管理', '/diff': '对比工具', - '/log': '日志', + '/log': '任务日志', '/setting': '系统设置', }; diff --git a/src/layouts/defaultProps.tsx b/src/layouts/defaultProps.tsx index f2019f18..888cf247 100644 --- a/src/layouts/defaultProps.tsx +++ b/src/layouts/defaultProps.tsx @@ -38,7 +38,7 @@ export default { }, { path: '/script', - name: '查看脚本', + name: '脚本管理', icon: , component: '@/pages/script/index', }, @@ -50,7 +50,7 @@ export default { }, { path: '/log', - name: '日志', + name: '任务日志', icon: , component: '@/pages/log/index', }, diff --git a/src/layouts/index.less b/src/layouts/index.less index fab9c03b..8c8985f1 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -71,6 +71,34 @@ body { } } +.ant-tree { + .ant-tree-treenode { + width: 100%; + padding-right: 8px !important; + } + + .ant-tree-node-content-wrapper { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; + } +} + +.ant-select-tree { + .ant-select-tree-treenode { + width: 100%; + padding-right: 8px !important; + } + + .ant-select-tree-node-content-wrapper { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; + } +} + input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus, @@ -91,17 +119,17 @@ input:-webkit-autofill:active { .ql-container-wrapper { &.crontab-wrapper, - &.log-wrapper { + &.log-wrapper, + &.env-wrapper, + &.config-wrapper { .ant-pro-grid-content.wide .ant-pro-page-container-children-content { height: calc(100vh - 184px); height: calc(100vh - var(--vh-offset, 0px) - 184px); - margin-left: 0; - margin-right: 0; } .CodeMirror { height: calc(100vh - 216px); height: calc(100vh - var(--vh-offset, 0px) - 216px); - width: calc(100vw - 32px); + width: calc(100vw - 80px); } } .CodeMirror { @@ -114,3 +142,10 @@ input:-webkit-autofill:active { max-width: 250px !important; } } + +@media (min-width: 768px) { + .ant-layout-content.ant-pro-basicLayout-content.ant-pro-basicLayout-has-header { + min-height: calc(100vh - 72px); + min-height: calc(100vh - var(--vh-offset, 0px) - 72px); + } +} diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 175e021c..02c8689e 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -101,6 +101,7 @@ const Crontab = () => { key: 'status', dataIndex: 'status', align: 'center' as const, + width: 60, render: (text: string, record: any) => ( <> {(!record.isDisabled || record.status !== CrontabStatus.idle) && ( diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 833be0b1..55f1f344 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -108,6 +108,7 @@ const Env = () => { { title: '序号', align: 'center' as const, + width: 50, render: (text: string, record: any, index: number) => { return {index + 1} ; }, @@ -123,7 +124,7 @@ const Env = () => { dataIndex: 'value', key: 'value', align: 'center' as const, - width: '40%', + width: '44%', ellipsis: { showTitle: false, }, @@ -436,7 +437,7 @@ const Env = () => { return ( { const [filterData, setFilterData] = useState([]); const [loading, setLoading] = useState(false); const [isPhone, setIsPhone] = useState(false); + const [height, setHeight] = useState(); + const treeDom = useRef(); - const getConfig = () => { - request.get(`${config.apiPrefix}logs`).then((data) => { - const result = formatData(data.dirs) as any; - setData(result); - setFilterData(result); - }); + const getLogs = () => { + setLoading(true); + request + .get(`${config.apiPrefix}logs`) + .then((data) => { + const result = formatData(data.dirs) as any; + setData(result); + setFilterData(result); + }) + .finally(() => setLoading(false)); }; const formatData = (tree: any[]) => { @@ -73,13 +79,9 @@ const Log = () => { }; const getLog = (node: any) => { - setLoading(true); - request - .get(`${config.apiPrefix}logs/${node.value}`) - .then((data) => { - setValue(data.data); - }) - .finally(() => setLoading(false)); + request.get(`${config.apiPrefix}logs/${node.value}`).then((data) => { + setValue(data.data); + }); }; const onSelect = (value: any, node: any) => { @@ -113,13 +115,15 @@ const Log = () => { setMarginTop(-72); setIsPhone(false); } - getConfig(); + getLogs(); + setHeight(treeDom.current.clientHeight); }, []); return ( { className={styles['left-tree-search']} onChange={onSearch} > -
+
diff --git a/src/pages/script/index.module.less b/src/pages/script/index.module.less index b1f98948..d2dafec2 100644 --- a/src/pages/script/index.module.less +++ b/src/pages/script/index.module.less @@ -16,7 +16,7 @@ overflow: auto; } &-search { - margin-bottom: 16px; + margin-bottom: 8px; } } diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index ca419f83..1ac87134 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback, Key } from 'react'; +import { useState, useEffect, useCallback, Key, useRef } from 'react'; import { TreeSelect, Tree, Input } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; @@ -37,6 +37,8 @@ const Script = () => { const [loading, setLoading] = useState(false); const [isPhone, setIsPhone] = useState(false); const [mode, setMode] = useState(''); + const [height, setHeight] = useState(); + const treeDom = useRef(); const getScripts = () => { setLoading(true); @@ -89,6 +91,7 @@ const Script = () => { setIsPhone(false); } getScripts(); + setHeight(treeDom.current.clientHeight); }, []); return ( @@ -130,10 +133,13 @@ const Script = () => { className={styles['left-tree-search']} onChange={onSearch} > -
+
From 9320074a02fcd8b5a8ecab5a9c503a1dbcc8e2da Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 17 Jul 2021 22:24:29 +0800 Subject: [PATCH 199/247] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=BC=96=E8=BE=91=E9=BB=91=E5=90=8D=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/config/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/back/config/index.ts b/back/config/index.ts index 96bee0b4..fa127dc8 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -60,5 +60,11 @@ export default { configPath, scriptPath, samplePath, - blackFileList: ['auth.json', 'config.sh.sample', 'cookie.sh', 'crontab.list'], + blackFileList: [ + 'auth.json', + 'config.sh.sample', + 'cookie.sh', + 'crontab.list', + 'env.sh', + ], }; From b183e9cd2949f46566c25264b84e2452972fbede Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 20 Jul 2021 00:10:18 +0800 Subject: [PATCH 200/247] =?UTF-8?q?=E5=A2=9E=E5=8A=A0codemirror=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .umirc.ts | 3 +++ shell/task.sh | 48 +++++++++++++++++++++++------------------- src/layouts/index.less | 1 + 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/.umirc.ts b/.umirc.ts index 976e87d6..de1437d9 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -39,5 +39,8 @@ export default defineConfig({ 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/shell/shell.js', 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/python/python.js', 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/javascript/javascript.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/addon/dialog/dialog.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/addon/search/search.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/addon/search/searchcursor.js', ], }); diff --git a/shell/task.sh b/shell/task.sh index 1bfb6fc6..263565d3 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -99,7 +99,7 @@ run_normal() { echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path fi - timeout $command_timeout_time $which_program $p1 2>&1 | tee -p -a $log_path + timeout -k 10s $command_timeout_time $which_program $p1 2>&1 | tee -p -a $log_path if [[ ! $(. $file_task_after 1>/dev/null) ]]; then . $file_task_after @@ -145,8 +145,8 @@ run_concurrent() { single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") for i in "${!array[@]}"; do export ${p3}=${array[i]} - single_log_path="$log_dir/${single_log_time}_$((i+1)).log" - timeout $command_timeout_time $which_program $p1 &>$single_log_path & + single_log_path="$log_dir/${single_log_time}_$((i + 1)).log" + timeout -k 10s $command_timeout_time $which_program $p1 &>$single_log_path & done if [[ ! $(. $file_task_after 1>/dev/null) ]]; then @@ -178,7 +178,7 @@ run_else() { echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path fi - timeout $command_timeout_time "$@" 2>&1 | tee -p -a $log_path + timeout -k 10s $command_timeout_time bash -c "$@" 2>&1 | tee -p -a $log_path if [[ ! $(. $file_task_after 1>/dev/null) ]]; then . $file_task_after @@ -193,31 +193,35 @@ run_else() { ## 命令检测 main() { - case $# in - 0) - echo - usage - ;; - 1) - run_normal $1 - ;; - 2|3) - case $2 in - now) - run_normal $1 $2 + if [[ $1 == *.js ]] || [[ $1 == *.py ]] || [[ $1 == *.sh ]] || [[ $1 == *.ts ]]; then + case $# in + 0) + echo + usage ;; - conc) - run_concurrent $1 $2 $3 + 1) + run_normal $1 + ;; + 2 | 3) + case $2 in + now) + run_normal $1 $2 + ;; + conc) + run_concurrent $1 $2 $3 + ;; + *) + run_else "$@" + ;; + esac ;; *) run_else "$@" ;; esac - ;; - *) + else run_else "$@" - ;; - esac + fi } main "$@" diff --git a/src/layouts/index.less b/src/layouts/index.less index 8c8985f1..fe57adbc 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -14,6 +14,7 @@ body { } @import '~codemirror/lib/codemirror.css'; +@import '~codemirror/addon/dialog/dialog.css'; .ql-container-wrapper { .CodeMirror { From 7ced425e01f4554e0a072de91761970ac08a5aa9 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 22 Jul 2021 19:13:54 +0800 Subject: [PATCH 201/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9task=5Fbefore?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 38 +++++++------------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index 263565d3..caff733e 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -93,19 +93,11 @@ run_normal() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ ! $(. $file_task_before 1>/dev/null) ]]; then - . $file_task_before - else - echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path - fi + . $file_task_before timeout -k 10s $command_timeout_time $which_program $p1 2>&1 | tee -p -a $log_path - if [[ ! $(. $file_task_after 1>/dev/null) ]]; then - . $file_task_after - else - echo -e "## task_after执行失败,自行检查\n" | tee -p -a $log_path - fi + . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -135,11 +127,7 @@ run_concurrent() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ ! $(. $file_task_before 1>/dev/null) ]]; then - . $file_task_before - else - echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path - fi + . $file_task_before echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -p -a $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") @@ -149,11 +137,7 @@ run_concurrent() { timeout -k 10s $command_timeout_time $which_program $p1 &>$single_log_path & done - if [[ ! $(. $file_task_after 1>/dev/null) ]]; then - . $file_task_after - else - echo -e "## task_after执行失败,自行检查\n" | tee -p -a $log_path - fi + . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -172,19 +156,11 @@ run_else() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - if [[ ! $(. $file_task_before 1>/dev/null) ]]; then - . $file_task_before - else - echo -e "## task_before执行失败,自行检查\n" | tee -p -a $log_path - fi + . $file_task_before - timeout -k 10s $command_timeout_time bash -c "$@" 2>&1 | tee -p -a $log_path + timeout -k 10s $command_timeout_time "$@" 2>&1 | tee -p -a $log_path - if [[ ! $(. $file_task_after 1>/dev/null) ]]; then - . $file_task_after - else - echo -e "## task_after执行失败,自行检查\n" | tee -p -a $log_path - fi + . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) From 1614f3c8ad1f961fc24789753a882543d053fbdb Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 22 Jul 2021 22:00:53 +0800 Subject: [PATCH 202/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index f8940d7f..d1f76a9f 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-070'; -export const changeLog = 'https://t.me/jiaolongwang/120'; +export const version = 'v2.8.0-071'; +export const changeLog = 'https://t.me/jiaolongwang/121'; From eff109bf81163d68f447b02aebfb389bbb99f6b9 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 24 Jul 2021 23:17:33 +0800 Subject: [PATCH 203/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbot.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/bot.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/bot.sh b/shell/bot.sh index 373ec42c..02d20f3e 100644 --- a/shell/bot.sh +++ b/shell/bot.sh @@ -30,6 +30,7 @@ if [[ $PipMirror ]]; then pip3 config set global.index-url $PipMirror fi cp -f "$repo_path/jbot/requirements.txt" "$dir_root" +cd $dir_root pip3 --default-timeout=100 install -r requirements.txt --no-cache-dir echo -e "\npython3依赖安装成功...\n" From fd7153403df0eb0dc0d1bb510ed4c281cf9866c2 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 26 Jul 2021 00:26:14 +0800 Subject: [PATCH 204/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95monaco=E4=BB=A3?= =?UTF-8?q?=E6=9B=BFcodemirror?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .umirc.ts | 10 +---- package.json | 6 +-- pnpm-lock.yaml | 67 ++++++++++++++++++++++-------- src/layouts/index.less | 48 ++++++++++++++------- src/pages/config/index.tsx | 37 ++++++++++++----- src/pages/crontab/logModal.tsx | 61 ++++++++++++++++----------- src/pages/diff/index.tsx | 60 +++++++++++++------------- src/pages/log/index.module.less | 8 +--- src/pages/log/index.tsx | 37 ++++++++++++----- src/pages/script/index.module.less | 8 +--- src/pages/script/index.tsx | 38 ++++++++++++----- 11 files changed, 235 insertions(+), 145 deletions(-) diff --git a/.umirc.ts b/.umirc.ts index de1437d9..03d7b666 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -28,19 +28,11 @@ export default defineConfig({ externals: { react: 'window.React', 'react-dom': 'window.ReactDOM', - codemirror: 'window.CodeMirror', darkreader: 'window.DarkReader', }, scripts: [ 'https://gw.alipayobjects.com/os/lib/react/16.13.1/umd/react.production.min.js', 'https://gw.alipayobjects.com/os/lib/react-dom/16.13.1/umd/react-dom.production.min.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/lib/codemirror.min.js', - 'https://cdn.jsdelivr.net/npm/darkreader@4.9.27/darkreader.min.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/shell/shell.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/python/python.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/javascript/javascript.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/addon/dialog/dialog.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/addon/search/search.js', - 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/addon/search/searchcursor.js', + 'https://cdn.jsdelivr.net/npm/darkreader@4.9.34/darkreader.min.js', ], }); diff --git a/package.json b/package.json index bcf18966..d6a04a0e 100644 --- a/package.json +++ b/package.json @@ -32,18 +32,19 @@ "express": "^4.17.1", "express-jwt": "^6.0.0", "jsonwebtoken": "^8.5.1", + "lodash": "^4.17.21", "nedb": "^1.8.0", "node-fetch": "^2.6.1", "node-schedule": "^2.0.0", "p-queue": "6.6.2", "reflect-metadata": "^0.1.13", "typedi": "^0.8.0", - "lodash": "^4.17.21", "winston": "^3.3.3" }, "devDependencies": { "@ant-design/icons": "^4.6.2", "@ant-design/pro-layout": "^6.5.0", + "@monaco-editor/react": "^4.2.1", "@types/cors": "^2.8.10", "@types/express": "^4.17.8", "@types/express-jwt": "^6.0.1", @@ -57,7 +58,6 @@ "@types/react-dom": "^17.0.0", "@umijs/plugin-antd": "^0.9.1", "@umijs/test": "^3.3.9", - "codemirror": "^5.59.4", "compression-webpack-plugin": "6.1.1", "darkreader": "^4.9.27", "lint-staged": "^10.0.7", @@ -65,11 +65,11 @@ "prettier": "^2.2.0", "qrcode.react": "^1.0.1", "react": "17.x", - "react-codemirror2": "^7.2.1", "react-diff-viewer": "^3.1.1", "react-dnd": "^14.0.2", "react-dnd-html5-backend": "^14.0.0", "react-dom": "17.x", + "react-split-pane": "^0.1.92", "ts-node": "^9.0.0", "typescript": "^4.1.2", "umi": "^3.3.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89bf8207..c3fdd954 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,6 +3,7 @@ lockfileVersion: 5.3 specifiers: '@ant-design/icons': ^4.6.2 '@ant-design/pro-layout': ^6.5.0 + '@monaco-editor/react': ^4.2.1 '@types/cors': ^2.8.10 '@types/express': ^4.17.8 '@types/express-jwt': ^6.0.1 @@ -18,7 +19,6 @@ specifiers: '@umijs/test': ^3.3.9 body-parser: ^1.19.0 celebrate: ^13.0.3 - codemirror: ^5.59.4 compression-webpack-plugin: 6.1.1 cors: ^2.8.5 cron-parser: ^3.5.0 @@ -37,11 +37,11 @@ specifiers: prettier: ^2.2.0 qrcode.react: ^1.0.1 react: 17.x - react-codemirror2: ^7.2.1 react-diff-viewer: ^3.1.1 react-dnd: ^14.0.2 react-dnd-html5-backend: ^14.0.0 react-dom: 17.x + react-split-pane: ^0.1.92 reflect-metadata: ^0.1.13 ts-node: ^9.0.0 typedi: ^0.8.0 @@ -74,6 +74,7 @@ dependencies: devDependencies: '@ant-design/icons': 4.6.2_react-dom@17.0.2+react@17.0.2 '@ant-design/pro-layout': 6.18.0_react-dom@17.0.2+react@17.0.2 + '@monaco-editor/react': 4.2.1_react-dom@17.0.2+react@17.0.2 '@types/cors': 2.8.10 '@types/express': 4.17.11 '@types/express-jwt': 6.0.1 @@ -87,7 +88,6 @@ devDependencies: '@types/react-dom': 17.0.5 '@umijs/plugin-antd': 0.9.1_5ccfec03b6e15849b3687a64fe975f75 '@umijs/test': 3.4.20_ts-node@9.1.1 - codemirror: 5.61.0 compression-webpack-plugin: 6.1.1_webpack@5.37.0 darkreader: 4.9.32 lint-staged: 10.5.4 @@ -95,11 +95,11 @@ devDependencies: prettier: 2.3.0 qrcode.react: 1.0.1_react@17.0.2 react: 17.0.2 - react-codemirror2: 7.2.1_codemirror@5.61.0+react@17.0.2 react-diff-viewer: 3.1.1_react-dom@17.0.2+react@17.0.2 react-dnd: 14.0.2_695545ed68ea337339babea285839fc0 react-dnd-html5-backend: 14.0.0 react-dom: 17.0.2_react@17.0.2 + react-split-pane: 0.1.92_react-dom@17.0.2+react@17.0.2 ts-node: 9.1.1_typescript@4.2.4 typescript: 4.2.4 umi: 3.4.20 @@ -866,6 +866,28 @@ packages: chalk: 4.1.1 dev: true + /@monaco-editor/loader/1.1.1: + resolution: {integrity: sha512-mkT4r4xDjIyOG9o9M6rJDSzEIeonwF80sYErxEvAAL4LncFVdcbNli8Qv6NDqF6nyv6sunuKkDzo4iFjxPL+uQ==} + peerDependencies: + monaco-editor: '>= 0.21.0 < 1' + dependencies: + state-local: 1.0.7 + dev: true + + /@monaco-editor/react/4.2.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-yN8qVY0PyFIbqPjfrZ5TbR/wrcfeiwoys8+0QkmyfiOzG74vXxSBOPIUxk7Ly+qCj7qWHPq1uDJskzFGaIqaPA==} + peerDependencies: + monaco-editor: '>= 0.25.0 < 1' + react: ^16.8.0 || ^17.0.0 + react-dom: ^16.8.0 || ^17.0.0 + dependencies: + '@monaco-editor/loader': 1.1.1 + prop-types: 15.7.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + state-local: 1.0.7 + dev: true + /@npmcli/move-file/1.1.2: resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} engines: {node: '>=10'} @@ -2546,10 +2568,6 @@ packages: engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} dev: true - /codemirror/5.61.0: - resolution: {integrity: sha512-D3wYH90tYY1BsKlUe0oNj2JAhQ9TepkD51auk3N7q+4uz7A/cgJ5JsWHreT0PqieW1QhOuqxQ2reCXV1YXzecg==} - dev: true - /collect-v8-coverage/1.0.1: resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} dev: true @@ -7592,16 +7610,6 @@ packages: strip-json-comments: 2.0.1 dev: true - /react-codemirror2/7.2.1_codemirror@5.61.0+react@17.0.2: - resolution: {integrity: sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==} - peerDependencies: - codemirror: 5.x - react: '>=15.5 <=16.x' - dependencies: - codemirror: 5.61.0 - react: 17.0.2 - dev: true - /react-diff-viewer/3.1.1_react-dom@17.0.2+react@17.0.2: resolution: {integrity: sha512-rmvwNdcClp6ZWdS11m1m01UnBA4OwYaLG/li0dB781e/bQEzsGyj+qewVd6W5ztBwseQ72pO7nwaCcq5jnlzcw==} engines: {node: '>= 8'} @@ -7743,6 +7751,25 @@ packages: tiny-warning: 1.0.3 dev: true + /react-split-pane/0.1.92_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-GfXP1xSzLMcLJI5BM36Vh7GgZBpy+U/X0no+VM3fxayv+p1Jly5HpMofZJraeaMl73b3hvlr+N9zJKvLB/uz9w==} + peerDependencies: + react: ^16.0.0-0 + react-dom: ^16.0.0-0 + dependencies: + prop-types: 15.7.2 + react: 17.0.2 + react-dom: 17.0.2_react@17.0.2 + react-lifecycles-compat: 3.0.4 + react-style-proptype: 3.2.2 + dev: true + + /react-style-proptype/3.2.2: + resolution: {integrity: sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==} + dependencies: + prop-types: 15.7.2 + dev: true + /react-tween-state/0.1.5: resolution: {integrity: sha1-6YsGZVHvuTy5LdG+FJlcLj3q4zk=} dependencies: @@ -8595,6 +8622,10 @@ packages: escape-string-regexp: 2.0.0 dev: true + /state-local/1.0.7: + resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} + dev: true + /static-extend/0.1.2: resolution: {integrity: sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=} engines: {node: '>=0.10.0'} diff --git a/src/layouts/index.less b/src/layouts/index.less index fe57adbc..518db753 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -13,15 +13,32 @@ body { background-color: rgb(248, 248, 248); } -@import '~codemirror/lib/codemirror.css'; -@import '~codemirror/addon/dialog/dialog.css'; +.ant-modal { + padding-bottom: 0 !important; + width: 580px !important; +} -.ql-container-wrapper { - .CodeMirror { - position: absolute; - height: calc(100vh - 128px); - height: calc(100vh - var(--vh-offset, 0px) - 128px); - width: calc(100% - 32px); +.monaco-editor:not(.rename-box) { + height: calc(100vh - 128px) !important; + height: calc(100vh - var(--vh-offset, 0px) - 128px) !important; + .view-overlays .current-line{ + border-width: 0; + } +} + +.log-modal { + .monaco-editor:not(.rename-box) { + height: calc(100vh - 176px) !important; + height: calc(100vh - var(--vh-offset, 0px) - 176px) !important; + background-color: transparent !important; + } +} + +.rename-box { + height: 0; + .rename-input{ + height: 0; + padding: 0 !important; } } @@ -29,7 +46,7 @@ body { max-width: unset !important; overflow: auto; .ant-pro-page-container-children-content { - overflow: auto; + overflow: visible; height: calc(100vh - 96px); height: calc(100vh - var(--vh-offset, 0px) - 96px); background-color: #fff; @@ -127,15 +144,14 @@ input:-webkit-autofill:active { height: calc(100vh - 184px); height: calc(100vh - var(--vh-offset, 0px) - 184px); } - .CodeMirror { - height: calc(100vh - 216px); - height: calc(100vh - var(--vh-offset, 0px) - 216px); - width: calc(100vw - 80px); + .monaco-editor:not(.rename-box) { + height: calc(100vh - 216px) !important; + height: calc(100vh - var(--vh-offset, 0px) - 216px) !important; } } - .CodeMirror { - height: calc(100vh - 176px); - height: calc(100vh - var(--vh-offset, 0px) - 176px); + .monaco-editor:not(.rename-box) { + height: calc(100vh - 176px) !important; + height: calc(100vh - var(--vh-offset, 0px) - 176px) !important; } } diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 34fb9215..bcfc70b2 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -2,8 +2,8 @@ import React, { PureComponent, Fragment, useState, useEffect } from 'react'; import { Button, message, Modal, TreeSelect } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; -import { Controlled as CodeMirror } from 'react-codemirror2'; import { request } from '@/utils/http'; +import Editor from "@monaco-editor/react"; const Config = () => { const [width, setWidth] = useState('100%'); @@ -14,6 +14,7 @@ const Config = () => { const [title, setTitle] = useState('config.sh'); const [select, setSelect] = useState('config.sh'); const [data, setData] = useState([]); + const [theme, setTheme] = useState(''); const getConfig = (name: string) => { request.get(`${config.apiPrefix}configs/${name}`).then((data: any) => { @@ -61,6 +62,22 @@ const Config = () => { getConfig('config.sh'); }, []); + useEffect(()=>{ + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark?'vs-dark':'vs'); + media.addEventListener('change',(e)=>{ + if(storageTheme === 'auto' || !storageTheme){ + if(e.matches){ + setTheme('vs-dark') + }else{ + setTheme('vs'); + } + } + }) + },[]) + return ( { }, }} > - { - setValue(value); - }} - onChange={(editor, data, value) => {}} + onChange={(val) => {setValue(val as string)}} /> ); diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 015a3e99..cc67d2e5 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -6,7 +6,7 @@ import { Loading3QuartersOutlined, CheckCircleOutlined, } from '@ant-design/icons'; -import { Controlled as CodeMirror } from 'react-codemirror2'; +import Editor from "@monaco-editor/react"; enum CrontabStatus { 'running', @@ -28,6 +28,7 @@ const CronLogModal = ({ const [loading, setLoading] = useState(true); const [excuting, setExcuting] = useState(true); const [isPhone, setIsPhone] = useState(false); + const [theme, setTheme] = useState(''); const getCronLog = (isFirst?: boolean) => { if (isFirst) { @@ -91,40 +92,50 @@ const CronLogModal = ({ setIsPhone(document.body.clientWidth < 768); }, []); + useEffect(()=>{ + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark?'vs-dark':'vs'); + media.addEventListener('change',(e)=>{ + if(storageTheme === 'auto' || !storageTheme){ + if(e.matches){ + setTheme('vs-dark') + }else{ + setTheme('vs'); + } + } + }) + },[]) + return ( cancel()} onCancel={() => cancel()} > {!loading && value && ( -
-          {value}
-        
+ )}
); diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index f67ae103..db774adf 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -5,6 +5,7 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import ReactDiffViewer from 'react-diff-viewer'; import './index.less'; +import { DiffEditor } from "@monaco-editor/react"; const Crontab = () => { const [width, setWidth] = useState('100%'); @@ -13,6 +14,7 @@ const Crontab = () => { const [value, setValue] = useState(''); const [sample, setSample] = useState(''); const [loading, setLoading] = useState(true); + const [theme, setTheme] = useState(''); const getConfig = () => { request.get(`${config.apiPrefix}configs/config.sh`).then((data) => { @@ -44,6 +46,22 @@ const Crontab = () => { getSample(); }, []); + useEffect(()=>{ + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark?'vs-dark':'vs'); + media.addEventListener('change',(e)=>{ + if(storageTheme === 'auto' || !storageTheme){ + if(e.matches){ + setTheme('vs-dark') + }else{ + setTheme('vs'); + } + } + }) + },[]) + return ( { }, }} > - - {/* */} ); }; diff --git a/src/pages/log/index.module.less b/src/pages/log/index.module.less index d2dafec2..73ee7c51 100644 --- a/src/pages/log/index.module.less +++ b/src/pages/log/index.module.less @@ -14,9 +14,7 @@ &-scroller { flex: 1; overflow: auto; - } - &-search { - margin-bottom: 8px; + border-right: 1px dashed #f0f0f0; } } @@ -29,9 +27,5 @@ .ant-pro-grid-content.wide .ant-pro-page-container-children-content { background-color: #f8f8f8; } - - .CodeMirror { - width: calc(100% - 32px - @tree-width); - } } } diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index 1f86ab6e..133beb9e 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback, Key, useRef } from 'react'; import { TreeSelect, Tree, Input } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; -import { Controlled as CodeMirror } from 'react-codemirror2'; +import Editor from "@monaco-editor/react"; import { request } from '@/utils/http'; import styles from './index.module.less'; @@ -48,6 +48,7 @@ const Log = () => { const [isPhone, setIsPhone] = useState(false); const [height, setHeight] = useState(); const treeDom = useRef(); + const [theme, setTheme] = useState(''); const getLogs = () => { setLoading(true); @@ -119,6 +120,22 @@ const Log = () => { setHeight(treeDom.current.clientHeight); }, []); + useEffect(()=>{ + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark?'vs-dark':'vs'); + media.addEventListener('change',(e)=>{ + if(storageTheme === 'auto' || !storageTheme){ + if(e.matches){ + setTheme('vs-dark') + }else{ + setTheme('vs'); + } + } + }) + },[]) + return ( {
)} - { - setValue(value); - }} - onChange={(editor, data, value) => {}} + onChange={(val, ev) => {setValue(val as string)}} />
diff --git a/src/pages/script/index.module.less b/src/pages/script/index.module.less index d2dafec2..73ee7c51 100644 --- a/src/pages/script/index.module.less +++ b/src/pages/script/index.module.less @@ -14,9 +14,7 @@ &-scroller { flex: 1; overflow: auto; - } - &-search { - margin-bottom: 8px; + border-right: 1px dashed #f0f0f0; } } @@ -29,9 +27,5 @@ .ant-pro-grid-content.wide .ant-pro-page-container-children-content { background-color: #f8f8f8; } - - .CodeMirror { - width: calc(100% - 32px - @tree-width); - } } } diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 1ac87134..6e2d6872 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback, Key, useRef } from 'react'; import { TreeSelect, Tree, Input } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; -import { Controlled as CodeMirror } from 'react-codemirror2'; +import Editor from "@monaco-editor/react"; import { request } from '@/utils/http'; import styles from './index.module.less'; @@ -39,6 +39,7 @@ const Script = () => { const [mode, setMode] = useState(''); const [height, setHeight] = useState(); const treeDom = useRef(); + const [theme, setTheme] = useState(''); const getScripts = () => { setLoading(true); @@ -94,6 +95,22 @@ const Script = () => { setHeight(treeDom.current.clientHeight); }, []); + useEffect(()=>{ + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark?'vs-dark':'vs'); + media.addEventListener('change',(e)=>{ + if(storageTheme === 'auto' || !storageTheme){ + if(e.matches){ + setTheme('vs-dark') + }else{ + setTheme('vs'); + } + } + }) + },[]) + return ( { )} - { - setValue(value); - }} - onChange={(editor, data, value) => {}} + onChange={(val) => {setValue(val as string)}} /> From c77e302874666d4d2e838b87ca8737a4461b0610 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 26 Jul 2021 00:56:53 +0800 Subject: [PATCH 205/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BC=B9=E6=A1=86?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/crontab/logModal.tsx | 59 ++++++++++++++-------------------- src/pages/diff/index.tsx | 3 +- src/pages/log/index.tsx | 4 ++- src/pages/script/index.tsx | 3 +- 4 files changed, 31 insertions(+), 38 deletions(-) diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index cc67d2e5..dcbbd964 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -6,7 +6,6 @@ import { Loading3QuartersOutlined, CheckCircleOutlined, } from '@ant-design/icons'; -import Editor from "@monaco-editor/react"; enum CrontabStatus { 'running', @@ -92,50 +91,40 @@ const CronLogModal = ({ setIsPhone(document.body.clientWidth < 768); }, []); - useEffect(()=>{ - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark?'vs-dark':'vs'); - media.addEventListener('change',(e)=>{ - if(storageTheme === 'auto' || !storageTheme){ - if(e.matches){ - setTheme('vs-dark') - }else{ - setTheme('vs'); - } - } - }) - },[]) - return ( cancel()} onCancel={() => cancel()} > {!loading && value && ( - +
+          {value}
+        
)}
); diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index db774adf..e2f11d8b 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -91,7 +91,8 @@ const Crontab = () => { lineNumbersMinChars: 3, folding: false, glyphMargin: false, - renderSideBySide: width==='100%' + renderSideBySide: width==='100%', + wordWrap: 'on' }} theme={theme} /> diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index 133beb9e..f2a1cea0 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -196,8 +196,10 @@ const Log = () => { fontSize: 12, minimap: {enabled: width==='100%'}, lineNumbersMinChars: 3, + fontFamily: 'Source Code Pro', folding: false, - glyphMargin: false + glyphMargin: false, + wordWrap: 'on' }} onChange={(val, ev) => {setValue(val as string)}} /> diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 6e2d6872..0f908359 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -172,7 +172,8 @@ const Script = () => { minimap: {enabled: width==='100%'}, lineNumbersMinChars: 3, folding: false, - glyphMargin: false + glyphMargin: false, + wordWrap: 'on' }} onChange={(val) => {setValue(val as string)}} /> From 9d89ecc51ee993825c4ff4a10be8e0a8d4d76d1a Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 26 Jul 2021 01:06:27 +0800 Subject: [PATCH 206/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtask=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 7 +++---- src/pages/script/index.tsx | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/shell/task.sh b/shell/task.sh index caff733e..ada9024e 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -171,10 +171,6 @@ run_else() { main() { if [[ $1 == *.js ]] || [[ $1 == *.py ]] || [[ $1 == *.sh ]] || [[ $1 == *.ts ]]; then case $# in - 0) - echo - usage - ;; 1) run_normal $1 ;; @@ -195,6 +191,9 @@ main() { run_else "$@" ;; esac + elif [[ $# -eq 0]]; then + echo + usage else run_else "$@" fi diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 0f908359..35ad05de 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -173,7 +173,6 @@ const Script = () => { lineNumbersMinChars: 3, folding: false, glyphMargin: false, - wordWrap: 'on' }} onChange={(val) => {setValue(val as string)}} /> From da70b0799ac5003ccb4cdb88d1274696ba797bdc Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 26 Jul 2021 08:37:35 +0800 Subject: [PATCH 207/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtask.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/task.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/task.sh b/shell/task.sh index ada9024e..359ba3e4 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -191,7 +191,7 @@ main() { run_else "$@" ;; esac - elif [[ $# -eq 0]]; then + elif [[ $# -eq 0 ]]; then echo usage else From 105c0f802fda7306ad1b7e552b7b96fb16ca4647 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 26 Jul 2021 22:57:59 +0800 Subject: [PATCH 208/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dwindows=E6=8D=A2?= =?UTF-8?q?=E8=A1=8C=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/config/index.tsx | 31 +++++++++++++++++-------------- src/pages/log/index.tsx | 31 +++++++++++++++++-------------- src/pages/script/index.tsx | 31 ++++++++++++++++++------------- 3 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index bcfc70b2..031cce9e 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -3,7 +3,7 @@ import { Button, message, Modal, TreeSelect } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; -import Editor from "@monaco-editor/react"; +import Editor from '@monaco-editor/react'; const Config = () => { const [width, setWidth] = useState('100%'); @@ -62,21 +62,22 @@ const Config = () => { getConfig('config.sh'); }, []); - useEffect(()=>{ + useEffect(() => { const media = window.matchMedia('(prefers-color-scheme: dark)'); const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark?'vs-dark':'vs'); - media.addEventListener('change',(e)=>{ - if(storageTheme === 'auto' || !storageTheme){ - if(e.matches){ - setTheme('vs-dark') - }else{ + const isDark = + (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark ? 'vs-dark' : 'vs'); + media.addEventListener('change', (e) => { + if (storageTheme === 'auto' || !storageTheme) { + if (e.matches) { + setTheme('vs-dark'); + } else { setTheme('vs'); } } - }) - },[]) + }); + }, []); return ( { theme={theme} options={{ fontSize: 12, - minimap: {enabled: width==='100%'}, + minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, - glyphMargin: false + glyphMargin: false, + }} + onChange={(val) => { + setValue((val as string).replace(/\r\n/g, '\n')); }} - onChange={(val) => {setValue(val as string)}} /> ); diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index f2a1cea0..d91f044d 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback, Key, useRef } from 'react'; import { TreeSelect, Tree, Input } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; -import Editor from "@monaco-editor/react"; +import Editor from '@monaco-editor/react'; import { request } from '@/utils/http'; import styles from './index.module.less'; @@ -120,21 +120,22 @@ const Log = () => { setHeight(treeDom.current.clientHeight); }, []); - useEffect(()=>{ + useEffect(() => { const media = window.matchMedia('(prefers-color-scheme: dark)'); const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark?'vs-dark':'vs'); - media.addEventListener('change',(e)=>{ - if(storageTheme === 'auto' || !storageTheme){ - if(e.matches){ - setTheme('vs-dark') - }else{ + const isDark = + (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark ? 'vs-dark' : 'vs'); + media.addEventListener('change', (e) => { + if (storageTheme === 'auto' || !storageTheme) { + if (e.matches) { + setTheme('vs-dark'); + } else { setTheme('vs'); } } - }) - },[]) + }); + }, []); return ( { options={{ readOnly: true, fontSize: 12, - minimap: {enabled: width==='100%'}, + minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, fontFamily: 'Source Code Pro', folding: false, glyphMargin: false, - wordWrap: 'on' + wordWrap: 'on', + }} + onChange={(val, ev) => { + setValue((val as string).replace(/\r\n/g, '\n')); }} - onChange={(val, ev) => {setValue(val as string)}} /> diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 35ad05de..098ba082 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -2,7 +2,7 @@ import { useState, useEffect, useCallback, Key, useRef } from 'react'; import { TreeSelect, Tree, Input } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; -import Editor from "@monaco-editor/react"; +import Editor from '@monaco-editor/react'; import { request } from '@/utils/http'; import styles from './index.module.less'; @@ -23,6 +23,7 @@ const LangMap: any = { '.py': 'python', '.js': 'javascript', '.sh': 'shell', + '.ts': 'typescript', }; const Script = () => { @@ -95,21 +96,22 @@ const Script = () => { setHeight(treeDom.current.clientHeight); }, []); - useEffect(()=>{ + useEffect(() => { const media = window.matchMedia('(prefers-color-scheme: dark)'); const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark?'vs-dark':'vs'); - media.addEventListener('change',(e)=>{ - if(storageTheme === 'auto' || !storageTheme){ - if(e.matches){ - setTheme('vs-dark') - }else{ + const isDark = + (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark ? 'vs-dark' : 'vs'); + media.addEventListener('change', (e) => { + if (storageTheme === 'auto' || !storageTheme) { + if (e.matches) { + setTheme('vs-dark'); + } else { setTheme('vs'); } } - }) - },[]) + }); + }, []); return ( { options={{ readOnly: true, fontSize: 12, - minimap: {enabled: width==='100%'}, + minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, glyphMargin: false, + default + }} + onChange={(val) => { + setValue((val as string).replace(/\r\n/g, '\n')); }} - onChange={(val) => {setValue(val as string)}} /> From e03a9d2c1de03de81878c738db2da5f3f1e5cb60 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 26 Jul 2021 23:07:22 +0800 Subject: [PATCH 209/247] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/script/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 098ba082..e47e64d5 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -175,7 +175,6 @@ const Script = () => { lineNumbersMinChars: 3, folding: false, glyphMargin: false, - default }} onChange={(val) => { setValue((val as string).replace(/\r\n/g, '\n')); From 0b998821930b48756150fb19cf83638116ee14ef Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 27 Jul 2021 00:09:06 +0800 Subject: [PATCH 210/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index 518db753..470182cb 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -46,7 +46,7 @@ body { max-width: unset !important; overflow: auto; .ant-pro-page-container-children-content { - overflow: visible; + overflow: auto; height: calc(100vh - 96px); height: calc(100vh - var(--vh-offset, 0px) - 96px); background-color: #fff; From 38609feee91bd815e4b90fc6dec539273d738639 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Wed, 28 Jul 2021 21:39:43 +0800 Subject: [PATCH 211/247] =?UTF-8?q?monaco-editor=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 +- pnpm-lock.yaml | 203 +++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 173 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index d6a04a0e..597c28da 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ ] }, "dependencies": { + "@monaco-editor/react": "4.1.3", "body-parser": "^1.19.0", "celebrate": "^13.0.3", "cors": "^2.8.5", @@ -44,7 +45,6 @@ "devDependencies": { "@ant-design/icons": "^4.6.2", "@ant-design/pro-layout": "^6.5.0", - "@monaco-editor/react": "^4.2.1", "@types/cors": "^2.8.10", "@types/express": "^4.17.8", "@types/express-jwt": "^6.0.1", @@ -69,7 +69,7 @@ "react-dnd": "^14.0.2", "react-dnd-html5-backend": "^14.0.0", "react-dom": "17.x", - "react-split-pane": "^0.1.92", + "react-split-pane": "^2.0.3", "ts-node": "^9.0.0", "typescript": "^4.1.2", "umi": "^3.3.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c3fdd954..494ea49c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,7 +3,7 @@ lockfileVersion: 5.3 specifiers: '@ant-design/icons': ^4.6.2 '@ant-design/pro-layout': ^6.5.0 - '@monaco-editor/react': ^4.2.1 + '@monaco-editor/react': 4.1.3 '@types/cors': ^2.8.10 '@types/express': ^4.17.8 '@types/express-jwt': ^6.0.1 @@ -41,7 +41,7 @@ specifiers: react-dnd: ^14.0.2 react-dnd-html5-backend: ^14.0.0 react-dom: 17.x - react-split-pane: ^0.1.92 + react-split-pane: ^2.0.3 reflect-metadata: ^0.1.13 ts-node: ^9.0.0 typedi: ^0.8.0 @@ -54,6 +54,7 @@ specifiers: yorkie: ^2.0.0 dependencies: + '@monaco-editor/react': 4.1.3_react-dom@17.0.2+react@17.0.2 body-parser: 1.19.0 celebrate: 13.0.4 cors: 2.8.5 @@ -74,7 +75,6 @@ dependencies: devDependencies: '@ant-design/icons': 4.6.2_react-dom@17.0.2+react@17.0.2 '@ant-design/pro-layout': 6.18.0_react-dom@17.0.2+react@17.0.2 - '@monaco-editor/react': 4.2.1_react-dom@17.0.2+react@17.0.2 '@types/cors': 2.8.10 '@types/express': 4.17.11 '@types/express-jwt': 6.0.1 @@ -99,7 +99,7 @@ devDependencies: react-dnd: 14.0.2_695545ed68ea337339babea285839fc0 react-dnd-html5-backend: 14.0.0 react-dom: 17.0.2_react@17.0.2 - react-split-pane: 0.1.92_react-dom@17.0.2+react@17.0.2 + react-split-pane: 2.0.3 ts-node: 9.1.1_typescript@4.2.4 typescript: 4.2.4 umi: 3.4.20 @@ -872,12 +872,12 @@ packages: monaco-editor: '>= 0.21.0 < 1' dependencies: state-local: 1.0.7 - dev: true + dev: false - /@monaco-editor/react/4.2.1_react-dom@17.0.2+react@17.0.2: - resolution: {integrity: sha512-yN8qVY0PyFIbqPjfrZ5TbR/wrcfeiwoys8+0QkmyfiOzG74vXxSBOPIUxk7Ly+qCj7qWHPq1uDJskzFGaIqaPA==} + /@monaco-editor/react/4.1.3_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-kqcjVuoy6btcgALAk4RV/SlasveM+WTw5lzzlyq5FhKXjF8wu5tSe/2oCQ1uhLpcdtxcHfx3L0HrcAPWnejFnQ==} peerDependencies: - monaco-editor: '>= 0.25.0 < 1' + monaco-editor: ^0.23.0 react: ^16.8.0 || ^17.0.0 react-dom: ^16.8.0 || ^17.0.0 dependencies: @@ -886,7 +886,7 @@ packages: react: 17.0.2 react-dom: 17.0.2_react@17.0.2 state-local: 1.0.7 - dev: true + dev: false /@npmcli/move-file/1.1.2: resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} @@ -2159,6 +2159,10 @@ packages: type-is: 1.6.18 dev: false + /bowser/1.9.4: + resolution: {integrity: sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==} + dev: true + /boxen/4.2.0: resolution: {integrity: sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==} engines: {node: '>=8'} @@ -2203,6 +2207,10 @@ packages: fill-range: 7.0.1 dev: true + /brcast/3.0.2: + resolution: {integrity: sha512-f5XwwFCCuvgqP2nMH/hJ74FqnGmb4X3D+NC//HphxJzzhsZvSZa+Hk/syB7j3ZHpPDLMoYU8oBgviRWfNvEfKA==} + dev: true + /brorand/1.1.0: resolution: {integrity: sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=} dev: true @@ -2304,6 +2312,13 @@ packages: isarray: 1.0.0 dev: true + /buffer/5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + /builtin-status-codes/3.0.0: resolution: {integrity: sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=} dev: true @@ -2404,6 +2419,10 @@ packages: engines: {node: '>=10'} dev: true + /camelize/1.0.0: + resolution: {integrity: sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=} + dev: true + /caniuse-lite/1.0.30001228: resolution: {integrity: sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==} dev: true @@ -2926,6 +2945,11 @@ packages: postcss: 7.0.32 dev: true + /css-color-keywords/1.0.0: + resolution: {integrity: sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=} + engines: {node: '>=4'} + dev: true + /css-has-pseudo/0.10.0: resolution: {integrity: sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ==} engines: {node: '>=6.0.0'} @@ -2935,6 +2959,13 @@ packages: postcss-selector-parser: 5.0.0 dev: true + /css-in-js-utils/2.0.1: + resolution: {integrity: sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==} + dependencies: + hyphenate-style-name: 1.0.4 + isobject: 3.0.1 + dev: true + /css-prefers-color-scheme/3.1.1: resolution: {integrity: sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg==} engines: {node: '>=6.0.0'} @@ -2943,6 +2974,14 @@ packages: postcss: 7.0.32 dev: true + /css-to-react-native/2.3.2: + resolution: {integrity: sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==} + dependencies: + camelize: 1.0.0 + css-color-keywords: 1.0.0 + postcss-value-parser: 3.3.1 + dev: true + /cssdb/4.4.0: resolution: {integrity: sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ==} dev: true @@ -3285,7 +3324,7 @@ packages: /encoding/0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} dependencies: - iconv-lite: 0.6.2 + iconv-lite: 0.6.3 dev: true /end-of-stream/1.4.4: @@ -3640,6 +3679,10 @@ packages: resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} dev: true + /fast-memoize/2.5.2: + resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} + dev: true + /fast-safe-stringify/2.0.7: resolution: {integrity: sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==} dev: false @@ -3888,6 +3931,32 @@ packages: assert-plus: 1.0.0 dev: true + /glamor/2.20.40: + resolution: {integrity: sha512-DNXCd+c14N9QF8aAKrfl4xakPk5FdcFwmH7sD0qnC0Pr7xoZ5W9yovhUrY/dJc3psfGGXC58vqQyRtuskyUJxA==} + dependencies: + fbjs: 0.8.17 + inline-style-prefixer: 3.0.8 + object-assign: 4.1.1 + prop-types: 15.7.2 + through: 2.3.8 + dev: true + + /glamorous/4.13.1_glamor@2.20.40: + resolution: {integrity: sha512-x9yCGlRrPEkHF63m+WoZXHnpSet5ipS/fxczx5ic0ZKPPd2mMDyCZ0iEhse49OFlag0yxbJTc7k/L0g1GCmCYQ==} + peerDependencies: + glamor: '>=2' + dependencies: + brcast: 3.0.2 + csstype: 2.6.17 + fast-memoize: 2.5.2 + glamor: 2.20.40 + html-tag-names: 1.1.5 + is-function: 1.0.2 + is-plain-object: 2.0.4 + react-html-attributes: 1.4.6 + svg-tag-names: 1.1.2 + dev: true + /glob-parent/5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -3970,6 +4039,11 @@ packages: resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==} dev: true + /has-flag/1.0.0: + resolution: {integrity: sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=} + engines: {node: '>=0.10.0'} + dev: true + /has-flag/3.0.0: resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} engines: {node: '>=4'} @@ -4073,6 +4147,10 @@ packages: minimalistic-crypto-utils: 1.0.1 dev: true + /hoist-non-react-statics/1.2.0: + resolution: {integrity: sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=} + dev: true + /hoist-non-react-statics/3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: @@ -4083,6 +4161,10 @@ packages: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: true + /html-element-attributes/1.3.1: + resolution: {integrity: sha512-UrRKgp5sQmRnDy4TEwAUsu14XBUlzKB8U3hjIYDjcZ3Hbp86Jtftzxfgrv6E/ii/h78tsaZwAnAE8HwnHr0dPA==} + dev: true + /html-encoding-sniffer/1.0.2: resolution: {integrity: sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==} dependencies: @@ -4100,6 +4182,10 @@ packages: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} dev: true + /html-tag-names/1.1.5: + resolution: {integrity: sha512-aI5tKwNTBzOZApHIynaAwecLBv8TlZTEy/P4Sj2SzzAhBrGuI8yGZ0UIXVPQzOHGS+to2mjb04iy6VWt/8+d8A==} + dev: true + /http-cache-semantics/4.1.0: resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} dev: true @@ -4144,14 +4230,18 @@ packages: engines: {node: '>=8.12.0'} dev: true + /hyphenate-style-name/1.0.4: + resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} + dev: true + /iconv-lite/0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - /iconv-lite/0.6.2: - resolution: {integrity: sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==} + /iconv-lite/0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 @@ -4263,6 +4353,20 @@ packages: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} dev: true + /inline-style-prefixer/3.0.8: + resolution: {integrity: sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=} + dependencies: + bowser: 1.9.4 + css-in-js-utils: 2.0.1 + dev: true + + /inline-style-prefixer/4.0.2: + resolution: {integrity: sha512-N8nVhwfYga9MiV9jWlwfdj1UDIaZlBFu4cJSJkIr7tZX7sHpHhGR5su1qdpW+7KPL8ISTvCIkcaFi/JdBknvPg==} + dependencies: + bowser: 1.9.4 + css-in-js-utils: 2.0.1 + dev: true + /invariant/2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} dependencies: @@ -4418,6 +4522,10 @@ packages: engines: {node: '>=8'} dev: true + /is-function/1.0.2: + resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} + dev: true + /is-generator-fn/2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} @@ -5195,7 +5303,6 @@ packages: /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true /js-yaml/3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} @@ -5608,7 +5715,6 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 - dev: true /lowercase-keys/1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} @@ -6753,6 +6859,10 @@ packages: util-deprecate: 1.0.2 dev: true + /postcss-value-parser/3.3.1: + resolution: {integrity: sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==} + dev: true + /postcss-value-parser/4.1.0: resolution: {integrity: sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==} dev: true @@ -6844,7 +6954,6 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - dev: true /proxy-addr/2.0.6: resolution: {integrity: sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==} @@ -7681,9 +7790,14 @@ packages: scheduler: 0.20.2 dev: true + /react-html-attributes/1.4.6: + resolution: {integrity: sha512-uS3MmThNKFH2EZUQQw4k5pIcU7XIr208UE5dktrj/GOH1CMagqxDl4DCLpt3o2l9x+IB5nVYBeN3Cr4IutBXAg==} + dependencies: + html-element-attributes: 1.3.1 + dev: true + /react-is/16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: true /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -7751,23 +7865,17 @@ packages: tiny-warning: 1.0.3 dev: true - /react-split-pane/0.1.92_react-dom@17.0.2+react@17.0.2: - resolution: {integrity: sha512-GfXP1xSzLMcLJI5BM36Vh7GgZBpy+U/X0no+VM3fxayv+p1Jly5HpMofZJraeaMl73b3hvlr+N9zJKvLB/uz9w==} - peerDependencies: - react: ^16.0.0-0 - react-dom: ^16.0.0-0 - dependencies: - prop-types: 15.7.2 - react: 17.0.2 - react-dom: 17.0.2_react@17.0.2 - react-lifecycles-compat: 3.0.4 - react-style-proptype: 3.2.2 - dev: true - - /react-style-proptype/3.2.2: - resolution: {integrity: sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==} + /react-split-pane/2.0.3: + resolution: {integrity: sha512-1rW+EMSJTkS7eYMYethCaNFOjiAVDm/B2LlxJXLr1Uu8ddLrV9pfc5P/fngRBkTGC/0tvxRkW1dLxGY7zvHVkA==} dependencies: + glamor: 2.20.40 + glamorous: 4.13.1_glamor@2.20.40 + inline-style-prefixer: 4.0.2 + normalize.css: 7.0.0 prop-types: 15.7.2 + react: 16.14.0 + react-dom: 16.14.0_react@16.14.0 + styled-components: 2.4.1_react@16.14.0 dev: true /react-tween-state/0.1.5: @@ -8624,7 +8732,7 @@ packages: /state-local/1.0.7: resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} - dev: true + dev: false /static-extend/0.1.2: resolution: {integrity: sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=} @@ -8783,6 +8891,33 @@ packages: engines: {node: '>=0.10.0'} dev: true + /styled-components/2.4.1_react@16.14.0: + resolution: {integrity: sha1-ZjvQSF1LarRvlGIQ3APSOY0a3nQ=} + peerDependencies: + react: '>= 0.14.0 < 17.0.0-0' + dependencies: + buffer: 5.7.1 + css-to-react-native: 2.3.2 + fbjs: 0.8.17 + hoist-non-react-statics: 1.2.0 + is-plain-object: 2.0.4 + prop-types: 15.7.2 + react: 16.14.0 + stylis: 3.5.4 + supports-color: 3.2.3 + dev: true + + /stylis/3.5.4: + resolution: {integrity: sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==} + dev: true + + /supports-color/3.2.3: + resolution: {integrity: sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=} + engines: {node: '>=0.8.0'} + dependencies: + has-flag: 1.0.0 + dev: true + /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -8812,6 +8947,10 @@ packages: supports-color: 7.2.0 dev: true + /svg-tag-names/1.1.2: + resolution: {integrity: sha512-LIDOy8NRLGfJegTEnpizWA/ofg3Gyx58JgPEEjvATFciUJW9dHZ2aPTYY0Mn2rQYCeUGZElpHfu91OcWK0IMIw==} + dev: true + /swr/0.5.6_react@17.0.2: resolution: {integrity: sha512-Bmx3L4geMZjYT5S2Z6EE6/5Cx6v1Ka0LhqZKq8d6WL2eu9y6gHWz3dUzfIK/ymZVHVfwT/EweFXiYGgfifei3w==} peerDependencies: From 97281191018cc2f1ee5ca351a630d2db5fd834cf Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 31 Jul 2021 23:09:53 +0800 Subject: [PATCH 212/247] =?UTF-8?q?=E6=89=8B=E6=9C=BA=E7=AB=AF=E4=BD=BF?= =?UTF-8?q?=E7=94=A8codemirror?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .umirc.ts | 5 + back/api/auth.ts | 8 +- back/api/config.ts | 2 +- back/api/script.ts | 40 ++++++ back/config/index.ts | 6 + package.json | 4 +- pnpm-lock.yaml | 38 ++++-- src/layouts/index.less | 82 +++++++++-- src/layouts/index.tsx | 5 +- src/pages/config/index.tsx | 52 ++++--- src/pages/crontab/logModal.tsx | 1 + src/pages/diff/index.tsx | 88 ++++++++---- src/pages/log/index.module.less | 4 + src/pages/log/index.tsx | 54 +++++--- src/pages/login/index.tsx | 4 +- src/pages/script/editModal.tsx | 209 +++++++++++++++++++++++++++++ src/pages/script/index.module.less | 4 + src/pages/script/index.tsx | 95 +++++++++---- src/pages/script/saveModal.tsx | 87 ++++++++++++ src/pages/script/setting.tsx | 67 +++++++++ 20 files changed, 735 insertions(+), 120 deletions(-) create mode 100644 src/pages/script/editModal.tsx create mode 100644 src/pages/script/saveModal.tsx create mode 100644 src/pages/script/setting.tsx diff --git a/.umirc.ts b/.umirc.ts index 03d7b666..9e43bb64 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -29,10 +29,15 @@ export default defineConfig({ react: 'window.React', 'react-dom': 'window.ReactDOM', darkreader: 'window.DarkReader', + codemirror: 'window.CodeMirror', }, scripts: [ 'https://gw.alipayobjects.com/os/lib/react/16.13.1/umd/react.production.min.js', 'https://gw.alipayobjects.com/os/lib/react-dom/16.13.1/umd/react-dom.production.min.js', 'https://cdn.jsdelivr.net/npm/darkreader@4.9.34/darkreader.min.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/lib/codemirror.min.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/shell/shell.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/python/python.js', + 'https://cdn.jsdelivr.net/npm/codemirror@5.62.0/mode/javascript/javascript.js', ], }); diff --git a/back/api/auth.ts b/back/api/auth.ts index 329d4340..79e09572 100644 --- a/back/api/auth.ts +++ b/back/api/auth.ts @@ -35,7 +35,7 @@ export default (app: Router) => { ); return res.send({ code: 100, - msg: '已初始化密码,请前往auth.json查看并重新登录', + message: '已初始化密码,请前往auth.json查看并重新登录', }); } if ( @@ -57,10 +57,10 @@ export default (app: Router) => { ); res.send({ code: 200, token }); } else { - res.send({ code: 400, msg: config.authError }); + res.send({ code: 400, message: config.authError }); } } else { - res.send({ err: 400, msg: '请输入用户名密码!' }); + res.send({ err: 400, message: '请输入用户名密码!' }); } }); } catch (e) { @@ -101,7 +101,7 @@ export default (app: Router) => { try { fs.writeFile(config.authConfigFile, JSON.stringify(req.body), (err) => { if (err) console.log(err); - res.send({ code: 200, msg: '更新成功' }); + res.send({ code: 200, message: '更新成功' }); }); } catch (e) { logger.error('🔥 error: %o', e); diff --git a/back/api/config.ts b/back/api/config.ts index 175478a2..1c4afb2a 100644 --- a/back/api/config.ts +++ b/back/api/config.ts @@ -68,7 +68,7 @@ export default (app: Router) => { const { name, content } = req.body; const path = `${config.configPath}${name}`; fs.writeFileSync(path, content); - res.send({ code: 200, msg: '保存成功' }); + res.send({ code: 200, message: '保存成功' }); } catch (e) { logger.error('🔥 error: %o', e); return next(e); diff --git a/back/api/script.ts b/back/api/script.ts index 87480375..1b0a09c4 100644 --- a/back/api/script.ts +++ b/back/api/script.ts @@ -48,4 +48,44 @@ export default (app: Router) => { } }, ); + + route.post( + '/scripts', + celebrate({ + body: Joi.object({ + filename: Joi.string().required(), + path: Joi.string().required(), + content: Joi.string().required(), + }), + }), + async (req: Request, res: Response, next: NextFunction) => { + const logger: Logger = Container.get('logger'); + try { + let { filename, path, content } = req.body as { + filename: string; + path: string; + content: string; + }; + if (!path.endsWith('/')) { + path += '/'; + } + if (config.writePathList.every((x) => !path.startsWith(x))) { + return res.send({ code: 400, data: '文件路径错误,可保存目录/ql/scripts、/ql/config、/ql/jbot、/ql/bak' }); + } + const filePath = `${path}${filename.replace(/\//g, '')}`; + const bakPath = '/ql/bak'; + if (fs.existsSync(filePath)) { + if (!fs.existsSync(bakPath)) { + fs.mkdirSync(bakPath); + } + fs.copyFileSync(filePath, bakPath); + } + fs.writeFileSync(filePath, content); + return res.send({ code: 200 }); + } catch (e) { + logger.error('🔥 error: %o', e); + return next(e); + } + }, + ); }; diff --git a/back/config/index.ts b/back/config/index.ts index fa127dc8..4d37381a 100644 --- a/back/config/index.ts +++ b/back/config/index.ts @@ -67,4 +67,10 @@ export default { 'crontab.list', 'env.sh', ], + writePathList: [ + '/ql/scripts/', + '/ql/config/', + '/ql/jbot/', + '/ql/bak/', + ], }; diff --git a/package.json b/package.json index 597c28da..e3fb27fc 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ ] }, "dependencies": { - "@monaco-editor/react": "4.1.3", "body-parser": "^1.19.0", "celebrate": "^13.0.3", "cors": "^2.8.5", @@ -45,6 +44,7 @@ "devDependencies": { "@ant-design/icons": "^4.6.2", "@ant-design/pro-layout": "^6.5.0", + "@monaco-editor/react": "^4.2.1", "@types/cors": "^2.8.10", "@types/express": "^4.17.8", "@types/express-jwt": "^6.0.1", @@ -58,6 +58,7 @@ "@types/react-dom": "^17.0.0", "@umijs/plugin-antd": "^0.9.1", "@umijs/test": "^3.3.9", + "codemirror": "^5.62.2", "compression-webpack-plugin": "6.1.1", "darkreader": "^4.9.27", "lint-staged": "^10.0.7", @@ -65,6 +66,7 @@ "prettier": "^2.2.0", "qrcode.react": "^1.0.1", "react": "17.x", + "react-codemirror2": "^7.2.1", "react-diff-viewer": "^3.1.1", "react-dnd": "^14.0.2", "react-dnd-html5-backend": "^14.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 494ea49c..0ad29434 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,7 +3,7 @@ lockfileVersion: 5.3 specifiers: '@ant-design/icons': ^4.6.2 '@ant-design/pro-layout': ^6.5.0 - '@monaco-editor/react': 4.1.3 + '@monaco-editor/react': ^4.2.1 '@types/cors': ^2.8.10 '@types/express': ^4.17.8 '@types/express-jwt': ^6.0.1 @@ -19,6 +19,7 @@ specifiers: '@umijs/test': ^3.3.9 body-parser: ^1.19.0 celebrate: ^13.0.3 + codemirror: ^5.62.2 compression-webpack-plugin: 6.1.1 cors: ^2.8.5 cron-parser: ^3.5.0 @@ -37,6 +38,7 @@ specifiers: prettier: ^2.2.0 qrcode.react: ^1.0.1 react: 17.x + react-codemirror2: ^7.2.1 react-diff-viewer: ^3.1.1 react-dnd: ^14.0.2 react-dnd-html5-backend: ^14.0.0 @@ -54,7 +56,6 @@ specifiers: yorkie: ^2.0.0 dependencies: - '@monaco-editor/react': 4.1.3_react-dom@17.0.2+react@17.0.2 body-parser: 1.19.0 celebrate: 13.0.4 cors: 2.8.5 @@ -75,6 +76,7 @@ dependencies: devDependencies: '@ant-design/icons': 4.6.2_react-dom@17.0.2+react@17.0.2 '@ant-design/pro-layout': 6.18.0_react-dom@17.0.2+react@17.0.2 + '@monaco-editor/react': 4.2.1_react-dom@17.0.2+react@17.0.2 '@types/cors': 2.8.10 '@types/express': 4.17.11 '@types/express-jwt': 6.0.1 @@ -88,6 +90,7 @@ devDependencies: '@types/react-dom': 17.0.5 '@umijs/plugin-antd': 0.9.1_5ccfec03b6e15849b3687a64fe975f75 '@umijs/test': 3.4.20_ts-node@9.1.1 + codemirror: 5.62.2 compression-webpack-plugin: 6.1.1_webpack@5.37.0 darkreader: 4.9.32 lint-staged: 10.5.4 @@ -95,6 +98,7 @@ devDependencies: prettier: 2.3.0 qrcode.react: 1.0.1_react@17.0.2 react: 17.0.2 + react-codemirror2: 7.2.1_codemirror@5.62.2+react@17.0.2 react-diff-viewer: 3.1.1_react-dom@17.0.2+react@17.0.2 react-dnd: 14.0.2_695545ed68ea337339babea285839fc0 react-dnd-html5-backend: 14.0.0 @@ -872,12 +876,12 @@ packages: monaco-editor: '>= 0.21.0 < 1' dependencies: state-local: 1.0.7 - dev: false + dev: true - /@monaco-editor/react/4.1.3_react-dom@17.0.2+react@17.0.2: - resolution: {integrity: sha512-kqcjVuoy6btcgALAk4RV/SlasveM+WTw5lzzlyq5FhKXjF8wu5tSe/2oCQ1uhLpcdtxcHfx3L0HrcAPWnejFnQ==} + /@monaco-editor/react/4.2.1_react-dom@17.0.2+react@17.0.2: + resolution: {integrity: sha512-yN8qVY0PyFIbqPjfrZ5TbR/wrcfeiwoys8+0QkmyfiOzG74vXxSBOPIUxk7Ly+qCj7qWHPq1uDJskzFGaIqaPA==} peerDependencies: - monaco-editor: ^0.23.0 + monaco-editor: '>= 0.25.0 < 1' react: ^16.8.0 || ^17.0.0 react-dom: ^16.8.0 || ^17.0.0 dependencies: @@ -886,7 +890,7 @@ packages: react: 17.0.2 react-dom: 17.0.2_react@17.0.2 state-local: 1.0.7 - dev: false + dev: true /@npmcli/move-file/1.1.2: resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} @@ -2587,6 +2591,10 @@ packages: engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} dev: true + /codemirror/5.62.2: + resolution: {integrity: sha512-tVFMUa4J3Q8JUd1KL9yQzQB0/BJt7ZYZujZmTPgo/54Lpuq3ez4C8x/ATUY/wv7b7X3AUq8o3Xd+2C5ZrCGWHw==} + dev: true + /collect-v8-coverage/1.0.1: resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} dev: true @@ -5303,6 +5311,7 @@ packages: /js-tokens/4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true /js-yaml/3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} @@ -5715,6 +5724,7 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 + dev: true /lowercase-keys/1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} @@ -6954,6 +6964,7 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 + dev: true /proxy-addr/2.0.6: resolution: {integrity: sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==} @@ -7719,6 +7730,16 @@ packages: strip-json-comments: 2.0.1 dev: true + /react-codemirror2/7.2.1_codemirror@5.62.2+react@17.0.2: + resolution: {integrity: sha512-t7YFmz1AXdlImgHXA9Ja0T6AWuopilub24jRaQdPVbzUJVNKIYuy3uCFZYa7CE5S3UW6SrSa5nAqVQvtzRF9gw==} + peerDependencies: + codemirror: 5.x + react: '>=15.5 <=16.x' + dependencies: + codemirror: 5.62.2 + react: 17.0.2 + dev: true + /react-diff-viewer/3.1.1_react-dom@17.0.2+react@17.0.2: resolution: {integrity: sha512-rmvwNdcClp6ZWdS11m1m01UnBA4OwYaLG/li0dB781e/bQEzsGyj+qewVd6W5ztBwseQ72pO7nwaCcq5jnlzcw==} engines: {node: '>= 8'} @@ -7798,6 +7819,7 @@ packages: /react-is/16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -8732,7 +8754,7 @@ packages: /state-local/1.0.7: resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} - dev: false + dev: true /static-extend/0.1.2: resolution: {integrity: sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=} diff --git a/src/layouts/index.less b/src/layouts/index.less index 470182cb..91650eda 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -1,4 +1,5 @@ @import '~@/styles/variable.less'; +@import '~codemirror/lib/codemirror.css'; @font-face { font-family: 'Source Code Pro'; @@ -13,7 +14,7 @@ body { background-color: rgb(248, 248, 248); } -.ant-modal { +.log-modal .ant-modal { padding-bottom: 0 !important; width: 580px !important; } @@ -21,22 +22,14 @@ body { .monaco-editor:not(.rename-box) { height: calc(100vh - 128px) !important; height: calc(100vh - var(--vh-offset, 0px) - 128px) !important; - .view-overlays .current-line{ + .view-overlays .current-line { border-width: 0; } } -.log-modal { - .monaco-editor:not(.rename-box) { - height: calc(100vh - 176px) !important; - height: calc(100vh - var(--vh-offset, 0px) - 176px) !important; - background-color: transparent !important; - } -} - -.rename-box { +.rename-box { height: 0; - .rename-input{ + .rename-input { height: 0; padding: 0 !important; } @@ -144,12 +137,17 @@ input:-webkit-autofill:active { height: calc(100vh - 184px); height: calc(100vh - var(--vh-offset, 0px) - 184px); } - .monaco-editor:not(.rename-box) { + .monaco-editor:not(.rename-box), + .CodeMirror { height: calc(100vh - 216px) !important; height: calc(100vh - var(--vh-offset, 0px) - 216px) !important; } + .CodeMirror { + width: calc(100vw - 80px); + } } - .monaco-editor:not(.rename-box) { + .monaco-editor:not(.rename-box), + .CodeMirror { height: calc(100vh - 176px) !important; height: calc(100vh - var(--vh-offset, 0px) - 176px) !important; } @@ -166,3 +164,59 @@ input:-webkit-autofill:active { min-height: calc(100vh - var(--vh-offset, 0px) - 72px); } } + +.Resizer { + background: #000; + opacity: 0.2; + z-index: 1; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + -moz-background-clip: padding; + -webkit-background-clip: padding; + background-clip: padding-box; +} + +.Resizer:hover { + -webkit-transition: all 2s ease; + transition: all 2s ease; +} + +.Resizer.horizontal { + height: 11px; + margin: -5px 0; + border-top: 5px solid rgba(255, 255, 255, 0); + border-bottom: 5px solid rgba(255, 255, 255, 0); + cursor: row-resize; + width: 100%; +} + +.Resizer.horizontal:hover { + border-top: 5px solid rgba(0, 0, 0, 0.5); + border-bottom: 5px solid rgba(0, 0, 0, 0.5); +} + +.Resizer.vertical { + width: 11px; + margin: 0 -5px; + border-left: 5px solid rgba(255, 255, 255, 0); + border-right: 5px solid rgba(255, 255, 255, 0); + cursor: col-resize; +} + +.Resizer.vertical:hover { + border-left: 5px solid rgba(0, 0, 0, 0.5); + border-right: 5px solid rgba(0, 0, 0, 0.5); +} +.Resizer.disabled { + cursor: not-allowed; +} +.Resizer.disabled:hover { + border-color: transparent; +} + +.edit-modal { + .ant-drawer-body { + padding: 0; + } +} diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 1717dbd2..61890750 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -65,6 +65,8 @@ export default function (props: any) { const isSafari = navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('Chrome'); + const isQQBrowser = navigator.userAgent.includes('QQBrowser'); + return ( {version} diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 031cce9e..59a56d16 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -4,6 +4,7 @@ import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import Editor from '@monaco-editor/react'; +import { Controlled as CodeMirror } from 'react-codemirror2'; const Config = () => { const [width, setWidth] = useState('100%'); @@ -15,6 +16,7 @@ const Config = () => { const [select, setSelect] = useState('config.sh'); const [data, setData] = useState([]); const [theme, setTheme] = useState(''); + const [isPhone, setIsPhone] = useState(false); const getConfig = (name: string) => { request.get(`${config.apiPrefix}configs/${name}`).then((data: any) => { @@ -38,7 +40,7 @@ const Config = () => { data: { content: value, name: select }, }) .then((data: any) => { - message.success(data.msg); + message.success(data.message); }); }; @@ -53,10 +55,12 @@ const Config = () => { setWidth('auto'); setMarginLeft(0); setMarginTop(0); + setIsPhone(true); } else { setWidth('100%'); setMarginLeft(0); setMarginTop(-72); + setIsPhone(false); } getFiles(); getConfig('config.sh'); @@ -111,21 +115,37 @@ const Config = () => { }, }} > - { - setValue((val as string).replace(/\r\n/g, '\n')); - }} - /> + {isPhone ? ( + { + setValue(value); + }} + onChange={(editor, data, value) => {}} + /> + ) : ( + { + setValue((val as string).replace(/\r\n/g, '\n')); + }} + /> + )}
); }; diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index dcbbd964..488f03b9 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -96,6 +96,7 @@ const CronLogModal = ({ title={titleElement()} visible={visible} centered + className="log-modal" bodyStyle={{ overflowY: 'auto', maxHeight: 'calc(80vh - var(--vh-offset, 0px))', diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index e2f11d8b..34eff25a 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -3,9 +3,9 @@ import { Button, message, Modal } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; -import ReactDiffViewer from 'react-diff-viewer'; import './index.less'; -import { DiffEditor } from "@monaco-editor/react"; +import { DiffEditor } from '@monaco-editor/react'; +import ReactDiffViewer from 'react-diff-viewer'; const Crontab = () => { const [width, setWidth] = useState('100%'); @@ -15,6 +15,7 @@ const Crontab = () => { const [sample, setSample] = useState(''); const [loading, setLoading] = useState(true); const [theme, setTheme] = useState(''); + const [isPhone, setIsPhone] = useState(false); const getConfig = () => { request.get(`${config.apiPrefix}configs/config.sh`).then((data) => { @@ -37,30 +38,33 @@ const Crontab = () => { setWidth('auto'); setMarginLeft(0); setMarginTop(0); + setIsPhone(true); } else { setWidth('100%'); setMarginLeft(0); setMarginTop(-72); + setIsPhone(false); } getConfig(); getSample(); }, []); - useEffect(()=>{ + useEffect(() => { const media = window.matchMedia('(prefers-color-scheme: dark)'); const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark?'vs-dark':'vs'); - media.addEventListener('change',(e)=>{ - if(storageTheme === 'auto' || !storageTheme){ - if(e.matches){ - setTheme('vs-dark') - }else{ + const isDark = + (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark ? 'vs-dark' : 'vs'); + media.addEventListener('change', (e) => { + if (storageTheme === 'auto' || !storageTheme) { + if (e.matches) { + setTheme('vs-dark'); + } else { setTheme('vs'); } } - }) - },[]) + }); + }, []); return ( { }, }} > - + {isPhone ? ( + + ) : ( + + )} ); }; diff --git a/src/pages/log/index.module.less b/src/pages/log/index.module.less index 73ee7c51..9e7812a9 100644 --- a/src/pages/log/index.module.less +++ b/src/pages/log/index.module.less @@ -27,5 +27,9 @@ .ant-pro-grid-content.wide .ant-pro-page-container-children-content { background-color: #f8f8f8; } + + .CodeMirror { + width: calc(100% - 32px - @tree-width); + } } } diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index d91f044d..9e353352 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -5,6 +5,7 @@ import { PageContainer } from '@ant-design/pro-layout'; import Editor from '@monaco-editor/react'; import { request } from '@/utils/http'; import styles from './index.module.less'; +import { Controlled as CodeMirror } from 'react-codemirror2'; function getFilterData(keyword: string, data: any) { const expandedKeys: string[] = []; @@ -188,24 +189,41 @@ const Log = () => { )} - { - setValue((val as string).replace(/\r\n/g, '\n')); - }} - /> + {isPhone ? ( + { + setValue(value); + }} + onChange={(editor, data, value) => {}} + /> + ) : ( + { + setValue((val as string).replace(/\r\n/g, '\n')); + }} + /> + )}
); diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index ca67de21..a517b50c 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -21,9 +21,9 @@ const Login = () => { localStorage.setItem(config.authKey, data.token); history.push('/crontab'); } else if (data.code === 100) { - message.warn(data.msg); + message.warn(data.message); } else { - message.error(data.msg); + message.error(data.message); } }) .catch(function (error) { diff --git a/src/pages/script/editModal.tsx b/src/pages/script/editModal.tsx new file mode 100644 index 00000000..0fb937c1 --- /dev/null +++ b/src/pages/script/editModal.tsx @@ -0,0 +1,209 @@ +import React, { useEffect, useState } from 'react'; +import { Drawer, Button, Tabs, Badge, Select, TreeSelect } from 'antd'; +import { request } from '@/utils/http'; +import config from '@/utils/config'; +import SplitPane from 'react-split-pane'; +import Editor from '@monaco-editor/react'; +import SaveModal from './saveModal'; +import SettingModal from './setting'; + +const { Option } = Select; +const LangMap: any = { + '.py': 'python', + '.js': 'javascript', + '.sh': 'shell', + '.ts': 'typescript', +}; +const prefixMap: any = { + python: '.py', + javascript: '.js', + shell: '.sh', + typescript: '.ts', +}; + +const EditModal = ({ + treeData, + currentFile, + content, + handleCancel, + visible, +}: { + treeData?: any; + currentFile?: string; + content?: string; + visible: boolean; + handleCancel: () => void; +}) => { + const [value, setValue] = useState(''); + const [theme, setTheme] = useState(''); + const [language, setLanguage] = useState('javascript'); + const [fileName, setFileName] = useState(''); + const [saveModalVisible, setSaveModalVisible] = useState(false); + const [settingModalVisible, setSettingModalVisible] = + useState(false); + const [isNewFile, setIsNewFile] = useState(false); + const [log, setLog] = useState(''); + + const cancel = () => { + handleCancel(); + }; + + const onSelect = (value: any, node: any) => { + const newMode = LangMap[value.slice(-3)] || ''; + setFileName(value); + setLanguage(newMode); + setIsNewFile(false); + getDetail(node); + }; + + const getDetail = (node: any) => { + request.get(`${config.apiPrefix}scripts/${node.value}`).then((data) => { + setValue(data.data); + }); + }; + + const createFile = () => { + setFileName(`未命名${prefixMap[language]}`); + setIsNewFile(true); + setValue(''); + }; + + const run = () => {}; + + useEffect(() => { + if (!currentFile) { + createFile(); + } else { + setFileName(currentFile); + setValue(content as string); + } + setIsNewFile(!currentFile); + }, []); + + useEffect(() => { + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = + (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark ? 'vs-dark' : 'vs'); + media.addEventListener('change', (e) => { + if (storageTheme === 'auto' || !storageTheme) { + if (e.matches) { + setTheme('vs-dark'); + } else { + setTheme('vs'); + } + } + }); + }, []); + + return ( + + {fileName} + + + + + + + + + } + width={'100%'} + headerStyle={{ padding: '11px 24px' }} + onClose={cancel} + visible={visible} + > + + { + setValue((val as string).replace(/\r\n/g, '\n')); + }} + /> +
+
{log}
+
+
+ { + setSaveModalVisible(false); + }} + isNewFile={isNewFile} + file={{ content: value, filename: fileName }} + /> + { + setSettingModalVisible(false); + }} + /> +
+ ); +}; + +export default EditModal; diff --git a/src/pages/script/index.module.less b/src/pages/script/index.module.less index 73ee7c51..9e7812a9 100644 --- a/src/pages/script/index.module.less +++ b/src/pages/script/index.module.less @@ -27,5 +27,9 @@ .ant-pro-grid-content.wide .ant-pro-page-container-children-content { background-color: #f8f8f8; } + + .CodeMirror { + width: calc(100% - 32px - @tree-width); + } } } diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index e47e64d5..60c1fdbc 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -1,10 +1,12 @@ import { useState, useEffect, useCallback, Key, useRef } from 'react'; -import { TreeSelect, Tree, Input } from 'antd'; +import { TreeSelect, Tree, Input, Button } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; import Editor from '@monaco-editor/react'; import { request } from '@/utils/http'; import styles from './index.module.less'; +import EditModal from './editModal'; +import { Controlled as CodeMirror } from 'react-codemirror2'; function getFilterData(keyword: string, data: any) { if (keyword) { @@ -41,6 +43,7 @@ const Script = () => { const [height, setHeight] = useState(); const treeDom = useRef(); const [theme, setTheme] = useState(''); + const [isLogModalVisible, setIsLogModalVisible] = useState(false); const getScripts = () => { setLoading(true); @@ -119,18 +122,29 @@ const Script = () => { title={title} loading={loading} extra={ - isPhone && [ - , - ] + isPhone + ? [ + , + ] + : [ + , + ] } header={{ style: { @@ -164,20 +178,47 @@ const Script = () => { )} - { - setValue((val as string).replace(/\r\n/g, '\n')); + {isPhone ? ( + { + setValue(value); + }} + onChange={(editor, data, value) => {}} + /> + ) : ( + { + setValue((val as string).replace(/\r\n/g, '\n')); + }} + /> + )} + { + setIsLogModalVisible(false); }} /> diff --git a/src/pages/script/saveModal.tsx b/src/pages/script/saveModal.tsx new file mode 100644 index 00000000..55780c18 --- /dev/null +++ b/src/pages/script/saveModal.tsx @@ -0,0 +1,87 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, message, Input, Form } from 'antd'; +import { request } from '@/utils/http'; +import config from '@/utils/config'; + +const SaveModal = ({ + file, + handleCancel, + visible, + isNewFile, +}: { + file?: any; + visible: boolean; + handleCancel: (cks?: any[]) => void; + isNewFile: boolean; +}) => { + const [form] = Form.useForm(); + const [loading, setLoading] = useState(false); + + const handleOk = async (values: any) => { + console.log(file.filename); + setLoading(true); + const payload = { ...file, ...values }; + request + .post(`${config.apiPrefix}scripts`, { + data: payload, + }) + .then(({ code, data }) => { + if (code === 200) { + message.success('保存文件成功'); + handleCancel(data); + } else { + message.error(data); + } + setLoading(false); + }); + }; + + useEffect(() => { + form.resetFields(); + setLoading(false); + }, [file, visible]); + + return ( + { + form + .validateFields() + .then((values) => { + handleOk(values); + }) + .catch((info) => { + console.log('Validate Failed:', info); + }); + }} + onCancel={() => handleCancel()} + confirmLoading={loading} + > + + + + + + + + + + ); +}; + +export default SaveModal; diff --git a/src/pages/script/setting.tsx b/src/pages/script/setting.tsx new file mode 100644 index 00000000..c51e7498 --- /dev/null +++ b/src/pages/script/setting.tsx @@ -0,0 +1,67 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, message, Input, Form } from 'antd'; +import { request } from '@/utils/http'; +import config from '@/utils/config'; + +const SettingModal = ({ + file, + handleCancel, + visible, +}: { + file?: any; + visible: boolean; + handleCancel: (cks?: any[]) => void; +}) => { + const [form] = Form.useForm(); + const [loading, setLoading] = useState(false); + + const handleOk = async (values: any) => { + console.log(file.filename); + setLoading(true); + const payload = { ...file, ...values }; + request + .post(`${config.apiPrefix}scripts`, { + data: payload, + }) + .then(({ code, data }) => { + if (code === 200) { + message.success('保存文件成功'); + handleCancel(data); + } else { + message.error(data); + } + setLoading(false); + }); + }; + + useEffect(() => { + form.resetFields(); + setLoading(false); + }, [file, visible]); + + return ( + handleCancel()} + > +
+ + + + +
+ ); +}; + +export default SettingModal; From 5d846beabdec8695e7bb8eaaca981d49b2f5b961 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 31 Jul 2021 23:13:41 +0800 Subject: [PATCH 213/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index d1f76a9f..5f204cfc 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.0-071'; -export const changeLog = 'https://t.me/jiaolongwang/121'; +export const version = 'v2.8.1'; +export const changeLog = 'https://t.me/jiaolongwang/122'; From dc5b4de5fa322e3627460288ca7621a81c2ffbde Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 15:19:20 +0800 Subject: [PATCH 214/247] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/config/index.tsx | 48 +---------- src/pages/crontab/index.tsx | 27 +----- src/pages/diff/index.tsx | 49 +---------- src/pages/env/index.tsx | 30 +------ src/pages/log/index.tsx | 48 +---------- src/pages/script/index.tsx | 50 ++--------- src/pages/setting/index.tsx | 28 +------ src/utils/browser.ts | 160 ++++++++++++++++++++++++++++++++++++ src/utils/hooks.ts | 62 ++++++++++++++ 9 files changed, 250 insertions(+), 252 deletions(-) create mode 100644 src/utils/browser.ts create mode 100644 src/utils/hooks.ts diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 59a56d16..74542ec6 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -5,18 +5,16 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import Editor from '@monaco-editor/react'; import { Controlled as CodeMirror } from 'react-codemirror2'; +import { useCtx, useTheme } from '@/utils/hooks'; const Config = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); const [loading, setLoading] = useState(true); const [title, setTitle] = useState('config.sh'); const [select, setSelect] = useState('config.sh'); const [data, setData] = useState([]); - const [theme, setTheme] = useState(''); - const [isPhone, setIsPhone] = useState(false); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getConfig = (name: string) => { request.get(`${config.apiPrefix}configs/${name}`).then((data: any) => { @@ -51,38 +49,10 @@ const Config = () => { }; useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getFiles(); getConfig('config.sh'); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( { , ]} header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > {isPhone ? ( @@ -136,7 +97,6 @@ const Config = () => { theme={theme} options={{ fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, glyphMargin: false, diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index 02c8689e..fb423a26 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -31,6 +31,7 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import CronModal from './modal'; import CronLogModal from './logModal'; +import { useCtx, useTheme } from '@/utils/hooks'; const { Text } = Typography; const { Search } = Input; @@ -139,7 +140,7 @@ const Crontab = () => { key: 'action', align: 'center' as const, render: (text: string, record: any, index: number) => { - const isPc = width === '100%'; + const isPc = !isPhone; return ( {record.status === CrontabStatus.idle && ( @@ -180,9 +181,6 @@ const Crontab = () => { }, ]; - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); @@ -193,6 +191,7 @@ const Crontab = () => { const [selectedRowIds, setSelectedRowIds] = useState([]); const [currentPage, setCurrentPage] = useState(1); const [pageSize, setPageSize] = useState(20); + const { headerStyle, isPhone } = useCtx(); const getCrons = () => { setLoading(true); @@ -535,15 +534,6 @@ const Crontab = () => { }, [searchText]); useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - } setPageSize(parseInt(localStorage.getItem('pageSize') || '20')); }, []); @@ -564,16 +554,7 @@ const Crontab = () => { , ]} header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > {selectedRowIds.length > 0 && ( diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index 34eff25a..89055486 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -6,16 +6,14 @@ import { request } from '@/utils/http'; import './index.less'; import { DiffEditor } from '@monaco-editor/react'; import ReactDiffViewer from 'react-diff-viewer'; +import { useCtx, useTheme } from '@/utils/hooks'; const Crontab = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); const [sample, setSample] = useState(''); const [loading, setLoading] = useState(true); - const [theme, setTheme] = useState(''); - const [isPhone, setIsPhone] = useState(false); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getConfig = () => { request.get(`${config.apiPrefix}configs/config.sh`).then((data) => { @@ -34,54 +32,17 @@ const Crontab = () => { }; useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getConfig(); getSample(); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( {isPhone ? ( @@ -118,11 +79,9 @@ const Crontab = () => { options={{ readOnly: true, fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, glyphMargin: false, - renderSideBySide: width === '100%', wordWrap: 'on', }} theme={theme} diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 55f1f344..a4efb141 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -25,6 +25,7 @@ import EditNameModal from './editNameModal'; import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import './index.less'; +import { useCtx } from '@/utils/hooks'; const { Text } = Typography; const { Search } = Input; @@ -194,9 +195,6 @@ const Env = () => { }, }, ]; - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState([]); const [loading, setLoading] = useState(true); const [isModalVisible, setIsModalVisible] = useState(false); @@ -204,6 +202,7 @@ const Env = () => { const [editedEnv, setEditedEnv] = useState(); const [selectedRowIds, setSelectedRowIds] = useState([]); const [searchText, setSearchText] = useState(''); + const { headerStyle, isPhone } = useCtx(); const getEnvs = () => { setLoading(true); @@ -423,18 +422,6 @@ const Env = () => { getEnvs(); }, [searchText]); - useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - } - }, []); - return ( { , ]} header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > {selectedRowIds.length > 0 && ( @@ -511,7 +489,7 @@ const Env = () => { scroll={{ x: 768 }} components={components} loading={loading} - onRow={(record, index) => { + onRow={(record: any, index: number) => { return { index, moveRow, diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index 9e353352..6506eb14 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -6,6 +6,7 @@ import Editor from '@monaco-editor/react'; import { request } from '@/utils/http'; import styles from './index.module.less'; import { Controlled as CodeMirror } from 'react-codemirror2'; +import { useCtx, useTheme } from '@/utils/hooks'; function getFilterData(keyword: string, data: any) { const expandedKeys: string[] = []; @@ -37,19 +38,16 @@ function getFilterData(keyword: string, data: any) { } const Log = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [title, setTitle] = useState('请选择日志文件'); const [value, setValue] = useState('请选择日志文件'); const [select, setSelect] = useState(); const [data, setData] = useState([]); const [filterData, setFilterData] = useState([]); const [loading, setLoading] = useState(false); - const [isPhone, setIsPhone] = useState(false); const [height, setHeight] = useState(); const treeDom = useRef(); - const [theme, setTheme] = useState(''); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getLogs = () => { setLoading(true); @@ -106,38 +104,10 @@ const Log = () => { ); useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getLogs(); setHeight(treeDom.current.clientHeight); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( { ] } header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} >
@@ -212,7 +173,6 @@ const Log = () => { options={{ readOnly: true, fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, fontFamily: 'Source Code Pro', folding: false, diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index 60c1fdbc..2f67047f 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -7,6 +7,7 @@ import { request } from '@/utils/http'; import styles from './index.module.less'; import EditModal from './editModal'; import { Controlled as CodeMirror } from 'react-codemirror2'; +import { useCtx, useTheme } from '@/utils/hooks'; function getFilterData(keyword: string, data: any) { if (keyword) { @@ -29,21 +30,18 @@ const LangMap: any = { }; const Script = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [title, setTitle] = useState('请选择脚本文件'); const [value, setValue] = useState('请选择脚本文件'); const [select, setSelect] = useState(); const [data, setData] = useState([]); const [filterData, setFilterData] = useState([]); const [loading, setLoading] = useState(false); - const [isPhone, setIsPhone] = useState(false); const [mode, setMode] = useState(''); const [height, setHeight] = useState(); const treeDom = useRef(); - const [theme, setTheme] = useState(''); const [isLogModalVisible, setIsLogModalVisible] = useState(false); + const { headerStyle, isPhone } = useCtx(); + const { theme } = useTheme(); const getScripts = () => { setLoading(true); @@ -64,7 +62,7 @@ const Script = () => { const onSelect = (value: any, node: any) => { const newMode = LangMap[value.slice(-3)] || ''; - setMode(newMode); + setMode(isPhone && newMode === 'typescript' ? 'javascript' : newMode); setSelect(value); setTitle(node.parent || node.value); getDetail(node); @@ -84,38 +82,10 @@ const Script = () => { ); useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - setIsPhone(true); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - setIsPhone(false); - } getScripts(); setHeight(treeDom.current.clientHeight); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( { ] } header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} >
@@ -202,7 +163,6 @@ const Script = () => { options={{ readOnly: true, fontSize: 12, - minimap: { enabled: width === '100%' }, lineNumbersMinChars: 3, folding: false, glyphMargin: false, diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx index 08827385..26ae123e 100644 --- a/src/pages/setting/index.tsx +++ b/src/pages/setting/index.tsx @@ -10,6 +10,7 @@ import { setFetchMethod, } from 'darkreader'; import { history } from 'umi'; +import { useCtx } from '@/utils/hooks'; const optionsWithDisabled = [ { label: '亮色', value: 'light' }, @@ -18,13 +19,11 @@ const optionsWithDisabled = [ ]; const Password = () => { - const [width, setWidth] = useState('100%'); - const [marginLeft, setMarginLeft] = useState(0); - const [marginTop, setMarginTop] = useState(-72); const [value, setValue] = useState(''); const [loading, setLoading] = useState(true); const defaultDarken = localStorage.getItem('qinglong_dark_theme') || 'auto'; const [theme, setTheme] = useState(defaultDarken); + const { headerStyle, isPhone } = useCtx(); const handleOk = (values: any) => { request @@ -54,18 +53,6 @@ const Password = () => { }); }; - useEffect(() => { - if (document.body.clientWidth < 768) { - setWidth('auto'); - setMarginLeft(0); - setMarginTop(0); - } else { - setWidth('100%'); - setMarginLeft(0); - setMarginTop(-72); - } - }, []); - useEffect(() => { setFetchMethod(window.fetch); if (theme === 'dark') { @@ -90,16 +77,7 @@ const Password = () => { className="ql-container-wrapper" title="系统设置" header={{ - style: { - padding: '4px 16px 4px 15px', - position: 'sticky', - top: 0, - left: 0, - zIndex: 20, - marginTop, - width, - marginLeft, - }, + style: headerStyle, }} > 平台 > 内核 + 载体 + 内核版本 + 载体版本 > 外壳 + 外壳版本 + const ua = navigator.userAgent.toLowerCase(); + const testUa = (regexp: RegExp) => regexp.test(ua); + const testVs = (regexp: RegExp) => + (ua.match(regexp) || []) + .toString() + .replace(/[^0-9|_.]/g, '') + .replace(/_/g, '.'); + + // 系统 + let system = 'unknow'; + if (testUa(/windows|win32|win64|wow32|wow64/g)) { + system = 'windows'; // windows系统 + } else if (testUa(/macintosh|macintel/g)) { + system = 'macos'; // macos系统 + } else if (testUa(/x11/g)) { + system = 'linux'; // linux系统 + } else if (testUa(/android|adr/g)) { + system = 'android'; // android系统 + } else if (testUa(/ios|iphone|ipad|ipod|iwatch/g)) { + system = 'ios'; // ios系统 + } + + // 系统版本 + let systemVs = 'unknow'; + if (system === 'windows') { + if (testUa(/windows nt 5.0|windows 2000/g)) { + systemVs = '2000'; + } else if (testUa(/windows nt 5.1|windows xp/g)) { + systemVs = 'xp'; + } else if (testUa(/windows nt 5.2|windows 2003/g)) { + systemVs = '2003'; + } else if (testUa(/windows nt 6.0|windows vista/g)) { + systemVs = 'vista'; + } else if (testUa(/windows nt 6.1|windows 7/g)) { + systemVs = '7'; + } else if (testUa(/windows nt 6.2|windows 8/g)) { + systemVs = '8'; + } else if (testUa(/windows nt 6.3|windows 8.1/g)) { + systemVs = '8.1'; + } else if (testUa(/windows nt 10.0|windows 10/g)) { + systemVs = '10'; + } + } else if (system === 'macos') { + systemVs = testVs(/os x [\d._]+/g); + } else if (system === 'android') { + systemVs = testVs(/android [\d._]+/g); + } else if (system === 'ios') { + systemVs = testVs(/os [\d._]+/g); + } + + // 平台 + let platform = 'unknow'; + if (system === 'windows' || system === 'macos' || system === 'linux') { + platform = 'desktop'; // 桌面端 + } else if (system === 'android' || system === 'ios' || testUa(/mobile/g)) { + platform = 'mobile'; // 移动端 + } + + // 内核和载体 + let engine = 'unknow'; + let supporter = 'unknow'; + if (testUa(/applewebkit/g)) { + engine = 'webkit'; // webkit内核 + if (testUa(/edge/g)) { + supporter = 'edge'; // edge浏览器 + } else if (testUa(/opr/g)) { + supporter = 'opera'; // opera浏览器 + } else if (testUa(/chrome/g)) { + supporter = 'chrome'; // chrome浏览器 + } else if (testUa(/safari/g)) { + supporter = 'safari'; // safari浏览器 + } + } else if (testUa(/gecko/g) && testUa(/firefox/g)) { + engine = 'gecko'; // gecko内核 + supporter = 'firefox'; // firefox浏览器 + } else if (testUa(/presto/g)) { + engine = 'presto'; // presto内核 + supporter = 'opera'; // opera浏览器 + } else if (testUa(/trident|compatible|msie/g)) { + engine = 'trident'; // trident内核 + supporter = 'iexplore'; // iexplore浏览器 + } + + // 内核版本 + let engineVs = 'unknow'; + if (engine === 'webkit') { + engineVs = testVs(/applewebkit\/[\d._]+/g); + } else if (engine === 'gecko') { + engineVs = testVs(/gecko\/[\d._]+/g); + } else if (engine === 'presto') { + engineVs = testVs(/presto\/[\d._]+/g); + } else if (engine === 'trident') { + engineVs = testVs(/trident\/[\d._]+/g); + } + + // 载体版本 + let supporterVs = 'unknow'; + if (supporter === 'chrome') { + supporterVs = testVs(/chrome\/[\d._]+/g); + } else if (supporter === 'safari') { + supporterVs = testVs(/version\/[\d._]+/g); + } else if (supporter === 'firefox') { + supporterVs = testVs(/firefox\/[\d._]+/g); + } else if (supporter === 'opera') { + supporterVs = testVs(/opr\/[\d._]+/g); + } else if (supporter === 'iexplore') { + supporterVs = testVs(/(msie [\d._]+)|(rv:[\d._]+)/g); + } else if (supporter === 'edge') { + supporterVs = testVs(/edge\/[\d._]+/g); + } + + // 外壳和外壳版本 + let shell = 'none'; + let shellVs = 'unknow'; + if (testUa(/micromessenger/g)) { + shell = 'wechat'; // 微信浏览器 + shellVs = testVs(/micromessenger\/[\d._]+/g); + } else if (testUa(/qqbrowser/g)) { + shell = 'qq'; // QQ浏览器 + shellVs = testVs(/qqbrowser\/[\d._]+/g); + } else if (testUa(/ucbrowser/g)) { + shell = 'uc'; // UC浏览器 + shellVs = testVs(/ucbrowser\/[\d._]+/g); + } else if (testUa(/qihu 360se/g)) { + shell = '360'; // 360浏览器(无版本) + } else if (testUa(/2345explorer/g)) { + shell = '2345'; // 2345浏览器 + shellVs = testVs(/2345explorer\/[\d._]+/g); + } else if (testUa(/metasr/g)) { + shell = 'sougou'; // 搜狗浏览器(无版本) + } else if (testUa(/lbbrowser/g)) { + shell = 'liebao'; // 猎豹浏览器(无版本) + } else if (testUa(/maxthon/g)) { + shell = 'maxthon'; // 遨游浏览器 + shellVs = testVs(/maxthon\/[\d._]+/g); + } + + const result = Object.assign( + { + engine, // webkit gecko presto trident + engineVs, + platform, // desktop mobile + supporter, // chrome safari firefox opera iexplore edge + supporterVs, + system, // windows macos linux android ios + systemVs, + }, + shell === 'none' + ? {} + : { + shell, // wechat qq uc 360 2345 sougou liebao maxthon + shellVs, + }, + ); + + console.log(result); + return result; +} diff --git a/src/utils/hooks.ts b/src/utils/hooks.ts new file mode 100644 index 00000000..3310831a --- /dev/null +++ b/src/utils/hooks.ts @@ -0,0 +1,62 @@ +import { useState, useEffect } from 'react'; +import browserType from './browser'; + +export const useCtx = () => { + const [width, setWidth] = useState('100%'); + const [marginLeft, setMarginLeft] = useState(0); + const [marginTop, setMarginTop] = useState(-72); + const [isPhone, setIsPhone] = useState(false); + + useEffect(() => { + const { platform } = browserType(); + + if (platform === 'mobile') { + setWidth('auto'); + setMarginLeft(0); + setMarginTop(0); + setIsPhone(true); + } else { + setWidth('100%'); + setMarginLeft(0); + setMarginTop(-72); + setIsPhone(false); + } + }, []); + + return { + headerStyle: { + padding: '4px 16px 4px 15px', + position: 'sticky', + top: 0, + left: 0, + zIndex: 20, + marginTop, + width, + marginLeft, + } as any, + isPhone, + }; +}; + +export const useTheme = () => { + const [theme, setTheme] = useState(''); + + useEffect(() => { + const media = window.matchMedia('(prefers-color-scheme: dark)'); + const storageTheme = localStorage.getItem('qinglong_dark_theme'); + const isDark = + (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; + setTheme(isDark ? 'vs-dark' : 'vs'); + media.addEventListener('change', (e) => { + if (storageTheme === 'auto' || !storageTheme) { + if (e.matches) { + setTheme('vs-dark'); + } else { + setTheme('vs'); + } + } + }); + }, []); + + return { theme }; +}; From 59c9b17c40d17efd5efb4f7b2f8551ccf4a9589b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 16:00:45 +0800 Subject: [PATCH 215/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/env/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index a4efb141..039ca2da 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -164,7 +164,7 @@ const Env = () => { key: 'action', align: 'center' as const, render: (text: string, record: any, index: number) => { - const isPc = width === '100%'; + const isPc = !isPhone; return ( From 63f21b16984ef1260cda94b155a3e08896f85401 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 18:57:48 +0800 Subject: [PATCH 216/247] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E6=9C=89=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E4=B8=AD=E6=96=AD=E7=9A=84tee?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 6 +++--- shell/task.sh | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index a9ed9e06..98f9a186 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -170,10 +170,10 @@ update_cron() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "## 更新任务状态成功" | tee -p -a $log_path + echo -e "## 更新任务状态成功" >> $log_path else - echo -e "## 更新任务状态失败(${message})" | tee -p -a $log_path + echo -e "## 更新任务状态失败(${message})" >> $log_path fi } -get_token \ No newline at end of file +get_token diff --git a/shell/task.sh b/shell/task.sh index 359ba3e4..56b102b2 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -91,17 +91,17 @@ run_normal() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path + echo -e "## 开始执行... $begin_time\n" >> $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" . $file_task_before - timeout -k 10s $command_timeout_time $which_program $p1 2>&1 | tee -p -a $log_path + timeout -k 10s $command_timeout_time $which_program $p1 2>&1 >> $log_path . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -p -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" >> $log_path } ## 并发执行时,设定的 RandomDelay 不会生效,即所有任务立即执行 @@ -125,10 +125,10 @@ run_concurrent() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path + echo -e "## 开始执行... $begin_time\n" >> $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" . $file_task_before - echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" | tee -p -a $log_path + echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" >> $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") for i in "${!array[@]}"; do @@ -141,7 +141,7 @@ run_concurrent() { [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -p -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" >> $log_path } ## 运行其他命令 @@ -154,17 +154,17 @@ run_else() { local id=$(cat $list_crontab_user | grep -E "$cmd_task $p1" | perl -pe "s|.*ID=(.*) $cmd_task $p1\.*|\1|" | head -1 | awk -F " " '{print $1}') local begin_time=$(date '+%Y-%m-%d %H:%M:%S') - echo -e "## 开始执行... $begin_time\n" | tee -p -a $log_path + echo -e "## 开始执行... $begin_time\n" >> $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" . $file_task_before - timeout -k 10s $command_timeout_time "$@" 2>&1 | tee -p -a $log_path + timeout -k 10s $command_timeout_time "$@" 2>&1 >> $log_path . $file_task_after [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) - echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" | tee -p -a $log_path + echo -e "\n## 执行结束... $end_time 耗时 $diff_time 秒" >> $log_path } ## 命令检测 @@ -191,6 +191,7 @@ main() { run_else "$@" ;; esac + cat $log_path elif [[ $# -eq 0 ]]; then echo usage From 635306e2d3a4235397173461414b2891ea2113a0 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 19:02:21 +0800 Subject: [PATCH 217/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index 98f9a186..1cf19aca 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -170,9 +170,9 @@ update_cron() { code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) if [[ $code == 200 ]]; then - echo -e "## 更新任务状态成功" >> $log_path + echo -e "## 更新任务状态成功\n" >> $log_path else - echo -e "## 更新任务状态失败(${message})" >> $log_path + echo -e "\n## 更新任务状态失败(${message})" >> $log_path fi } From 43e02905c8d57559c0f3c09271a6660c64ff815c Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 19:04:01 +0800 Subject: [PATCH 218/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 5f204cfc..735c8b2a 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.1'; -export const changeLog = 'https://t.me/jiaolongwang/122'; +export const version = 'v2.8.1-001'; +export const changeLog = 'https://t.me/jiaolongwang/123'; From 2a9751e051bea01aca2fb230f337515a4646545f Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 19:07:45 +0800 Subject: [PATCH 219/247] =?UTF-8?q?=E6=B8=85=E7=A9=BA=E9=BB=98=E8=AE=A4ngi?= =?UTF-8?q?nx=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/share.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/share.sh b/shell/share.sh index aa9aedc6..9c6596d8 100755 --- a/shell/share.sh +++ b/shell/share.sh @@ -195,8 +195,8 @@ fix_config() { fi if [ -s /etc/nginx/conf.d/default.conf ]; then - echo -e "检测到默认nginx配置文件,删除...\n" - rm -f /etc/nginx/conf.d/default.conf + echo -e "检测到默认nginx配置文件,清空...\n" + echo '' > /etc/nginx/conf.d/default.conf echo fi } From 2f4fb657e6167931651013f373fc3f485c160f7c Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 21:21:28 +0800 Subject: [PATCH 220/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8DmatchMedia=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/hooks.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/utils/hooks.ts b/src/utils/hooks.ts index 3310831a..14ec3c60 100644 --- a/src/utils/hooks.ts +++ b/src/utils/hooks.ts @@ -47,7 +47,8 @@ export const useTheme = () => { const isDark = (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { + + const cb = (e: any) => { if (storageTheme === 'auto' || !storageTheme) { if (e.matches) { setTheme('vs-dark'); @@ -55,7 +56,12 @@ export const useTheme = () => { setTheme('vs'); } } - }); + }; + if (typeof media.addEventListener === 'function') { + media.addEventListener('change', cb); + } else if (typeof media.addListener === 'function') { + media.addListener(cb); + } }, []); return { theme }; From 2ddf69a79a14436c59a36a4773474b2b53df3059 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Mon, 2 Aug 2021 21:44:42 +0800 Subject: [PATCH 221/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8DmatchMedia=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/script/editModal.tsx | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/pages/script/editModal.tsx b/src/pages/script/editModal.tsx index 0fb937c1..58b07df5 100644 --- a/src/pages/script/editModal.tsx +++ b/src/pages/script/editModal.tsx @@ -6,6 +6,7 @@ import SplitPane from 'react-split-pane'; import Editor from '@monaco-editor/react'; import SaveModal from './saveModal'; import SettingModal from './setting'; +import { useTheme } from '@/utils/hooks'; const { Option } = Select; const LangMap: any = { @@ -35,7 +36,6 @@ const EditModal = ({ handleCancel: () => void; }) => { const [value, setValue] = useState(''); - const [theme, setTheme] = useState(''); const [language, setLanguage] = useState('javascript'); const [fileName, setFileName] = useState(''); const [saveModalVisible, setSaveModalVisible] = useState(false); @@ -43,6 +43,7 @@ const EditModal = ({ useState(false); const [isNewFile, setIsNewFile] = useState(false); const [log, setLog] = useState(''); + const { theme } = useTheme(); const cancel = () => { handleCancel(); @@ -80,23 +81,6 @@ const EditModal = ({ setIsNewFile(!currentFile); }, []); - useEffect(() => { - const media = window.matchMedia('(prefers-color-scheme: dark)'); - const storageTheme = localStorage.getItem('qinglong_dark_theme'); - const isDark = - (media.matches && storageTheme !== 'light') || storageTheme === 'dark'; - setTheme(isDark ? 'vs-dark' : 'vs'); - media.addEventListener('change', (e) => { - if (storageTheme === 'auto' || !storageTheme) { - if (e.matches) { - setTheme('vs-dark'); - } else { - setTheme('vs'); - } - } - }); - }, []); - return ( Date: Mon, 2 Aug 2021 21:46:29 +0800 Subject: [PATCH 222/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 735c8b2a..0c75590c 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.1-001'; -export const changeLog = 'https://t.me/jiaolongwang/123'; +export const version = 'v2.8.1-002'; +export const changeLog = 'https://t.me/jiaolongwang/124'; From c51306ef27d55c2cd21604ccf30f74ad27a2ed36 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 3 Aug 2021 11:07:05 +0800 Subject: [PATCH 223/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dql=20update=E4=B8=ADr?= =?UTF-8?q?eset=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 18 +++++++----------- src/layouts/index.tsx | 4 +++- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index bd52a1b0..faad93e8 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -119,7 +119,7 @@ add_cron() { cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" [[ -z $cron_line ]] && cron_line=$(grep "cron:" $file | awk -F ":" '{print $2}' | xargs) - [[ -z $cron_line ]] && cron_line=$(grep "cron " $file | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron " $file | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" result=$(add_cron_api "$cron_line:$cmd_task $file:$cron_name") echo -e "$result" @@ -193,7 +193,7 @@ update_raw() { cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$raw_file_name" [[ -z $cron_line ]] && cron_line=$(grep "cron:" $raw_file_name | awk -F ":" '{print $2}' | xargs) - [[ -z $cron_line ]] && cron_line=$(grep "cron " $raw_file_name | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron " $raw_file_name | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" if [[ -z $cron_id ]]; then result=$(add_cron_api "$cron_line:$cmd_task $filename:$cron_name") @@ -238,8 +238,8 @@ update_qinglong() { local no_restart="$1" [ -f $dir_root/package.json ] && ql_depend_old=$(cat $dir_root/package.json) - reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" - git_pull_scripts $dir_root + reset_romote_url ${dir_root} "${github_proxy_url}https://github.com/whyour/qinglong.git" "master" + git_pull_scripts $dir_root "master" if [[ $exit_status -eq 0 ]]; then echo -e "\n更新$dir_root成功...\n" @@ -255,12 +255,8 @@ update_qinglong() { local url="${github_proxy_url}https://github.com/whyour/qinglong-static.git" if [ -d ${ql_static_repo}/.git ]; then - reset_romote_url ${ql_static_repo} ${url} - cd ${ql_static_repo} - git fetch --all - exit_status=$? - git reset --hard origin/master - cd $dir_root + reset_romote_url ${ql_static_repo} ${url} "master" + git_pull_scripts ${ql_static_repo} "master" else git_clone_scripts ${url} ${ql_static_repo} fi @@ -298,7 +294,7 @@ patch_version() { reload_pm2() { pm2 l >/dev/null 2>&1 - + if [[ $(pm2 info panel 2>/dev/null) ]]; then pm2 reload panel --source-map-support --time >/dev/null 2>&1 else diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 61890750..deee590a 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -29,6 +29,9 @@ export default function (props: any) { history.push('/login'); } vhCheck(); + + // patch custome layout title as react node [object, object] + document.title = '控制面板'; }, []); useEffect(() => { @@ -109,7 +112,6 @@ export default function (props: any) { }, ]; }} - pageTitleRender={() => '控制面板'} {...defaultProps} > {props.children} From 42fbed157f7e6e35e34c24ce3fbcd147520c1065 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 3 Aug 2021 11:14:33 +0800 Subject: [PATCH 224/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index deee590a..35530de5 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -112,6 +112,7 @@ export default function (props: any) { }, ]; }} + pageTitleRender={() => '控制面板'} {...defaultProps} > {props.children} From b86ee5674d099088b461933e76d711a4803aae32 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 3 Aug 2021 11:23:06 +0800 Subject: [PATCH 225/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/back/services/cron.ts b/back/services/cron.ts index 1676274b..9b5a10cb 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -183,6 +183,7 @@ export default class CronService { this.cronDb.update( { _id: { $in: ids } }, { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, + { multi: true }, ); resolve(); }); From 5fd79173d6699e523bedf30430f5bd695700ff56 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 3 Aug 2021 12:06:38 +0800 Subject: [PATCH 226/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95kill=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=BF=9B=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/cron.ts | 69 ++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/back/services/cron.ts b/back/services/cron.ts index 9b5a10cb..16f94507 100644 --- a/back/services/cron.ts +++ b/back/services/cron.ts @@ -9,6 +9,7 @@ import cron_parser from 'cron-parser'; import { getFileContentByName } from '../config/util'; import PQueue from 'p-queue'; import { promises, existsSync } from 'fs'; +import { promisify } from 'util'; @Service() export default class CronService { @@ -164,32 +165,58 @@ export default class CronService { public async stop(ids: string[]) { return new Promise((resolve: any) => { - this.cronDb.find({ _id: { $in: ids } }).exec((err, docs: Crontab[]) => { - for (const doc of docs) { - if (doc.pid) { - try { - process.kill(-doc.pid); - } catch (error) { - this.logger.silly(error); + this.cronDb + .find({ _id: { $in: ids } }) + .exec(async (err, docs: Crontab[]) => { + for (const doc of docs) { + if (doc.pid) { + try { + process.kill(-doc.pid); + } catch (error) { + this.logger.silly(error); + } + } + const err = await this.killTask(doc.command); + if (doc.log_path) { + const str = err ? `\n${err}` : ''; + fs.appendFileSync( + `${doc.log_path}`, + `${str}\n## 执行结束... ${new Date().toLocaleString()} `, + ); } } - if (doc.log_path) { - fs.appendFileSync( - `${doc.log_path}`, - `\n## 执行结束... ${new Date().toLocaleString()} `, - ); - } - } - this.cronDb.update( - { _id: { $in: ids } }, - { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, - { multi: true }, - ); - resolve(); - }); + this.cronDb.update( + { _id: { $in: ids } }, + { $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, + { multi: true }, + ); + this.queue.clear(); + resolve(); + }); }); } + private async killTask(name: string) { + let taskCommond = `ps -ef | grep "${name}" | grep -v grep | awk '{print $1}'`; + const execAsync = promisify(exec); + try { + let pid = (await execAsync(taskCommond)).stdout; + if (pid) { + pid = (await execAsync(`pstree -p ${pid}`)).stdout; + } else { + return; + } + const pids = pid.match(/\d+/g); + for (const id of pids) { + const c = `kill -9 ${id}`; + const { stdout, stderr } = await execAsync(c); + return stderr; + } + } catch (e) { + return JSON.stringify(e); + } + } + private async runSingle(id: string): Promise { return new Promise(async (resolve: any) => { const cron = await this.get(id); From eba78ca84f92a61ca84a2c6e844601cc92422c39 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 3 Aug 2021 18:06:40 +0800 Subject: [PATCH 227/247] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/config/index.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 74542ec6..d021c01e 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -1,4 +1,4 @@ -import React, { PureComponent, Fragment, useState, useEffect } from 'react'; +import React, { PureComponent, Fragment, useState, useEffect, useRef } from 'react'; import { Button, message, Modal, TreeSelect } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; @@ -15,6 +15,7 @@ const Config = () => { const [data, setData] = useState([]); const { headerStyle, isPhone } = useCtx(); const { theme } = useTheme(); + const editorRef = useRef(null); const getConfig = (name: string) => { request.get(`${config.apiPrefix}configs/${name}`).then((data: any) => { @@ -33,9 +34,11 @@ const Config = () => { }; const updateConfig = () => { + const content = editorRef.current.getValue(1); + request .post(`${config.apiPrefix}configs/save`, { - data: { content: value, name: select }, + data: { content, name: select }, }) .then((data: any) => { message.success(data.message); @@ -101,8 +104,8 @@ const Config = () => { folding: false, glyphMargin: false, }} - onChange={(val) => { - setValue((val as string).replace(/\r\n/g, '\n')); + onMount={(editor) => { + editorRef.current = editor; }} /> )} From d8587b64a5ce070a82f3b872ee4a3c7669f470dd Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 3 Aug 2021 18:45:24 +0800 Subject: [PATCH 228/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9set=20envs=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/services/env.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/back/services/env.ts b/back/services/env.ts index 98f40638..cc18c3dd 100644 --- a/back/services/env.ts +++ b/back/services/env.ts @@ -211,14 +211,16 @@ export default class EnvService { const envs = await this.envs( '', { position: -1 }, - { status: { $ne: EnvStatus.disabled }, name: { $exists: true } }, + { name: { $exists: true } }, ); const groups = _.groupBy(envs, 'name'); let env_string = ''; for (const key in groups) { if (Object.prototype.hasOwnProperty.call(groups, key)) { const group = groups[key]; - env_string += `export ${key}="${_.map(group, 'value') + env_string += `export ${key}="${_(group) + .filter((x) => x.status !== EnvStatus.disabled) + .map('value') .join('&') .replace(/ /g, '')}"\n`; } From 9e4b41ce48cc5da90976635790e12b497859ea84 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Tue, 3 Aug 2021 19:03:41 +0800 Subject: [PATCH 229/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA=E6=97=A0=E6=B3=95=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- back/api/config.ts | 2 +- src/pages/log/index.tsx | 3 --- src/pages/script/editModal.tsx | 9 +++++---- src/pages/script/index.tsx | 3 --- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/back/api/config.ts b/back/api/config.ts index 1c4afb2a..b05f97f7 100644 --- a/back/api/config.ts +++ b/back/api/config.ts @@ -59,7 +59,7 @@ export default (app: Router) => { celebrate({ body: Joi.object({ name: Joi.string().required(), - content: Joi.string().required(), + content: Joi.string().allow('').optional(), }), }), async (req: Request, res: Response, next: NextFunction) => { diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index 6506eb14..2479061b 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -179,9 +179,6 @@ const Log = () => { glyphMargin: false, wordWrap: 'on', }} - onChange={(val, ev) => { - setValue((val as string).replace(/\r\n/g, '\n')); - }} /> )}
diff --git a/src/pages/script/editModal.tsx b/src/pages/script/editModal.tsx index 58b07df5..4c450c8f 100644 --- a/src/pages/script/editModal.tsx +++ b/src/pages/script/editModal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import { Drawer, Button, Tabs, Badge, Select, TreeSelect } from 'antd'; import { request } from '@/utils/http'; import config from '@/utils/config'; @@ -44,6 +44,7 @@ const EditModal = ({ const [isNewFile, setIsNewFile] = useState(false); const [log, setLog] = useState(''); const { theme } = useTheme(); + const editorRef = useRef(null); const cancel = () => { handleCancel(); @@ -164,8 +165,8 @@ const EditModal = ({ lineNumbersMinChars: 3, glyphMargin: false, }} - onChange={(val) => { - setValue((val as string).replace(/\r\n/g, '\n')); + onMount={(editor) => { + editorRef.current = editor; }} />
@@ -178,7 +179,7 @@ const EditModal = ({ setSaveModalVisible(false); }} isNewFile={isNewFile} - file={{ content: value, filename: fileName }} + file={{ content: editorRef.current.getValue(1), filename: fileName }} /> { folding: false, glyphMargin: false, }} - onChange={(val) => { - setValue((val as string).replace(/\r\n/g, '\n')); - }} /> )} Date: Tue, 3 Aug 2021 19:05:01 +0800 Subject: [PATCH 230/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=E7=AE=A1=E7=90=86editorRef=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/script/editModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/script/editModal.tsx b/src/pages/script/editModal.tsx index 4c450c8f..89a5fb81 100644 --- a/src/pages/script/editModal.tsx +++ b/src/pages/script/editModal.tsx @@ -179,7 +179,7 @@ const EditModal = ({ setSaveModalVisible(false); }} isNewFile={isNewFile} - file={{ content: editorRef.current.getValue(1), filename: fileName }} + file={{ content: editorRef.current && editorRef.current.getValue(1), filename: fileName }} /> Date: Tue, 3 Aug 2021 21:12:31 +0800 Subject: [PATCH 231/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dwindows=E6=8D=A2?= =?UTF-8?q?=E8=A1=8C=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/config/index.tsx | 2 +- src/pages/script/editModal.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index d021c01e..4a7847a1 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -34,7 +34,7 @@ const Config = () => { }; const updateConfig = () => { - const content = editorRef.current.getValue(1); + const content = editorRef.current.getValue().replace(/\r\n/g, '\n'); request .post(`${config.apiPrefix}configs/save`, { diff --git a/src/pages/script/editModal.tsx b/src/pages/script/editModal.tsx index 89a5fb81..04e8c72e 100644 --- a/src/pages/script/editModal.tsx +++ b/src/pages/script/editModal.tsx @@ -179,7 +179,7 @@ const EditModal = ({ setSaveModalVisible(false); }} isNewFile={isNewFile} - file={{ content: editorRef.current && editorRef.current.getValue(1), filename: fileName }} + file={{ content: editorRef.current && editorRef.current.getValue().replace(/\r\n/g, '\n'), filename: fileName }} /> Date: Tue, 3 Aug 2021 21:37:28 +0800 Subject: [PATCH 232/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=89=8B=E6=9C=BA?= =?UTF-8?q?=E7=AB=AF=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/config/index.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 4a7847a1..149c92e9 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -1,4 +1,10 @@ -import React, { PureComponent, Fragment, useState, useEffect, useRef } from 'react'; +import React, { + PureComponent, + Fragment, + useState, + useEffect, + useRef, +} from 'react'; import { Button, message, Modal, TreeSelect } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; @@ -34,7 +40,9 @@ const Config = () => { }; const updateConfig = () => { - const content = editorRef.current.getValue().replace(/\r\n/g, '\n'); + const content = editorRef.current + ? editorRef.current.getValue().replace(/\r\n/g, '\n') + : value; request .post(`${config.apiPrefix}configs/save`, { From d6f51988930da4c603c83306674bf913b931a1f7 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 5 Aug 2021 01:07:47 +0800 Subject: [PATCH 233/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A6=96=E6=AC=A1?= =?UTF-8?q?=E6=8B=89=E5=8C=BArepo=20cdn=E6=97=A0=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index faad93e8..01e0ce6a 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -152,11 +152,12 @@ update_repo() { local repo_path="${dir_repo}/${author}_${repo}" [[ $branch ]] && repo_path="${repo_path}_${branch}" + local formatUrl="${github_proxy_url}${url/https:\/\/ghproxy.com\//}" if [ -d ${repo_path}/.git ]; then - reset_romote_url ${repo_path} "${github_proxy_url}${url/https:\/\/ghproxy.com\//}" "${branch}" + reset_romote_url ${repo_path} "${formatUrl}" "${branch}" git_pull_scripts ${repo_path} "${branch}" else - git_clone_scripts ${url} ${repo_path} "${branch}" + git_clone_scripts "${formatUrl}" ${repo_path} "${branch}" fi if [[ $exit_status -eq 0 ]]; then echo -e "\n更新${repo_path}成功...\n" From 5fbad9956f11322a783fa31dc9c9991e0836d110 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 5 Aug 2021 14:42:53 +0800 Subject: [PATCH 234/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Drepo=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E6=97=A5=E5=BF=97=E6=96=87=E4=BB=B6=E5=94=AF=E4=B8=80?= =?UTF-8?q?=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/api.sh | 6 ++---- shell/task.sh | 18 +++++++++--------- shell/update.sh | 29 ++++++++++++++++++++--------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/shell/api.sh b/shell/api.sh index 1cf19aca..d241a3a8 100755 --- a/shell/api.sh +++ b/shell/api.sh @@ -169,10 +169,8 @@ update_cron() { ) code=$(echo $api | jq -r .code) message=$(echo $api | jq -r .message) - if [[ $code == 200 ]]; then - echo -e "## 更新任务状态成功\n" >> $log_path - else - echo -e "\n## 更新任务状态失败(${message})" >> $log_path + if [[ $code != 200 ]]; then + echo -e "\n## 更新任务状态失败(${message})\n" >> $log_path fi } diff --git a/shell/task.sh b/shell/task.sh index 56b102b2..4671e846 100755 --- a/shell/task.sh +++ b/shell/task.sh @@ -93,11 +93,11 @@ run_normal() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" >> $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + . $file_task_before >> $log_path 2>&1 - timeout -k 10s $command_timeout_time $which_program $p1 2>&1 >> $log_path + timeout -k 10s $command_timeout_time $which_program $p1 >> $log_path 2>&1 - . $file_task_after + . $file_task_after >> $log_path 2>&1 [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -127,17 +127,17 @@ run_concurrent() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" >> $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + . $file_task_before >> $log_path 2>&1 echo -e "\n各账号间已经在后台开始并发执行,前台不输入日志,日志直接写入文件中。\n" >> $log_path single_log_time=$(date "+%Y-%m-%d-%H-%M-%S.%N") for i in "${!array[@]}"; do export ${p3}=${array[i]} single_log_path="$log_dir/${single_log_time}_$((i + 1)).log" - timeout -k 10s $command_timeout_time $which_program $p1 &>$single_log_path & + timeout -k 10s $command_timeout_time $which_program $p1 &>$single_log_path 2>&1 & done - . $file_task_after + . $file_task_after >> $log_path 2>&1 [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) @@ -156,11 +156,11 @@ run_else() { local begin_time=$(date '+%Y-%m-%d %H:%M:%S') echo -e "## 开始执行... $begin_time\n" >> $log_path [[ $id ]] && update_cron "\"$id\"" "0" "$$" "$log_path" - . $file_task_before + . $file_task_before >> $log_path 2>&1 - timeout -k 10s $command_timeout_time "$@" 2>&1 >> $log_path + timeout -k 10s $command_timeout_time "$@" >> $log_path 2>&1 - . $file_task_after + . $file_task_after >> $log_path 2>&1 [[ $id ]] && update_cron "\"$id\"" "1" "" "$log_path" local end_time=$(date '+%Y-%m-%d %H:%M:%S') local diff_time=$(($(date +%s -d "$end_time") - $(date +%s -d "$begin_time"))) diff --git a/shell/update.sh b/shell/update.sh index 01e0ce6a..02473a55 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -141,16 +141,12 @@ update_repo() { local blackword="$3" local dependence="$4" local branch="$5" - local urlTmp="${url%*/}" - local repoTmp="${urlTmp##*/}" - local repo="${repoTmp%.*}" local tmp="${url%/*}" local authorTmp1="${tmp##*/}" local authorTmp2="${authorTmp1##*:}" local author="${authorTmp2##*.}" - local repo_path="${dir_repo}/${author}_${repo}" - [[ $branch ]] && repo_path="${repo_path}_${branch}" + local repo_path="${dir_repo}/${uniq_path}" local formatUrl="${github_proxy_url}${url/https:\/\/ghproxy.com\//}" if [ -d ${repo_path}/.git ]; then @@ -392,6 +388,21 @@ gen_list_repo() { cd $dir_current } +get_uniq_path() { + local url="$1" + local branch="$2" + local urlTmp="${url%*/}" + local repoTmp="${urlTmp##*/}" + local repo="${repoTmp%.*}" + local tmp="${url%/*}" + local authorTmp1="${tmp##*/}" + local authorTmp2="${authorTmp1##*:}" + local author="${authorTmp2##*.}" + + uniq_path="${author}_${repo}" + [[ $branch ]] && uniq_path="${uniq_path}_${branch}" +} + main() { local p1=$1 local p2=$2 @@ -413,8 +424,8 @@ main() { ;; repo) get_user_info - local name=$(echo "${p2##*/}" | awk -F "." '{print $1}') - log_path="$dir_log/update/${log_time}_$name.log" + get_uniq_path "$p2" "$p6" + log_path="$dir_log/update/${log_time}_${uniq_path}.log" echo -e "## 开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then update_repo "$p2" "$p3" "$p4" "$p5" "$p6" | tee -p -a $log_path @@ -425,8 +436,8 @@ main() { ;; raw) get_user_info - local name=$(echo "${p2##*/}" | awk -F "." '{print $1}') - log_path="$dir_log/update/${log_time}_$name.log" + get_uniq_path "$p2" + log_path="$dir_log/update/${log_time}_${uniq_path}.log" echo -e "## 开始执行... $begin_time\n" >> $log_path if [[ -n $p2 ]]; then update_raw "$p2" | tee -p -a $log_path From f1e0823a100483c76f063a86aa2761fac2ab321c Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 5 Aug 2021 15:05:40 +0800 Subject: [PATCH 235/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=95=E4=B8=AA?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=94=AF=E4=B8=80=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 02473a55..cd08abd1 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -124,9 +124,9 @@ add_cron() { result=$(add_cron_api "$cron_line:$cmd_task $file:$cron_name") echo -e "$result" if [[ $detail ]]; then - detail="${detail}\n${result}" + detail="${detail}${result}\n" else - detail="${result}" + detail="${result}\n" fi fi done @@ -166,8 +166,9 @@ update_repo() { ## 更新所有 raw 文件 update_raw() { echo -e "--------------------------------------------------------------\n" - local raw_url="$1" - raw_file_name=$(echo ${raw_url} | awk -F "/" '{print $NF}') + local raw_url="${github_proxy_url}${1/https:\/\/ghproxy.com\//}" + local suffix="${raw_url##*.}" + local raw_file_name="${uniq_path}${suffix}" echo -e "开始下载:${raw_url} \n\n保存路径:$dir_raw/${raw_file_name}\n" wget -q --no-check-certificate -O "$dir_raw/${raw_file_name}.new" ${raw_url} if [[ $? -eq 0 ]]; then @@ -194,7 +195,7 @@ update_raw() { [[ -z $cron_line ]] && cron_line="0 6 * * *" if [[ -z $cron_id ]]; then result=$(add_cron_api "$cron_line:$cmd_task $filename:$cron_name") - echo -e "$result" + echo -e "$result\n" notify "新增任务通知" "\n$result" # update_cron_api "$cron_line:$cmd_task $filename:$cron_name:$cron_id" fi From dfab2cb7f1a2b56241e92bd8563f6121a5d215c3 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 5 Aug 2021 15:06:00 +0800 Subject: [PATCH 236/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 0c75590c..08bdfa92 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.1-002'; -export const changeLog = 'https://t.me/jiaolongwang/124'; +export const version = 'v2.8.1-003'; +export const changeLog = 'https://t.me/jiaolongwang/125'; From e06175c3da488b6e036084b814b97a8de67e745a Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 5 Aug 2021 16:29:42 +0800 Subject: [PATCH 237/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Draw=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/update.sh b/shell/update.sh index cd08abd1..bcf5862e 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -168,7 +168,7 @@ update_raw() { echo -e "--------------------------------------------------------------\n" local raw_url="${github_proxy_url}${1/https:\/\/ghproxy.com\//}" local suffix="${raw_url##*.}" - local raw_file_name="${uniq_path}${suffix}" + local raw_file_name="${uniq_path}.${suffix}" echo -e "开始下载:${raw_url} \n\n保存路径:$dir_raw/${raw_file_name}\n" wget -q --no-check-certificate -O "$dir_raw/${raw_file_name}.new" ${raw_url} if [[ $? -eq 0 ]]; then From 069e236674b8caa361ae470bf73b6a2bd84f4f84 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 5 Aug 2021 18:02:00 +0800 Subject: [PATCH 238/247] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E8=AF=AD=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index bcf5862e..0ef5b6c9 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -278,10 +278,10 @@ update_qinglong() { } patch_version() { - if [ -f /ql/db/cookie.db ]; then + if [[ -f "/ql/db/cookie.db" ]]; then echo -e "检测到旧的db文件,拷贝为新db...\n" mv /ql/db/cookie.db /ql/db/env.db - rm /ql/db/cookie.db + rm -rf /ql/db/cookie.db echo fi From f2dbb64984c778d835eccd259db758a4a5debbfb Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Thu, 5 Aug 2021 21:18:50 +0800 Subject: [PATCH 239/247] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8rename=20input?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/layouts/index.less b/src/layouts/index.less index 91650eda..b708a155 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -32,6 +32,7 @@ body { .rename-input { height: 0; padding: 0 !important; + display: none !important; } } From 25236958ff1fcddfbf5f73725f81d54c901b7651 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 6 Aug 2021 14:46:42 +0800 Subject: [PATCH 240/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E5=BC=B9=E6=A1=86=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/index.less | 15 ++++++++++++--- src/pages/crontab/logModal.tsx | 11 ++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/layouts/index.less b/src/layouts/index.less index b708a155..d094cad0 100644 --- a/src/layouts/index.less +++ b/src/layouts/index.less @@ -14,9 +14,18 @@ body { background-color: rgb(248, 248, 248); } -.log-modal .ant-modal { - padding-bottom: 0 !important; - width: 580px !important; +.log-modal { + .ant-modal { + padding-bottom: 0 !important; + width: 580px !important; + } + + pre { + white-space: break-spaces; + line-height: 17px; + margin-bottom: 0; + overflow: hidden; + } } .monaco-editor:not(.rename-box) { diff --git a/src/pages/crontab/logModal.tsx b/src/pages/crontab/logModal.tsx index 488f03b9..2fe35912 100644 --- a/src/pages/crontab/logModal.tsx +++ b/src/pages/crontab/logModal.tsx @@ -108,20 +108,13 @@ const CronLogModal = ({ {!loading && value && (
           {value}

From 69a5ba899674d98908dd75cd8fe03be742679380 Mon Sep 17 00:00:00 2001
From: hanhh <18330117883@163.com>
Date: Fri, 6 Aug 2021 15:09:17 +0800
Subject: [PATCH 241/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 1fd29cb8..dfc96234 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
   
 

-

青龙(WIP)

+

青龙

From bc110ff9499877b497a6cad34341936d68750479 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 6 Aug 2021 16:05:33 +0800 Subject: [PATCH 242/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 0ef5b6c9..6f519202 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -118,8 +118,8 @@ add_cron() { ) cron_name=$(grep "new Env" $file | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$file_name" - [[ -z $cron_line ]] && cron_line=$(grep "cron:" $file | awk -F ":" '{print $2}' | xargs) - [[ -z $cron_line ]] && cron_line=$(grep "cron " $file | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron:" $file | awk -F ":" '{print $2}' | head -1 | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron " $file | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | head -1 | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" result=$(add_cron_api "$cron_line:$cmd_task $file:$cron_name") echo -e "$result" @@ -190,8 +190,8 @@ update_raw() { ) cron_name=$(grep "new Env" $raw_file_name | awk -F "\(" '{print $2}' | awk -F "\)" '{print $1}' | sed 's:^.\(.*\).$:\1:' | head -1) [[ -z $cron_name ]] && cron_name="$raw_file_name" - [[ -z $cron_line ]] && cron_line=$(grep "cron:" $raw_file_name | awk -F ":" '{print $2}' | xargs) - [[ -z $cron_line ]] && cron_line=$(grep "cron " $raw_file_name | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron:" $raw_file_name | awk -F ":" '{print $2}' | head -1 | xargs) + [[ -z $cron_line ]] && cron_line=$(grep "cron " $raw_file_name | awk -F "cron \"" '{print $2}' | awk -F "\" " '{print $1}' | head -1 | xargs) [[ -z $cron_line ]] && cron_line="0 6 * * *" if [[ -z $cron_id ]]; then result=$(add_cron_api "$cron_line:$cmd_task $filename:$cron_name") From 99f02e7c54aa4456f5da2afc517a62c547947890 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 6 Aug 2021 18:41:06 +0800 Subject: [PATCH 243/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfc96234..58922b27 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@
-Python 和 JavaScript 定时任务管理面板 +Python、JavaScript、Shell、Typescript 定时任务管理 [![docker version][docker-version-image]][docker-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url] [![donate][donate-image]][donate-url] From 95e104dc9ca367d5e47bbe182c1df24c30576f14 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 6 Aug 2021 18:42:45 +0800 Subject: [PATCH 244/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 58922b27..931c55c1 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@
-Python、JavaScript、Shell、Typescript 定时任务管理 +Python/JavaScript/Shell/Typescript 定时任务管理 [![docker version][docker-version-image]][docker-version-url] [![docker pulls][docker-pulls-image]][docker-pulls-url] [![docker stars][docker-stars-image]][docker-stars-url] [![docker image size][docker-image-size-image]][docker-image-size-url] [![donate][donate-image]][donate-url] From ebc2e0e4b68987385ac649dd376f5eed49f0b879 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Fri, 6 Aug 2021 19:10:02 +0800 Subject: [PATCH 245/247] =?UTF-8?q?PC=E7=AB=AF=E6=94=AF=E6=8C=81=E5=AF=B9?= =?UTF-8?q?=E6=AF=94=E5=B7=A5=E5=85=B7=E4=BF=AE=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/diff/index.tsx | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index 89055486..43503406 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -1,4 +1,4 @@ -import React, { PureComponent, Fragment, useState, useEffect } from 'react'; +import React, { PureComponent, useRef, useState, useEffect } from 'react'; import { Button, message, Modal } from 'antd'; import config from '@/utils/config'; import { PageContainer } from '@ant-design/pro-layout'; @@ -14,6 +14,7 @@ const Crontab = () => { const [loading, setLoading] = useState(true); const { headerStyle, isPhone } = useCtx(); const { theme } = useTheme(); + const editorRef = useRef(null); const getConfig = () => { request.get(`${config.apiPrefix}configs/config.sh`).then((data) => { @@ -31,6 +32,20 @@ const Crontab = () => { .finally(() => setLoading(false)); }; + const updateConfig = () => { + const content = editorRef.current + ? editorRef.current.getModel().modified.getValue().replace(/\r\n/g, '\n') + : value; + + request + .post(`${config.apiPrefix}configs/save`, { + data: { content, name: 'config.sh' }, + }) + .then((data: any) => { + message.success(data.message); + }); + }; + useEffect(() => { getConfig(); getSample(); @@ -44,6 +59,13 @@ const Crontab = () => { header={{ style: headerStyle, }} + extra={ + !isPhone && [ + , + ] + } > {isPhone ? ( { original={sample} modified={value} options={{ - readOnly: true, fontSize: 12, lineNumbersMinChars: 3, folding: false, @@ -85,6 +106,9 @@ const Crontab = () => { wordWrap: 'on', }} theme={theme} + onMount={(editor) => { + editorRef.current = editor; + }} /> )} From cbd1ddc5e708659cf29c76c6af96de42e96030d1 Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 7 Aug 2021 20:11:06 +0800 Subject: [PATCH 246/247] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgithub=5Fproxy=5Furl?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=BD=B1=E5=93=8D=E6=8B=89=E5=8F=96gitee?= =?UTF-8?q?=E4=BB=93=E5=BA=93=E6=88=96=E8=80=85=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shell/update.sh | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/shell/update.sh b/shell/update.sh index 6f519202..aeb395ef 100755 --- a/shell/update.sh +++ b/shell/update.sh @@ -148,7 +148,12 @@ update_repo() { local repo_path="${dir_repo}/${uniq_path}" - local formatUrl="${github_proxy_url}${url/https:\/\/ghproxy.com\//}" + local formatUrl="$url" + if [[ $github_proxy_url ]]; then + if [[ $url =~ "github.com" ]] || [[ $url =~ "githubusercontent.com" ]]; then + [[ ! $url =~ "https://ghproxy.com" ]] && formatUrl="${github_proxy_url}${url}" + fi + fi if [ -d ${repo_path}/.git ]; then reset_romote_url ${repo_path} "${formatUrl}" "${branch}" git_pull_scripts ${repo_path} "${branch}" @@ -166,7 +171,13 @@ update_repo() { ## 更新所有 raw 文件 update_raw() { echo -e "--------------------------------------------------------------\n" - local raw_url="${github_proxy_url}${1/https:\/\/ghproxy.com\//}" + local url="$1" + local raw_url="$url" + if [[ $github_proxy_url ]]; then + if [[ $url =~ "github.com" ]] || [[ $url =~ "githubusercontent.com" ]]; then + [[ ! $url =~ "https://ghproxy.com" ]] && raw_url="${github_proxy_url}${url}" + fi + fi local suffix="${raw_url##*.}" local raw_file_name="${uniq_path}.${suffix}" echo -e "开始下载:${raw_url} \n\n保存路径:$dir_raw/${raw_file_name}\n" @@ -227,7 +238,7 @@ usage() { echo -e "4. $cmd_update repo # 更新单个仓库的脚本" echo -e "5. $cmd_update rmlog # 删除旧日志" echo -e "6. $cmd_update bot # 启动tg-bot" - echo -e "7. $cmd_update reset # 重置青龙基础环境" + echo -e "7. $cmd_update check # 检测青龙环境并修复" } ## 更新qinglong From 6e36e06ddae89d4b88ea2a0e2ac203706e224b0b Mon Sep 17 00:00:00 2001 From: hanhh <18330117883@163.com> Date: Sat, 7 Aug 2021 20:12:38 +0800 Subject: [PATCH 247/247] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/version.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.ts b/src/version.ts index 08bdfa92..0c4ebc69 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1,2 +1,2 @@ -export const version = 'v2.8.1-003'; -export const changeLog = 'https://t.me/jiaolongwang/125'; +export const version = 'v2.8.1-004'; +export const changeLog = 'https://t.me/jiaolongwang/126';