diff --git a/app/wails/frontend/components.d.ts b/app/wails/frontend/components.d.ts
index 551f7c8..7003c82 100644
--- a/app/wails/frontend/components.d.ts
+++ b/app/wails/frontend/components.d.ts
@@ -10,12 +10,17 @@ declare module 'vue' {
CPUUsage: typeof import('./src/components/system/cpu/CPUUsage.vue')['default']
CPUUsageChart: typeof import('./src/components/system/cpu/CPUUsageChart.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
+ ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
ElCol: typeof import('element-plus/es')['ElCol']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
+ ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
+ ElIcon: typeof import('element-plus/es')['ElIcon']
+ ElInput: typeof import('element-plus/es')['ElInput']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElStatistic: typeof import('element-plus/es')['ElStatistic']
+ ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTableV2: typeof import('element-plus/es')['ElTableV2']
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
diff --git a/app/wails/frontend/index.html b/app/wails/frontend/index.html
index c6011c4..c3b93d3 100644
--- a/app/wails/frontend/index.html
+++ b/app/wails/frontend/index.html
@@ -4,6 +4,14 @@
wails
+
+
diff --git a/app/wails/frontend/package.json b/app/wails/frontend/package.json
index 8009489..ec8fe88 100644
--- a/app/wails/frontend/package.json
+++ b/app/wails/frontend/package.json
@@ -19,7 +19,9 @@
"vite": "^4.0.0"
},
"dependencies": {
+ "@amap/amap-jsapi-loader": "^1.0.1",
"@vueuse/core": "^10.2.1",
+ "axios": "^1.4.0",
"echarts": "^5.4.2",
"element-plus": "^2.3.7",
"eruda": "^3.0.0",
diff --git a/app/wails/frontend/package.json.md5 b/app/wails/frontend/package.json.md5
index 432f504..e933267 100644
--- a/app/wails/frontend/package.json.md5
+++ b/app/wails/frontend/package.json.md5
@@ -1 +1 @@
-d09bd561bfdf7ff46efd368fe8aa4abe
\ No newline at end of file
+56a069904657d2e7c850e467b8924bd9
\ No newline at end of file
diff --git a/app/wails/frontend/src/router/router.js b/app/wails/frontend/src/router/router.js
index a547b72..8b64642 100644
--- a/app/wails/frontend/src/router/router.js
+++ b/app/wails/frontend/src/router/router.js
@@ -31,6 +31,14 @@ const routes = [
groups: "/",
}
},
+ {
+ path: "/location-record",
+ component: ()=>import("src/views/tabs/location-record/index.vue"),
+ meta: {
+ title: "定位记录",
+ groups: "/"
+ }
+ },
{
path: "/test",
component: ()=>import("src/views/tabs/home/Test.vue"),
diff --git a/app/wails/frontend/src/utils/axios/index.ts b/app/wails/frontend/src/utils/axios/index.ts
new file mode 100644
index 0000000..18b4167
--- /dev/null
+++ b/app/wails/frontend/src/utils/axios/index.ts
@@ -0,0 +1,62 @@
+import axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig} from "axios";
+import {ElNotification} from "element-plus";
+
+export function getAxiosInstance(axiosRequestConfig: AxiosRequestConfig): AxiosInstance {
+ let instance = axios.create(axiosRequestConfig);
+ // 全局 请求拦截器
+ instance.interceptors.request.use(async (config: InternalAxiosRequestConfig) => {
+ let headers = config.headers || {}
+ return config;
+ })
+ // 全局 响应拦截器
+ instance.interceptors.response.use(successCB, rejectCB);
+ return instance;
+}
+
+
+// 请求成功回调
+export function successCB(response: AxiosResponse | Promise): AxiosResponse | Promise {
+ function processResponse(response: AxiosResponse) {
+ if (response.status === 200) { // 响应成功
+ if (response.data.code === 401) {
+ ElNotification.warning({
+ message: "登录状态失效, 请重新登录",
+ })
+ console.log(response,response.data.msg)
+ } else if (response.data.code === 403) {
+ setTimeout(() => {
+ console.log(response,response.data.msg)
+ }, 0)
+ }
+ return response;
+ } else {
+ return Promise.reject(response);
+ }
+ }
+
+ if (response instanceof Promise) {
+ let resp: AxiosResponse
+ return new Promise((resolve)=>{
+ response.then((r: AxiosResponse) => {
+ resp = r;
+ resolve(processResponse(resp))
+ });
+ })
+ } else {
+ return processResponse(response);
+ }
+}
+
+// 请求失败回调
+export function rejectCB(error: any): any {
+ let response = error.response
+ if(response.status === 401){
+ return response;
+ } else if(response.status === 403){
+ setTimeout(() => {
+ console.log(response.data.msg)
+ }, 0)
+ return response;
+ }
+ return Promise.reject(error);
+}
diff --git a/app/wails/frontend/src/views/tabs/home/Home.vue b/app/wails/frontend/src/views/tabs/home/Home.vue
index 8afd865..052a0f7 100644
--- a/app/wails/frontend/src/views/tabs/home/Home.vue
+++ b/app/wails/frontend/src/views/tabs/home/Home.vue
@@ -151,6 +151,7 @@ const cpuInfo = useCpuInfo()
添加tab
环境变量
+ 定位记录
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/color.ts b/app/wails/frontend/src/views/tabs/location-record/logic/color.ts
new file mode 100644
index 0000000..97da563
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/color.ts
@@ -0,0 +1,10 @@
+export const COLOR = [
+ '#6090e0', '#30c030', '#d070d0', '#80c0f0', '#f07050', '#ffb900',
+ '#37a2da', '#ffdb5c', '#8378ea', '#e7bcf3', '#32c5e9', '#67e0e3',
+ '#dd6b66', '#759aa0', '#e69d87', '#8dc1a9', '#ea7e53', '#eedd78',
+]
+
+export function randomColorList(len:number){
+ return Array.from({ length: len })
+ .map(() => COLOR[Math.floor(Math.random() * COLOR.length)]);
+}
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/icon.ts b/app/wails/frontend/src/views/tabs/location-record/logic/icon.ts
new file mode 100644
index 0000000..54c8ae3
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/icon.ts
@@ -0,0 +1,18 @@
+export function createCanvasDir(){
+ let canvasDir = document.createElement('canvas')
+ let width = 24;
+ let height = 24;
+ canvasDir.width = width;
+ canvasDir.height = height;
+
+ let context = canvasDir.getContext('2d')!;
+ context.strokeStyle = 'white';
+ context.lineJoin = 'round';
+ context.lineWidth = 8;
+ context.moveTo(-4, width - 4);
+ context.lineTo(width / 2, 6);
+ context.lineTo(width + 4, width - 4);
+ context.stroke();
+
+ return canvasDir;
+}
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/lines.ts b/app/wails/frontend/src/views/tabs/location-record/logic/lines.ts
new file mode 100644
index 0000000..f440b82
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/lines.ts
@@ -0,0 +1,72 @@
+import {randomColorList} from "src/views/tabs/location-record/logic/color";
+import {createCanvasDir} from "src/views/tabs/location-record/logic/icon";
+import {getAvgSpeed, getMaxSpeed} from "src/views/tabs/location-record/logic/speed";
+
+const canvasDir = createCanvasDir();
+const SLOW = "#ff0036"
+const NORMAL = "#ff8119"
+const FAST = "#AF5"
+export function drawLines(map,data,lines){
+ map.remove(data.polylines)
+ data.polylines = []
+ let colorList = randomColorList(lines.length)
+
+ lines.forEach((_data,index) => {
+ let max = getMaxSpeed(_data)
+ let avg = getAvgSpeed(_data)
+
+ let p:any = []
+ for (let i = 0; i < _data.length; i++) {
+ let item = _data[i]
+ let speed = item.speed || 0
+ let type
+ if(speed < avg / 2){
+ type= SLOW
+ } else if(speed >= avg/2 && speed < avg){
+ type = NORMAL
+ } else {
+ type = FAST
+ }
+
+ if(p.length === 0){
+ p.push({
+ path: [new AMap.LngLat(item.longitude, item.latitude)],
+ strokeColor: type,
+ })
+ } else {
+ if(p[p.length - 1].strokeColor === type){
+ p[p.length - 1].path.push(new AMap.LngLat(item.longitude, item.latitude))
+ } else {
+ let prevPath = p[p.length - 1].path
+ let prev = prevPath[prevPath.length - 1]
+ p.push({
+ path: [prev, new AMap.LngLat(item.longitude, item.latitude)],
+ strokeColor: type,
+ })
+ }
+ }
+ }
+ console.log("p",p)
+
+ let polylineArr:any[] = []
+ p.forEach((item)=>{
+ let polyline = new AMap.Polyline({
+ path: item.path,
+ showDir: true,
+ dirImg: canvasDir,
+ borderWeight: 6, // 线条宽度,默认为 1
+ strokeWeight: 6,
+ strokeOpacity: 0.9, // 透明度
+ strokeColor: item.strokeColor, // 线条颜色
+ dirColor: 'white',
+ lineJoin: 'round' // 折线拐点连接处样式})
+ })
+ polylineArr.push(polyline)
+ })
+ data.polylines.push(polylineArr)
+ })
+
+ data.polylines = data.polylines.flat()
+ console.log("polylines",data.polylines)
+ map.add(data.polylines)
+}
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/location.ts b/app/wails/frontend/src/views/tabs/location-record/logic/location.ts
new file mode 100644
index 0000000..4cf45f7
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/location.ts
@@ -0,0 +1,65 @@
+export function fixedLocationHandler(map,data) {
+ console.log(map,data)
+ let task:Promise[] = []
+ let startTime
+ let preFixedData = (data.data || []).map((item, index) => {
+ if (index % 500 === 0) {
+ startTime = data.data[0].time
+ }
+
+ let time = item.time
+ return {
+ x: item.longitude,
+ y: item.latitude,
+ sp: item.speed || 0,
+ ag: item.bearing || 0,
+ tm: index % 500 === 0 ? time.unix() : time.diff(startTime, 's')
+ }
+ })
+ console.log("纠偏路线 预处理数据: ", preFixedData)
+
+ let group:any[] = []
+ let len = preFixedData.length
+ for (let i = 0; i < Math.ceil(len / 500); i++) {
+ group.push(preFixedData.splice(0, 500))
+ }
+ console.log("分组: ", group)
+
+ task = group.map(item => {
+ return new Promise(resolve => {
+ AMap.plugin('AMap.GraspRoad', function () {
+ let grasp = new AMap.GraspRoad();
+ grasp.driving(item, function (error, result) {
+ if (error) {
+ resolve([])
+ }
+ if (!error) {
+ let newPath = result.data.points;//纠偏后的轨迹
+ let distance = result.data.distance;//里程
+
+ console.log("返回值 => ", "路径: ", newPath, "里程: ", distance)
+ resolve(newPath)
+ }
+ })
+ })
+ })
+ })
+
+ Promise.all(task).then(paths => {
+ let fixedData = paths.flat(1)
+ console.log("纠偏路线数据: ", fixedData)
+
+ data.fixedPolyline = new AMap.Polyline({
+ path: fixedData.map(item => {
+ return new AMap.LngLat(item.x, item.y)
+ }),
+ showDir: true,
+ strokeColor: 'orange', // 线条颜色
+ borderWeight: 6, // 线条宽度,默认为 1
+ strokeWeight: 6,
+ })
+ map.add(data.fixedPolyline)
+ })
+}
+
+
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/login.ts b/app/wails/frontend/src/views/tabs/location-record/logic/login.ts
new file mode 100644
index 0000000..7ff0415
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/login.ts
@@ -0,0 +1,54 @@
+import {auth, LoginDTO} from "src/views/tabs/location-record/api";
+import moment from "moment";
+import {ElMessage, ElNotification} from "element-plus";
+
+export function checkLoginStatus(){
+ let user = localStorage.getItem("user")
+ let lastLogin = localStorage.getItem("lastLogin")
+ let token = localStorage.getItem("token")
+
+ return !!user &&
+ !!lastLogin &&
+ !!token &&
+ moment().diff(moment(lastLogin),"h") < 24
+}
+
+export function logoutHandler(){
+ localStorage.removeItem("user")
+ localStorage.removeItem("lastLogin")
+ localStorage.removeItem("token")
+}
+
+export function loginRequest(authModel:LoginDTO, server:string){
+ logoutHandler()
+
+ return new Promise((resolve)=>{
+ auth.login(authModel,server).then((resp)=>{
+ let res = resp.data
+ console.log("login", res)
+ if(res.code !== 200){
+ ElMessage.warning({
+ message: res.data || res.msg,
+ duration: 500
+ })
+ resolve(false)
+ } else {
+ ElMessage.success({
+ message: "登录成功",
+ duration: 500
+ })
+ localStorage.setItem("user", authModel.account)
+ localStorage.setItem("lastLogin", moment().format("YYYY-MM-DD HH:mm:ss"))
+ localStorage.setItem("token",res.data.token)
+ resolve(true)
+ }
+ }).catch((e)=>{
+ console.error(e)
+ ElMessage.error({
+ message: "登录失败",
+ duration: 500,
+ })
+ resolve(false)
+ })
+ })
+}
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/markers.ts b/app/wails/frontend/src/views/tabs/location-record/logic/markers.ts
new file mode 100644
index 0000000..f13fa59
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/markers.ts
@@ -0,0 +1,91 @@
+export function getMarkers(map,data,line){
+ if(!data.tmpMarker){
+ data.tmpMarker = new AMap.Marker({
+ anchor: 'bottom-center',
+ offset: [0, -15],
+ });
+ }
+ return line.filter((_, index) => index % 1 === 0).map((item) => {
+ let text = {
+ fontSize: 10,
+ content: `时间:${item.locationTime}
速度: ${((item.speed || 0) * 3.6).toFixed(2)}km/h 方向角: ${(item.bearing || 0).toFixed(2)}°`
+ }
+
+ let marker = new AMap.LabelMarker({
+ name: item.id,
+ position: [item.longitude, item.latitude],
+ zIndex: 10,
+ icon: {
+ // 图标类型,现阶段只支持 image 类型
+ type: 'image',
+ // 图片 url
+ image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_b.png',
+ // 图片尺寸
+ size: [6, 9],
+ // 图片相对 position 的锚点,默认为 bottom-center
+ anchor: 'bottom-center'
+ },
+ // text,
+ })
+
+ function show(e) {
+ let position = e.data.data && e.data.data.position;
+
+ if (position) {
+ data.tmpMarker.setContent(
+ ``
+ + text.content +
+ '
' +
+ '
');
+ data.tmpMarker.setPosition(position);
+ map.add(data.tmpMarker);
+ }
+ }
+
+ function hide() {
+ map.remove(data.tmpMarker);
+ }
+
+ marker.on('mouseover', (e) => show(e));
+ marker.on('touchstart', (e) => show(e));
+ marker.on('mouseout', () => hide());
+ marker.on('touchend', () => hide());
+
+ return marker;
+ });
+}
+
+export function drawMarkers(map,data,options,lines){
+ if(!data.labelsLayer){
+ data.labelsLayer = new AMap.LabelsLayer({
+ zooms: [3, 20],
+ zIndex: 1000,
+ // 该层内标注是否避让
+ collision: true,
+ // 设置 allowCollision:true,可以让标注避让用户的标注
+ allowCollision: false,
+ });
+ map.add(data.labelsLayer)
+ }
+ data.labelsLayer.remove(data.markers)
+ data.markers = []
+
+ if(!options.showMarker){
+ return
+ }
+ data.markers = lines.map(line=>{
+ return getMarkers(map,data,line)
+ }).flat()
+ data.labelsLayer.add(data.markers)
+}
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/play.ts b/app/wails/frontend/src/views/tabs/location-record/logic/play.ts
new file mode 100644
index 0000000..0df2cf3
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/play.ts
@@ -0,0 +1,84 @@
+let index = 0
+
+export function playAnimation(map,data,line,animateRate,view,itemIndex){
+ console.log("playAnimation",line)
+ if(data.animateMarker){
+ map.remove(data.animateMarker)
+ }
+ data.animateMarker = new AMap.Marker({
+ map: map,
+ position: [0,0],
+ icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",
+ offset: new AMap.Pixel(-13, -26),
+ autoRotation: true
+ })
+
+ if(!data.infoWindow){
+ data.infoWindow = new AMap.InfoWindow({
+ offset: new AMap.Pixel(6, -25),
+ content: "",
+ isCustom: true
+ });
+ }
+
+ if(itemIndex !== view.animating){
+ index = 0
+ }
+
+ let path = line.slice(index).map((item) => {
+ return new AMap.LngLat(item.longitude, item.latitude)
+ })
+
+ data.animateMarker.stopMove();
+ data.animateMarker.on("movealong",()=>{})
+ let lastMovingIndex = 0
+ data.animateMarker.on("moving",(e)=>{
+ if(lastMovingIndex != e.index){
+ index++
+ }
+ lastMovingIndex = e.index
+ let lastLocation = e.passedPath[e.passedPath.length - 1];
+ data.infoWindow.setPosition(lastLocation);
+ let speed = ((line[index].speed||0) * 3.6).toFixed(2)
+ data.infoWindow.setContent(`
+
${line[index].locationTime}
+
${speed} km/h
+
`);
+ map.setCenter(e.target.getPosition(),true)
+ })
+ data.animateMarker.on("moveend",()=>{
+ if(index >= line.length-2){
+ setTimeout(()=>{
+ view.animating = -1
+ index = 0
+ data.animateMarker.stopMove()
+ map.remove(data.animateMarker)
+ data.infoWindow.close()
+ },100)
+ }
+ })
+ let polyline = new AMap.Polyline({
+ path: path,
+ })
+ data.animateMarker.moveAlong(polyline.getPath(),{
+ duration: 1000/animateRate,
+ autoRotation: true
+ });
+ data.infoWindow.open(map, data.animateMarker.getPosition())
+}
+
+export function stopAnimation(map,data,view){
+ if(!data.animateMarker){
+ return
+ }
+ pauseAnimation(data)
+ view.animating = -1
+ index = 0
+}
+
+export function pauseAnimation(data){
+ if(!data.animateMarker){
+ return
+ }
+ data.animateMarker.stopMove()
+}
diff --git a/app/wails/frontend/src/views/tabs/location-record/logic/speed.ts b/app/wails/frontend/src/views/tabs/location-record/logic/speed.ts
new file mode 100644
index 0000000..0467bdc
--- /dev/null
+++ b/app/wails/frontend/src/views/tabs/location-record/logic/speed.ts
@@ -0,0 +1,14 @@
+export function getMaxSpeed(data:any[]){
+ let sortSpeedData = JSON.parse(JSON.stringify(data)).sort((a,b)=>{return (b.speed || 0) - (a.speed||0)})
+ return ((sortSpeedData[0]||{}).speed || 0)
+}
+
+export function getAvgSpeed(data:any[]){
+ if(data.length === 0){
+ return 0
+ } else {
+ return ((data.map(item=>item.speed || 0).reduce((prev,cur)=>{
+ return prev + cur
+ },0) / data.length))
+ }
+}
diff --git a/app/wails/frontend/tsconfig.json b/app/wails/frontend/tsconfig.json
index 2726733..d3c066f 100644
--- a/app/wails/frontend/tsconfig.json
+++ b/app/wails/frontend/tsconfig.json
@@ -10,6 +10,7 @@
"resolveJsonModule": true,
"isolatedModules": false,
"esModuleInterop": true,
+ "noImplicitAny": false,
"lib": [
"ESNext",
"DOM"
@@ -24,7 +25,8 @@
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
- "src/**/*.vue"
+ "src/**/*.vue",
+ "node_modules/@amap/amap-jsapi-loader/src/global.d.ts"
],
"references": [
{
diff --git a/app/wails/frontend/yarn.lock b/app/wails/frontend/yarn.lock
index 36c5fdc..b1e87be 100644
--- a/app/wails/frontend/yarn.lock
+++ b/app/wails/frontend/yarn.lock
@@ -7,6 +7,11 @@
resolved "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
+"@amap/amap-jsapi-loader@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz#9ec4b4d5d2467eac451f6c852e35db69e9f9f0c0"
+ integrity sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==
+
"@ampproject/remapping@^2.2.0":
version "2.2.1"
resolved "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630"
@@ -728,6 +733,11 @@ async-validator@^4.2.5:
resolved "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339"
integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+ integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
+
autoprefixer@^10.4.14:
version "10.4.14"
resolved "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d"
@@ -740,6 +750,15 @@ autoprefixer@^10.4.14:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
+axios@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.npmmirror.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
+ integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
+ dependencies:
+ follow-redirects "^1.15.0"
+ form-data "^4.0.0"
+ proxy-from-env "^1.1.0"
+
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -833,6 +852,13 @@ color-name@1.1.3:
resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+combined-stream@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
+ integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
+ dependencies:
+ delayed-stream "~1.0.0"
+
commander@^4.0.0:
version "4.1.1"
resolved "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
@@ -870,6 +896,11 @@ debug@^4.1.0, debug@^4.3.4:
dependencies:
ms "2.1.2"
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+ integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
+
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
@@ -992,6 +1023,20 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
+follow-redirects@^1.15.0:
+ version "1.15.2"
+ resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
+ integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
+
+form-data@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
+ integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.8"
+ mime-types "^2.1.12"
+
fraction.js@^4.2.0:
version "4.2.0"
resolved "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950"
@@ -1196,6 +1241,18 @@ micromatch@^4.0.4, micromatch@^4.0.5:
braces "^3.0.2"
picomatch "^2.3.1"
+mime-db@1.52.0:
+ version "1.52.0"
+ resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+
+mime-types@^2.1.12:
+ version "2.1.35"
+ resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
+ dependencies:
+ mime-db "1.52.0"
+
minimatch@^3.0.4:
version "3.1.2"
resolved "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@@ -1362,6 +1419,11 @@ postcss@^8.1.10, postcss@^8.4.23, postcss@^8.4.24:
picocolors "^1.0.0"
source-map-js "^1.0.2"
+proxy-from-env@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
+ integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"