wzh 3 năm trước cách đây
mục cha
commit
7c8e57e35c
91 tập tin đã thay đổi với 5868 bổ sung2 xóa
  1. 11 2
      README.md
  2. 36 0
      cloudfunctions/api/WXBizDataCrypt.js
  3. 6 0
      cloudfunctions/api/config.json
  4. 117 0
      cloudfunctions/api/index.js
  5. 2524 0
      cloudfunctions/api/package-lock.json
  6. 17 0
      cloudfunctions/api/package.json
  7. 17 0
      miniprogram/apis/api.js
  8. 23 0
      miniprogram/apis/apiConfig.js
  9. 22 0
      miniprogram/apis/cloudApi.js
  10. 36 0
      miniprogram/app.js
  11. 62 0
      miniprogram/app.json
  12. 205 0
      miniprogram/app.wxss
  13. 56 0
      miniprogram/components/getPhoneButton/getPhoneButton.js
  14. 4 0
      miniprogram/components/getPhoneButton/getPhoneButton.json
  15. 3 0
      miniprogram/components/getPhoneButton/getPhoneButton.wxml
  16. 1 0
      miniprogram/components/getPhoneButton/getPhoneButton.wxss
  17. 158 0
      miniprogram/components/voyages/voyages.js
  18. 4 0
      miniprogram/components/voyages/voyages.json
  19. 15 0
      miniprogram/components/voyages/voyages.wxml
  20. 83 0
      miniprogram/components/voyages/voyages.wxss
  21. 6 0
      miniprogram/envList.js
  22. BIN
      miniprogram/images/bills.png
  23. BIN
      miniprogram/images/camera.png
  24. BIN
      miniprogram/images/rudder.png
  25. BIN
      miniprogram/images/ship.png
  26. BIN
      miniprogram/images/tabBar/index-c.png
  27. BIN
      miniprogram/images/tabBar/index.png
  28. BIN
      miniprogram/images/tabBar/user-c.png
  29. BIN
      miniprogram/images/tabBar/user.png
  30. BIN
      miniprogram/images/tabBar/voyage-c.png
  31. BIN
      miniprogram/images/tabBar/voyage.png
  32. 66 0
      miniprogram/pages/financialManage/financialManage.js
  33. 3 0
      miniprogram/pages/financialManage/financialManage.json
  34. 2 0
      miniprogram/pages/financialManage/financialManage.wxml
  35. 1 0
      miniprogram/pages/financialManage/financialManage.wxss
  36. 50 0
      miniprogram/pages/index/index.js
  37. 5 0
      miniprogram/pages/index/index.json
  38. 43 0
      miniprogram/pages/index/index.wxml
  39. 64 0
      miniprogram/pages/index/index.wxss
  40. 34 0
      miniprogram/pages/login/login.js
  41. 5 0
      miniprogram/pages/login/login.json
  42. 7 0
      miniprogram/pages/login/login.wxml
  43. 4 0
      miniprogram/pages/login/login.wxss
  44. 58 0
      miniprogram/pages/me/me.js
  45. 5 0
      miniprogram/pages/me/me.json
  46. 28 0
      miniprogram/pages/me/me.wxml
  47. 12 0
      miniprogram/pages/me/me.wxss
  48. 360 0
      miniprogram/pages/sharePage/sharePage.js
  49. 5 0
      miniprogram/pages/sharePage/sharePage.json
  50. 159 0
      miniprogram/pages/sharePage/sharePage.wxml
  51. 211 0
      miniprogram/pages/sharePage/sharePage.wxss
  52. 66 0
      miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.js
  53. 3 0
      miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.json
  54. 2 0
      miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.wxml
  55. 1 0
      miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.wxss
  56. 66 0
      miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.js
  57. 3 0
      miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.json
  58. 2 0
      miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.wxml
  59. 1 0
      miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.wxss
  60. 66 0
      miniprogram/pages/voyageManage/myBills/myBills.js
  61. 3 0
      miniprogram/pages/voyageManage/myBills/myBills.json
  62. 2 0
      miniprogram/pages/voyageManage/myBills/myBills.wxml
  63. 1 0
      miniprogram/pages/voyageManage/myBills/myBills.wxss
  64. 66 0
      miniprogram/pages/voyageManage/myDaily/myDaily.js
  65. 3 0
      miniprogram/pages/voyageManage/myDaily/myDaily.json
  66. 2 0
      miniprogram/pages/voyageManage/myDaily/myDaily.wxml
  67. 1 0
      miniprogram/pages/voyageManage/myDaily/myDaily.wxss
  68. 66 0
      miniprogram/pages/voyageManage/myVoyages/myVoyages.js
  69. 3 0
      miniprogram/pages/voyageManage/myVoyages/myVoyages.json
  70. 2 0
      miniprogram/pages/voyageManage/myVoyages/myVoyages.wxml
  71. 1 0
      miniprogram/pages/voyageManage/myVoyages/myVoyages.wxss
  72. 66 0
      miniprogram/pages/voyageManage/voyageManage.js
  73. 3 0
      miniprogram/pages/voyageManage/voyageManage.json
  74. 2 0
      miniprogram/pages/voyageManage/voyageManage.wxml
  75. 1 0
      miniprogram/pages/voyageManage/voyageManage.wxss
  76. 306 0
      miniprogram/pages/voyages/detail/detail.js
  77. 3 0
      miniprogram/pages/voyages/detail/detail.json
  78. 183 0
      miniprogram/pages/voyages/detail/detail.wxml
  79. 136 0
      miniprogram/pages/voyages/detail/detail.wxss
  80. 17 0
      miniprogram/pages/voyages/voyages.js
  81. 5 0
      miniprogram/pages/voyages/voyages.json
  82. 1 0
      miniprogram/pages/voyages/voyages.wxml
  83. 4 0
      miniprogram/pages/voyages/voyages.wxss
  84. 7 0
      miniprogram/sitemap.json
  85. 22 0
      miniprogram/utils/upload.js
  86. 9 0
      miniprogram/utils/utils.js
  87. 57 0
      miniprogram/utils/wxUtils.js
  88. 80 0
      project.config.json
  89. 56 0
      project.private.config.json
  90. 1 0
      uploadCloudFunction.sh
  91. 21 0
      隐私协议.txt

+ 11 - 2
README.md

@@ -1,3 +1,12 @@
-# Agency_WxApp
+# 云开发 quickstart
+
+这是云开发的快速启动指引,其中演示了如何上手使用云开发的三大基础能力:
+
+- 数据库:一个既可在小程序前端操作,也能在云函数中读写的 JSON 文档型数据库
+- 文件存储:在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理
+- 云函数:在云端运行的代码,微信私有协议天然鉴权,开发者只需编写业务逻辑代码
+
+## 参考文档
+
+- [云开发文档](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html)
 
-汇很多代理小程序

+ 36 - 0
cloudfunctions/api/WXBizDataCrypt.js

@@ -0,0 +1,36 @@
+var crypto = require('crypto')
+
+function WXBizDataCrypt(appId, sessionKey) {
+  this.appId = appId
+  this.sessionKey = sessionKey
+}
+
+WXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
+  // base64 decode
+  var sessionKey = new Buffer(this.sessionKey, 'base64')
+  encryptedData = new Buffer(encryptedData, 'base64')
+  iv = new Buffer(iv, 'base64')
+
+  try {
+    // 解密
+    var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv)
+    // 设置自动 padding 为 true,删除填充补位
+    decipher.setAutoPadding(true)
+    // var decoded = decipher.update(encryptedData, 'binary', 'utf8')
+    var decoded = decipher.update(encryptedData, '', 'utf8')
+    decoded += decipher.final('utf8')
+
+    decoded = JSON.parse(decoded)
+
+  } catch (err) {
+    throw new Error('Illegal Buffer')
+  }
+
+  if (decoded.watermark.appid !== this.appId) {
+    throw new Error('Illegal Buffer')
+  }
+
+  return decoded
+}
+
+module.exports = WXBizDataCrypt

+ 6 - 0
cloudfunctions/api/config.json

@@ -0,0 +1,6 @@
+{
+  "permissions": {
+    "openapi": [
+    ]
+  }
+}

+ 117 - 0
cloudfunctions/api/index.js

@@ -0,0 +1,117 @@
+// 云函数入口文件
+const cloud = require('wx-server-sdk')
+const TcbRouter = require("tcb-router")
+const got = require('got')
+const md5 = require("md5")
+const APPID = "wxd2dff8f427e787d7"
+const SECRET = "05ab60eabd23177668f9725b1a03c85d"
+const WXBizDataCrypt = require('./WXBizDataCrypt')
+
+cloud.init()
+
+const db = cloud.database()
+const errorLogs = db.collection("huihenduo_error_log")
+
+// 云函数入口函数
+exports.main = async (event, context) => {
+  const wxContext = cloud.getWXContext()
+  const _openid = wxContext.OPENID
+
+  const app = new TcbRouter({
+    event
+  });
+
+  console.log('Event', event)
+
+  app.use(async (ctx, next) => {
+    ctx.data = {};
+    await next();
+  });
+
+
+  app.router("getWxPhoneNumber", async (ctx, next) => {
+    let {
+      cloudID,
+      encryptedData,
+      errMsg,
+      iv,
+      session_key
+    } = event
+    console.log(event)
+
+    let pc = new WXBizDataCrypt(APPID, session_key)
+
+    let data = pc.decryptData(encryptedData, iv)
+
+    ctx.body = {
+      phone: data.phoneNumber,
+      _openid
+    }
+    await next()
+  })
+
+  app.router("getOpenId", async (ctx, next) => {
+    ctx.body = {
+      openId: _openid
+    }
+    await next()
+  })
+  app.router("sendError", async (ctx, next) => {
+    delete event.$url
+    delete event.userInfo
+    let res = await errorLogs.add({
+      data: {
+        createTime: db.serverDate(),
+        ...event,
+        _openid,
+      }
+    })
+    await next()
+  })
+
+  app.router("base", async (ctx, next) => {
+
+    await next()
+  })
+
+  app.router("code2Session", async (ctx, next) => {
+    let JSCODE = event.JSCODE
+    let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${JSCODE}&grant_type=authorization_code`
+
+    let res = await got(url)
+    let result = JSON.parse(res.body)
+    ctx.body = {
+      ...result,
+      _openid
+    }
+
+    await next()
+  })
+
+
+
+  app.router("getAccessToken", async (ctx, next) => {
+    let tokenUrl = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${APPID}&secret=${SECRET}`
+
+
+    let res = await got(tokenUrl)
+    let {
+      access_token
+    } = JSON.parse(res.body)
+    console.log(access_token)
+    ctx.data = {
+      access_token
+    }
+    await next();
+  });
+
+
+  app.router("getOpenId", async (ctx, next) => {
+    ctx.data = {
+      openId: _openid
+    }
+    await next();
+  });
+
+  return app.serve();
+}

+ 2524 - 0
cloudfunctions/api/package-lock.json

@@ -0,0 +1,2524 @@
+{
+  "name": "api",
+  "version": "1.0.0",
+  "lockfileVersion": 2,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "api",
+      "version": "1.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "got": "^11.8.2",
+        "md5": "^2.3.0",
+        "tcb-router": "^1.1.2",
+        "wx-server-sdk": "~2.5.3"
+      }
+    },
+    "node_modules/@cloudbase/database": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/database/-/database-1.2.2.tgz",
+      "integrity": "sha512-14GPoD0vdVnfdN+4rHlMmpkxAekFklt4X2gi33iCuoZUDC62p5LWS7OuTjoronnZ4QPsZPCKm+WsjE8mVD+Hmw==",
+      "dependencies": {
+        "bson": "^4.0.3",
+        "lodash.clonedeep": "4.5.0",
+        "lodash.set": "4.3.2",
+        "lodash.unset": "4.5.2"
+      }
+    },
+    "node_modules/@cloudbase/node-sdk": {
+      "version": "2.4.7",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/node-sdk/-/node-sdk-2.4.7.tgz",
+      "integrity": "sha512-gMtp+25nAJzpXTxpZzN7PTtsTdv6m7SNRszMwPpWB3pwAYyefbuOkR505iv+kYugsX6MkbgKjcCQ/F5dpNMMYw==",
+      "dependencies": {
+        "@cloudbase/database": "1.2.2",
+        "@cloudbase/signature-nodejs": "1.0.0-beta.0",
+        "@types/retry": "^0.12.0",
+        "agentkeepalive": "^4.1.3",
+        "is-regex": "^1.0.4",
+        "jsonwebtoken": "^8.5.1",
+        "lodash.merge": "^4.6.1",
+        "request": "^2.87.0",
+        "request-promise": "^4.2.5",
+        "retry": "^0.12.0",
+        "ts-node": "^8.10.2",
+        "xml2js": "^0.4.19"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
+    "node_modules/@cloudbase/signature-nodejs": {
+      "version": "1.0.0-beta.0",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/signature-nodejs/-/signature-nodejs-1.0.0-beta.0.tgz",
+      "integrity": "sha512-gpKqwsVk/D2PzvFamYNReymXSdvRSY90eZ1ARf+1wZ8oT6OpK9kr6nmevGykMxN1n17Gn92hBbWqAxU9o3+kAQ==",
+      "dependencies": {
+        "@types/clone": "^0.1.30",
+        "clone": "^2.1.2",
+        "is-stream": "^2.0.0",
+        "url": "^0.11.0"
+      }
+    },
+    "node_modules/@protobufjs/aspromise": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+    },
+    "node_modules/@protobufjs/base64": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/base64/-/base64-1.1.2.tgz",
+      "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+    },
+    "node_modules/@protobufjs/codegen": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+      "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+    },
+    "node_modules/@protobufjs/eventemitter": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+    },
+    "node_modules/@protobufjs/fetch": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.1",
+        "@protobufjs/inquire": "^1.1.0"
+      }
+    },
+    "node_modules/@protobufjs/float": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/float/-/float-1.0.2.tgz",
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+    },
+    "node_modules/@protobufjs/inquire": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+    },
+    "node_modules/@protobufjs/path": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/path/-/path-1.1.2.tgz",
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+    },
+    "node_modules/@protobufjs/pool": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/pool/-/pool-1.1.0.tgz",
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+    },
+    "node_modules/@protobufjs/utf8": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+    },
+    "node_modules/@sindresorhus/is": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-4.6.0.tgz",
+      "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@szmarczak/http-timer": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmmirror.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
+      "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
+      "dependencies": {
+        "defer-to-connect": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@types/cacheable-request": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmmirror.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
+      "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==",
+      "dependencies": {
+        "@types/http-cache-semantics": "*",
+        "@types/keyv": "*",
+        "@types/node": "*",
+        "@types/responselike": "*"
+      }
+    },
+    "node_modules/@types/clone": {
+      "version": "0.1.30",
+      "resolved": "https://registry.npmmirror.com/@types/clone/-/clone-0.1.30.tgz",
+      "integrity": "sha512-vcxBr+ybljeSiasmdke1cQ9ICxoEwaBgM1OQ/P5h4MPj/kRyLcDl5L8PrftlbyV1kBbJIs3M3x1A1+rcWd4mEA=="
+    },
+    "node_modules/@types/http-cache-semantics": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
+      "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ=="
+    },
+    "node_modules/@types/keyv": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/@types/keyv/-/keyv-3.1.3.tgz",
+      "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/long": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/@types/long/-/long-4.0.1.tgz",
+      "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
+    },
+    "node_modules/@types/node": {
+      "version": "17.0.21",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-17.0.21.tgz",
+      "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ=="
+    },
+    "node_modules/@types/responselike": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/@types/responselike/-/responselike-1.0.0.tgz",
+      "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/retry": {
+      "version": "0.12.1",
+      "resolved": "https://registry.npmmirror.com/@types/retry/-/retry-0.12.1.tgz",
+      "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g=="
+    },
+    "node_modules/agentkeepalive": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmmirror.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
+      "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
+      "dependencies": {
+        "debug": "^4.1.0",
+        "depd": "^1.1.2",
+        "humanize-ms": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 8.0.0"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "node_modules/arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
+    },
+    "node_modules/asn1": {
+      "version": "0.2.6",
+      "resolved": "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz",
+      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+      "dependencies": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmmirror.com/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmmirror.com/aws4/-/aws4-1.11.0.tgz",
+      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+    },
+    "node_modules/bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+      "dependencies": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "node_modules/bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+    },
+    "node_modules/bson": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmmirror.com/bson/-/bson-4.6.1.tgz",
+      "integrity": "sha512-I1LQ7Hz5zgwR4QquilLNZwbhPw0Apx7i7X9kGMBTsqPdml/03Q9NBtD9nt/19ahjlphktQImrnderxqpzeVDjw==",
+      "dependencies": {
+        "buffer": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
+    "node_modules/buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+    },
+    "node_modules/cacheable-lookup": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmmirror.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
+      "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
+      "engines": {
+        "node": ">=10.6.0"
+      }
+    },
+    "node_modules/cacheable-request": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmmirror.com/cacheable-request/-/cacheable-request-7.0.2.tgz",
+      "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==",
+      "dependencies": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^4.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^6.0.1",
+        "responselike": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "node_modules/caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
+    },
+    "node_modules/charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
+      "dependencies": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+    },
+    "node_modules/crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/debug": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.3.tgz",
+      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+      "dependencies": {
+        "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/decompress-response": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz",
+      "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+      "dependencies": {
+        "mimic-response": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/decompress-response/node_modules/mimic-response": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz",
+      "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/defer-to-connect": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+      "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+      "engines": {
+        "node": ">=0.3.1"
+      }
+    },
+    "node_modules/ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+      "dependencies": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "node_modules/ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "node_modules/extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+      "engines": [
+        "node >=0.6.0"
+      ]
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+    },
+    "node_modules/forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "dependencies": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "node_modules/get-stream": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-5.2.0.tgz",
+      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmmirror.com/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+      "dependencies": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "node_modules/got": {
+      "version": "11.8.3",
+      "resolved": "https://registry.npmmirror.com/got/-/got-11.8.3.tgz",
+      "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==",
+      "dependencies": {
+        "@sindresorhus/is": "^4.0.0",
+        "@szmarczak/http-timer": "^4.0.5",
+        "@types/cacheable-request": "^6.0.1",
+        "@types/responselike": "^1.0.0",
+        "cacheable-lookup": "^5.0.3",
+        "cacheable-request": "^7.0.2",
+        "decompress-response": "^6.0.0",
+        "http2-wrapper": "^1.0.0-beta.5.2",
+        "lowercase-keys": "^2.0.0",
+        "p-cancelable": "^2.0.0",
+        "responselike": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10.19.0"
+      }
+    },
+    "node_modules/har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmmirror.com/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "deprecated": "this library is no longer supported",
+      "dependencies": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "dependencies": {
+        "function-bind": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+      "dependencies": {
+        "has-symbols": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
+    },
+    "node_modules/http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.8",
+        "npm": ">=1.3.7"
+      }
+    },
+    "node_modules/http2-wrapper": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
+      "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
+      "dependencies": {
+        "quick-lru": "^5.1.1",
+        "resolve-alpn": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=10.19.0"
+      }
+    },
+    "node_modules/humanize-ms": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/humanize-ms/-/humanize-ms-1.2.1.tgz",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+      "dependencies": {
+        "ms": "^2.0.0"
+      }
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+    },
+    "node_modules/is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+    },
+    "node_modules/is-regex": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.1.4.tgz",
+      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
+    },
+    "node_modules/isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
+    },
+    "node_modules/jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
+    },
+    "node_modules/json-buffer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz",
+      "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
+    },
+    "node_modules/json-schema": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+    },
+    "node_modules/json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
+    },
+    "node_modules/jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "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.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "engines": {
+        "node": ">=4",
+        "npm": ">=1.4.28"
+      }
+    },
+    "node_modules/jsprim": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+      "dependencies": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.4.0",
+        "verror": "1.10.0"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "dependencies": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "dependencies": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/keyv": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.1.1.tgz",
+      "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==",
+      "dependencies": {
+        "json-buffer": "3.0.1"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "node_modules/lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+    },
+    "node_modules/lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+    },
+    "node_modules/lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+    },
+    "node_modules/lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+    },
+    "node_modules/lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+    },
+    "node_modules/lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "node_modules/lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+    },
+    "node_modules/lodash.merge": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
+      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+    },
+    "node_modules/lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+    },
+    "node_modules/lodash.set": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmmirror.com/lodash.set/-/lodash.set-4.3.2.tgz",
+      "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg=="
+    },
+    "node_modules/lodash.unset": {
+      "version": "4.5.2",
+      "resolved": "https://registry.npmmirror.com/lodash.unset/-/lodash.unset-4.5.2.tgz",
+      "integrity": "sha512-bwKX88k2JhCV9D1vtE8+naDKlLiGrSmf8zi/Y9ivFHwbmRfA8RxS/aVJ+sIht2XOwqoNr4xUPUkGZpc1sHFEKg=="
+    },
+    "node_modules/long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
+    "node_modules/lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
+    },
+    "node_modules/md5": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/md5/-/md5-2.3.0.tgz",
+      "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
+      "dependencies": {
+        "charenc": "0.0.2",
+        "crypt": "0.0.2",
+        "is-buffer": "~1.1.6"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "node_modules/normalize-url": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz",
+      "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmmirror.com/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/p-cancelable": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/p-cancelable/-/p-cancelable-2.1.1.tgz",
+      "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+    },
+    "node_modules/protobufjs": {
+      "version": "6.8.8",
+      "resolved": "https://registry.npmmirror.com/protobufjs/-/protobufjs-6.8.8.tgz",
+      "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "@protobufjs/aspromise": "^1.1.2",
+        "@protobufjs/base64": "^1.1.2",
+        "@protobufjs/codegen": "^2.0.4",
+        "@protobufjs/eventemitter": "^1.1.0",
+        "@protobufjs/fetch": "^1.1.0",
+        "@protobufjs/float": "^1.0.2",
+        "@protobufjs/inquire": "^1.1.0",
+        "@protobufjs/path": "^1.1.2",
+        "@protobufjs/pool": "^1.1.0",
+        "@protobufjs/utf8": "^1.1.0",
+        "@types/long": "^4.0.0",
+        "@types/node": "^10.1.0",
+        "long": "^4.0.0"
+      },
+      "bin": {
+        "pbjs": "bin/pbjs",
+        "pbts": "bin/pbts"
+      }
+    },
+    "node_modules/protobufjs/node_modules/@types/node": {
+      "version": "10.17.60",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-10.17.60.tgz",
+      "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
+    },
+    "node_modules/psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmmirror.com/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+    },
+    "node_modules/pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.5.3.tgz",
+      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==",
+      "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
+      "engines": {
+        "node": ">=0.4.x"
+      }
+    },
+    "node_modules/quick-lru": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz",
+      "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmmirror.com/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
+      "dependencies": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/request-promise": {
+      "version": "4.2.6",
+      "resolved": "https://registry.npmmirror.com/request-promise/-/request-promise-4.2.6.tgz",
+      "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==",
+      "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
+      "dependencies": {
+        "bluebird": "^3.5.0",
+        "request-promise-core": "1.1.4",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "peerDependencies": {
+        "request": "^2.34"
+      }
+    },
+    "node_modules/request-promise-core": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/request-promise-core/-/request-promise-core-1.1.4.tgz",
+      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+      "dependencies": {
+        "lodash": "^4.17.19"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      },
+      "peerDependencies": {
+        "request": "^2.34"
+      }
+    },
+    "node_modules/resolve-alpn": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+      "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
+    },
+    "node_modules/responselike": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/responselike/-/responselike-2.0.0.tgz",
+      "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
+      "dependencies": {
+        "lowercase-keys": "^2.0.0"
+      }
+    },
+    "node_modules/retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "node_modules/sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+    },
+    "node_modules/semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.21",
+      "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/sshpk": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmmirror.com/sshpk/-/sshpk-1.17.0.tgz",
+      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+      "dependencies": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      },
+      "bin": {
+        "sshpk-conv": "bin/sshpk-conv",
+        "sshpk-sign": "bin/sshpk-sign",
+        "sshpk-verify": "bin/sshpk-verify"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/tcb-admin-node": {
+      "version": "1.23.0",
+      "resolved": "https://registry.npmmirror.com/tcb-admin-node/-/tcb-admin-node-1.23.0.tgz",
+      "integrity": "sha512-SAbjTqMsSi63SId1BJ4kWdyGJzhxh9Tjvy3YXxcsoaAC2PtASn4UIYsBsiNEUfcn58QEn2tdvCvvf69WLLjjrg==",
+      "dependencies": {
+        "@cloudbase/database": "0.9.15",
+        "@cloudbase/signature-nodejs": "^1.0.0-beta.0",
+        "is-regex": "^1.0.4",
+        "jsonwebtoken": "^8.5.1",
+        "lodash.merge": "^4.6.1",
+        "request": "^2.87.0",
+        "xml2js": "^0.4.19"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
+    "node_modules/tcb-admin-node/node_modules/@cloudbase/database": {
+      "version": "0.9.15",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/database/-/database-0.9.15.tgz",
+      "integrity": "sha512-63e7iIl+van41B39Tw4ScNe9TRCt+5GHjc7q6i8NzkWBLC3U3KlbWo79YHsUHUPI79POpQ8UMlMVo7HXIAO3dg==",
+      "dependencies": {
+        "bson": "^4.0.2",
+        "lodash.clonedeep": "4.5.0",
+        "lodash.set": "4.3.2",
+        "lodash.unset": "4.5.2"
+      }
+    },
+    "node_modules/tcb-router": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/tcb-router/-/tcb-router-1.1.2.tgz",
+      "integrity": "sha512-VB+83paVdYG0LWaodh73JUy660te2oleM5gETslbCHLnhTtgXXYfAR0dlHBU5dIhhH47V1nKp43lZUo6Xm9O4g=="
+    },
+    "node_modules/tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "dependencies": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/ts-node": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-8.10.2.tgz",
+      "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
+      "dependencies": {
+        "arg": "^4.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "source-map-support": "^0.5.17",
+        "yn": "3.1.1"
+      },
+      "bin": {
+        "ts-node": "dist/bin.js",
+        "ts-node-script": "dist/bin-script.js",
+        "ts-node-transpile-only": "dist/bin-transpile.js",
+        "ts-script": "dist/bin-script-deprecated.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      },
+      "peerDependencies": {
+        "typescript": ">=2.7"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "node_modules/tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+      "dependencies": {
+        "safe-buffer": "^5.0.1"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmmirror.com/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+    },
+    "node_modules/typescript": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "peer": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmmirror.com/url/-/url-0.11.0.tgz",
+      "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==",
+      "dependencies": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      }
+    },
+    "node_modules/url/node_modules/punycode": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-1.3.2.tgz",
+      "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
+    },
+    "node_modules/uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
+      "bin": {
+        "uuid": "bin/uuid"
+      }
+    },
+    "node_modules/verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmmirror.com/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+    },
+    "node_modules/wx-server-sdk": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmmirror.com/wx-server-sdk/-/wx-server-sdk-2.5.3.tgz",
+      "integrity": "sha512-UrLSvDZGb5iUhOikZAD7FtgaOXfobfnegc5mSQZ/MGghiLMNOL73Vb3xHIUPK41N4Hax9BTqMALscGuNJS5wqA==",
+      "dependencies": {
+        "@cloudbase/node-sdk": "2.4.7",
+        "protobufjs": "6.8.8",
+        "tcb-admin-node": "latest",
+        "tslib": "^1.9.3"
+      }
+    },
+    "node_modules/xml2js": {
+      "version": "0.4.23",
+      "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.4.23.tgz",
+      "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+      "dependencies": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+      "engines": {
+        "node": ">=6"
+      }
+    }
+  },
+  "dependencies": {
+    "@cloudbase/database": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/database/-/database-1.2.2.tgz",
+      "integrity": "sha512-14GPoD0vdVnfdN+4rHlMmpkxAekFklt4X2gi33iCuoZUDC62p5LWS7OuTjoronnZ4QPsZPCKm+WsjE8mVD+Hmw==",
+      "requires": {
+        "bson": "^4.0.3",
+        "lodash.clonedeep": "4.5.0",
+        "lodash.set": "4.3.2",
+        "lodash.unset": "4.5.2"
+      }
+    },
+    "@cloudbase/node-sdk": {
+      "version": "2.4.7",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/node-sdk/-/node-sdk-2.4.7.tgz",
+      "integrity": "sha512-gMtp+25nAJzpXTxpZzN7PTtsTdv6m7SNRszMwPpWB3pwAYyefbuOkR505iv+kYugsX6MkbgKjcCQ/F5dpNMMYw==",
+      "requires": {
+        "@cloudbase/database": "1.2.2",
+        "@cloudbase/signature-nodejs": "1.0.0-beta.0",
+        "@types/retry": "^0.12.0",
+        "agentkeepalive": "^4.1.3",
+        "is-regex": "^1.0.4",
+        "jsonwebtoken": "^8.5.1",
+        "lodash.merge": "^4.6.1",
+        "request": "^2.87.0",
+        "request-promise": "^4.2.5",
+        "retry": "^0.12.0",
+        "ts-node": "^8.10.2",
+        "xml2js": "^0.4.19"
+      }
+    },
+    "@cloudbase/signature-nodejs": {
+      "version": "1.0.0-beta.0",
+      "resolved": "https://registry.npmmirror.com/@cloudbase/signature-nodejs/-/signature-nodejs-1.0.0-beta.0.tgz",
+      "integrity": "sha512-gpKqwsVk/D2PzvFamYNReymXSdvRSY90eZ1ARf+1wZ8oT6OpK9kr6nmevGykMxN1n17Gn92hBbWqAxU9o3+kAQ==",
+      "requires": {
+        "@types/clone": "^0.1.30",
+        "clone": "^2.1.2",
+        "is-stream": "^2.0.0",
+        "url": "^0.11.0"
+      }
+    },
+    "@protobufjs/aspromise": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+    },
+    "@protobufjs/base64": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/base64/-/base64-1.1.2.tgz",
+      "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+    },
+    "@protobufjs/codegen": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+      "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+    },
+    "@protobufjs/eventemitter": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+    },
+    "@protobufjs/fetch": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+      "requires": {
+        "@protobufjs/aspromise": "^1.1.1",
+        "@protobufjs/inquire": "^1.1.0"
+      }
+    },
+    "@protobufjs/float": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/float/-/float-1.0.2.tgz",
+      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+    },
+    "@protobufjs/inquire": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+    },
+    "@protobufjs/path": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/path/-/path-1.1.2.tgz",
+      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+    },
+    "@protobufjs/pool": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/pool/-/pool-1.1.0.tgz",
+      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+    },
+    "@protobufjs/utf8": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+    },
+    "@sindresorhus/is": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-4.6.0.tgz",
+      "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="
+    },
+    "@szmarczak/http-timer": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmmirror.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
+      "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
+      "requires": {
+        "defer-to-connect": "^2.0.0"
+      }
+    },
+    "@types/cacheable-request": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmmirror.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
+      "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==",
+      "requires": {
+        "@types/http-cache-semantics": "*",
+        "@types/keyv": "*",
+        "@types/node": "*",
+        "@types/responselike": "*"
+      }
+    },
+    "@types/clone": {
+      "version": "0.1.30",
+      "resolved": "https://registry.npmmirror.com/@types/clone/-/clone-0.1.30.tgz",
+      "integrity": "sha512-vcxBr+ybljeSiasmdke1cQ9ICxoEwaBgM1OQ/P5h4MPj/kRyLcDl5L8PrftlbyV1kBbJIs3M3x1A1+rcWd4mEA=="
+    },
+    "@types/http-cache-semantics": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
+      "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ=="
+    },
+    "@types/keyv": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/@types/keyv/-/keyv-3.1.3.tgz",
+      "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/long": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/@types/long/-/long-4.0.1.tgz",
+      "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
+    },
+    "@types/node": {
+      "version": "17.0.21",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-17.0.21.tgz",
+      "integrity": "sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ=="
+    },
+    "@types/responselike": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/@types/responselike/-/responselike-1.0.0.tgz",
+      "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
+      "requires": {
+        "@types/node": "*"
+      }
+    },
+    "@types/retry": {
+      "version": "0.12.1",
+      "resolved": "https://registry.npmmirror.com/@types/retry/-/retry-0.12.1.tgz",
+      "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g=="
+    },
+    "agentkeepalive": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmmirror.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz",
+      "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==",
+      "requires": {
+        "debug": "^4.1.0",
+        "depd": "^1.1.2",
+        "humanize-ms": "^1.2.1"
+      }
+    },
+    "ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "requires": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "arg": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz",
+      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
+    },
+    "asn1": {
+      "version": "0.2.6",
+      "resolved": "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz",
+      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmmirror.com/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA=="
+    },
+    "aws4": {
+      "version": "1.11.0",
+      "resolved": "https://registry.npmmirror.com/aws4/-/aws4-1.11.0.tgz",
+      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+    },
+    "base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+    },
+    "bson": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmmirror.com/bson/-/bson-4.6.1.tgz",
+      "integrity": "sha512-I1LQ7Hz5zgwR4QquilLNZwbhPw0Apx7i7X9kGMBTsqPdml/03Q9NBtD9nt/19ahjlphktQImrnderxqpzeVDjw==",
+      "requires": {
+        "buffer": "^5.6.0"
+      }
+    },
+    "buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "requires": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+    },
+    "buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+    },
+    "cacheable-lookup": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmmirror.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
+      "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="
+    },
+    "cacheable-request": {
+      "version": "7.0.2",
+      "resolved": "https://registry.npmmirror.com/cacheable-request/-/cacheable-request-7.0.2.tgz",
+      "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==",
+      "requires": {
+        "clone-response": "^1.0.2",
+        "get-stream": "^5.1.0",
+        "http-cache-semantics": "^4.0.0",
+        "keyv": "^4.0.0",
+        "lowercase-keys": "^2.0.0",
+        "normalize-url": "^6.0.1",
+        "responselike": "^2.0.0"
+      }
+    },
+    "call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
+    },
+    "charenc": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/charenc/-/charenc-0.0.2.tgz",
+      "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA=="
+    },
+    "clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
+    },
+    "clone-response": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/clone-response/-/clone-response-1.0.2.tgz",
+      "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
+      "requires": {
+        "mimic-response": "^1.0.0"
+      }
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+    },
+    "crypt": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmmirror.com/crypt/-/crypt-0.0.2.tgz",
+      "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow=="
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "debug": {
+      "version": "4.3.3",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.3.tgz",
+      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+      "requires": {
+        "ms": "2.1.2"
+      }
+    },
+    "decompress-response": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz",
+      "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+      "requires": {
+        "mimic-response": "^3.1.0"
+      },
+      "dependencies": {
+        "mimic-response": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz",
+          "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
+        }
+      }
+    },
+    "defer-to-connect": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
+      "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="
+    },
+    "diff": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz",
+      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g=="
+    },
+    "fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw=="
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "get-stream": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-5.2.0.tgz",
+      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+      "requires": {
+        "pump": "^3.0.0"
+      }
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmmirror.com/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "got": {
+      "version": "11.8.3",
+      "resolved": "https://registry.npmmirror.com/got/-/got-11.8.3.tgz",
+      "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==",
+      "requires": {
+        "@sindresorhus/is": "^4.0.0",
+        "@szmarczak/http-timer": "^4.0.5",
+        "@types/cacheable-request": "^6.0.1",
+        "@types/responselike": "^1.0.0",
+        "cacheable-lookup": "^5.0.3",
+        "cacheable-request": "^7.0.2",
+        "decompress-response": "^6.0.0",
+        "http2-wrapper": "^1.0.0-beta.5.2",
+        "lowercase-keys": "^2.0.0",
+        "p-cancelable": "^2.0.0",
+        "responselike": "^2.0.0"
+      }
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q=="
+    },
+    "har-validator": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmmirror.com/har-validator/-/har-validator-5.1.5.tgz",
+      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+      "requires": {
+        "ajv": "^6.12.3",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+    },
+    "has-tostringtag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+      "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+      "requires": {
+        "has-symbols": "^1.0.2"
+      }
+    },
+    "http-cache-semantics": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+      "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "http2-wrapper": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
+      "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
+      "requires": {
+        "quick-lru": "^5.1.1",
+        "resolve-alpn": "^1.0.0"
+      }
+    },
+    "humanize-ms": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/humanize-ms/-/humanize-ms-1.2.1.tgz",
+      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+      "requires": {
+        "ms": "^2.0.0"
+      }
+    },
+    "ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+    },
+    "is-regex": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.1.4.tgz",
+      "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+      "requires": {
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
+      }
+    },
+    "is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
+    },
+    "json-buffer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz",
+      "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
+    },
+    "json-schema": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
+    },
+    "jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "requires": {
+        "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.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      }
+    },
+    "jsprim": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.4.0",
+        "verror": "1.10.0"
+      }
+    },
+    "jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "requires": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmmirror.com/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "requires": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "keyv": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.1.1.tgz",
+      "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==",
+      "requires": {
+        "json-buffer": "3.0.1"
+      }
+    },
+    "lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+    },
+    "lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="
+    },
+    "lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="
+    },
+    "lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="
+    },
+    "lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="
+    },
+    "lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+    },
+    "lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="
+    },
+    "lodash.merge": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
+      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+    },
+    "lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
+    },
+    "lodash.set": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmmirror.com/lodash.set/-/lodash.set-4.3.2.tgz",
+      "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg=="
+    },
+    "lodash.unset": {
+      "version": "4.5.2",
+      "resolved": "https://registry.npmmirror.com/lodash.unset/-/lodash.unset-4.5.2.tgz",
+      "integrity": "sha512-bwKX88k2JhCV9D1vtE8+naDKlLiGrSmf8zi/Y9ivFHwbmRfA8RxS/aVJ+sIht2XOwqoNr4xUPUkGZpc1sHFEKg=="
+    },
+    "long": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/long/-/long-4.0.0.tgz",
+      "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
+    },
+    "lowercase-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+      "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
+    },
+    "make-error": {
+      "version": "1.3.6",
+      "resolved": "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz",
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
+    },
+    "md5": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/md5/-/md5-2.3.0.tgz",
+      "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
+      "requires": {
+        "charenc": "0.0.2",
+        "crypt": "0.0.2",
+        "is-buffer": "~1.1.6"
+      }
+    },
+    "mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+    },
+    "mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "requires": {
+        "mime-db": "1.52.0"
+      }
+    },
+    "mimic-response": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-1.0.1.tgz",
+      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
+    },
+    "ms": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+    },
+    "normalize-url": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz",
+      "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
+    },
+    "oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmmirror.com/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "p-cancelable": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/p-cancelable/-/p-cancelable-2.1.1.tgz",
+      "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+    },
+    "protobufjs": {
+      "version": "6.8.8",
+      "resolved": "https://registry.npmmirror.com/protobufjs/-/protobufjs-6.8.8.tgz",
+      "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
+      "requires": {
+        "@protobufjs/aspromise": "^1.1.2",
+        "@protobufjs/base64": "^1.1.2",
+        "@protobufjs/codegen": "^2.0.4",
+        "@protobufjs/eventemitter": "^1.1.0",
+        "@protobufjs/fetch": "^1.1.0",
+        "@protobufjs/float": "^1.0.2",
+        "@protobufjs/inquire": "^1.1.0",
+        "@protobufjs/path": "^1.1.2",
+        "@protobufjs/pool": "^1.1.0",
+        "@protobufjs/utf8": "^1.1.0",
+        "@types/long": "^4.0.0",
+        "@types/node": "^10.1.0",
+        "long": "^4.0.0"
+      },
+      "dependencies": {
+        "@types/node": {
+          "version": "10.17.60",
+          "resolved": "https://registry.npmmirror.com/@types/node/-/node-10.17.60.tgz",
+          "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
+        }
+      }
+    },
+    "psl": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmmirror.com/psl/-/psl-1.8.0.tgz",
+      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+    },
+    "qs": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.5.3.tgz",
+      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA=="
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g=="
+    },
+    "quick-lru": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz",
+      "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="
+    },
+    "request": {
+      "version": "2.88.2",
+      "resolved": "https://registry.npmmirror.com/request/-/request-2.88.2.tgz",
+      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+      "requires": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.3",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.5.0",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "request-promise": {
+      "version": "4.2.6",
+      "resolved": "https://registry.npmmirror.com/request-promise/-/request-promise-4.2.6.tgz",
+      "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==",
+      "requires": {
+        "bluebird": "^3.5.0",
+        "request-promise-core": "1.1.4",
+        "stealthy-require": "^1.1.1",
+        "tough-cookie": "^2.3.3"
+      }
+    },
+    "request-promise-core": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/request-promise-core/-/request-promise-core-1.1.4.tgz",
+      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+      "requires": {
+        "lodash": "^4.17.19"
+      }
+    },
+    "resolve-alpn": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
+      "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
+    },
+    "responselike": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/responselike/-/responselike-2.0.0.tgz",
+      "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
+      "requires": {
+        "lowercase-keys": "^2.0.0"
+      }
+    },
+    "retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="
+    },
+    "safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+    },
+    "semver": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz",
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+    },
+    "source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+    },
+    "source-map-support": {
+      "version": "0.5.21",
+      "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "sshpk": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmmirror.com/sshpk/-/sshpk-1.17.0.tgz",
+      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+      "requires": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      }
+    },
+    "stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g=="
+    },
+    "tcb-admin-node": {
+      "version": "1.23.0",
+      "resolved": "https://registry.npmmirror.com/tcb-admin-node/-/tcb-admin-node-1.23.0.tgz",
+      "integrity": "sha512-SAbjTqMsSi63SId1BJ4kWdyGJzhxh9Tjvy3YXxcsoaAC2PtASn4UIYsBsiNEUfcn58QEn2tdvCvvf69WLLjjrg==",
+      "requires": {
+        "@cloudbase/database": "0.9.15",
+        "@cloudbase/signature-nodejs": "^1.0.0-beta.0",
+        "is-regex": "^1.0.4",
+        "jsonwebtoken": "^8.5.1",
+        "lodash.merge": "^4.6.1",
+        "request": "^2.87.0",
+        "xml2js": "^0.4.19"
+      },
+      "dependencies": {
+        "@cloudbase/database": {
+          "version": "0.9.15",
+          "resolved": "https://registry.npmmirror.com/@cloudbase/database/-/database-0.9.15.tgz",
+          "integrity": "sha512-63e7iIl+van41B39Tw4ScNe9TRCt+5GHjc7q6i8NzkWBLC3U3KlbWo79YHsUHUPI79POpQ8UMlMVo7HXIAO3dg==",
+          "requires": {
+            "bson": "^4.0.2",
+            "lodash.clonedeep": "4.5.0",
+            "lodash.set": "4.3.2",
+            "lodash.unset": "4.5.2"
+          }
+        }
+      }
+    },
+    "tcb-router": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/tcb-router/-/tcb-router-1.1.2.tgz",
+      "integrity": "sha512-VB+83paVdYG0LWaodh73JUy660te2oleM5gETslbCHLnhTtgXXYfAR0dlHBU5dIhhH47V1nKp43lZUo6Xm9O4g=="
+    },
+    "tough-cookie": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-2.5.0.tgz",
+      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+      "requires": {
+        "psl": "^1.1.28",
+        "punycode": "^2.1.1"
+      }
+    },
+    "ts-node": {
+      "version": "8.10.2",
+      "resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-8.10.2.tgz",
+      "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
+      "requires": {
+        "arg": "^4.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "source-map-support": "^0.5.17",
+        "yn": "3.1.1"
+      }
+    },
+    "tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmmirror.com/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+    },
+    "typescript": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
+      "peer": true
+    },
+    "uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmmirror.com/url/-/url-0.11.0.tgz",
+      "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==",
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmmirror.com/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
+        }
+      }
+    },
+    "uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmmirror.com/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+    },
+    "wx-server-sdk": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmmirror.com/wx-server-sdk/-/wx-server-sdk-2.5.3.tgz",
+      "integrity": "sha512-UrLSvDZGb5iUhOikZAD7FtgaOXfobfnegc5mSQZ/MGghiLMNOL73Vb3xHIUPK41N4Hax9BTqMALscGuNJS5wqA==",
+      "requires": {
+        "@cloudbase/node-sdk": "2.4.7",
+        "protobufjs": "6.8.8",
+        "tcb-admin-node": "latest",
+        "tslib": "^1.9.3"
+      }
+    },
+    "xml2js": {
+      "version": "0.4.23",
+      "resolved": "https://registry.npmmirror.com/xml2js/-/xml2js-0.4.23.tgz",
+      "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+      "requires": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~11.0.0"
+      }
+    },
+    "xmlbuilder": {
+      "version": "11.0.1",
+      "resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+    },
+    "yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
+    }
+  }
+}

+ 17 - 0
cloudfunctions/api/package.json

@@ -0,0 +1,17 @@
+{
+  "name": "api",
+  "version": "1.0.0",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "wx-server-sdk": "~2.5.3",
+    "md5": "^2.3.0",
+    "got": "^11.8.2",
+    "tcb-router": "^1.1.2"
+  },
+  "description": ""
+}

+ 17 - 0
miniprogram/apis/api.js

@@ -0,0 +1,17 @@
+const {
+  api
+} = require("./apiConfig")
+
+function getApi(url, data) {
+  return api(url, data, "get")
+}
+
+function postApi(url, data) {
+  return api(url, data, "post")
+
+}
+
+module.exports = {
+  getApi,
+  postApi
+}

+ 23 - 0
miniprogram/apis/apiConfig.js

@@ -0,0 +1,23 @@
+let v = wx.getAccountInfoSync()
+let apiUrl = `${v.miniProgram.envVersion == 'release'?'https://interface.huihenduo.com.cn/hhd-pat-cargo-app/':'https://interface.huihenduo.com.cn/hhd-pat-cargo-app-dev/'}`
+
+function api(url, data, method) {
+  return new Promise((resolve, reject) => {
+    wx.request({
+      url: `${apiUrl}/${url}`,
+      method,
+      data,
+      dataType: 'json',
+      header: {
+        'content-type': 'application/json'
+      },
+      success: resolve,
+      fail: reject
+    })
+  })
+}
+
+module.exports = {
+  apiUrl,
+  api
+}

+ 22 - 0
miniprogram/apis/cloudApi.js

@@ -0,0 +1,22 @@
+module.exports = async function cloudApi($url, data) {
+  if ($url == "sendError") {
+    let res = getCurrentPages()
+    let v = wx.getAccountInfoSync()
+    data.path = res[res.length - 1].route
+    data.env = v.miniProgram.envVersion
+
+    if (data.error) {
+      data.error = data.error.toString()
+    }
+    if (v.miniProgram.version) {
+      data.appVersion = v.miniProgram.version
+    }
+  }
+  return await wx.cloud.callFunction({
+    name: "api",
+    data: {
+      $url,
+      ...data
+    }
+  })
+}

+ 36 - 0
miniprogram/app.js

@@ -0,0 +1,36 @@
+import {
+  wxSetSessionKey
+} from "./utils/wxUtils"
+App({
+  onLaunch: function () {
+    wxSetSessionKey()
+    const updateManager = wx.getUpdateManager()
+
+    updateManager.onCheckForUpdate(function (res) {
+      // 请求完新版本信息的回调
+    })
+
+    updateManager.onUpdateReady(function () {
+      wx.showModal({
+        title: '更新提示',
+        content: '新版本已经准备好,是否重启应用?',
+        success: function (res) {
+          if (res.confirm) {
+            // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
+            updateManager.applyUpdate()
+          }
+        }
+      })
+    })
+
+    updateManager.onUpdateFailed(function () {
+      // 新版本下载失败
+    })
+
+
+    wx.cloud.init({
+      traceUser: true
+    })
+    this.globalData = {}
+  },
+})

+ 62 - 0
miniprogram/app.json

@@ -0,0 +1,62 @@
+{
+  "pages": [
+    "pages/index/index",
+    "pages/voyages/voyages",
+    "pages/me/me",
+    "pages/login/login",
+    "pages/voyages/detail/detail",
+    "pages/voyageManage/voyageManage",
+    "pages/shipOwnerManage/shipOwnerList/shipOwnerList",
+    "pages/shipOwnerManage/addShipOnwer/addShipOnwer",
+    "pages/financialManage/financialManage",
+    "pages/sharePage/sharePage"
+
+  ],
+  "window": {
+    "backgroundColor": "#F6F6F6",
+    "backgroundTextStyle": "light",
+    "navigationBarBackgroundColor": "#F6F6F6",
+    "navigationBarTitleText": "汇很多",
+    "navigationBarTextStyle": "black"
+  },
+  "tabBar": {
+    "list": [{
+        "pagePath": "pages/index/index",
+        "text": "首页",
+        "iconPath": "images/tabBar/index.png",
+        "selectedIconPath": "images/tabBar/index-c.png"
+      },
+      {
+        "pagePath": "pages/voyageManage/voyageManage",
+        "text": "航次管理",
+        "iconPath": "images/tabBar/voyage.png",
+        "selectedIconPath": "images/tabBar/voyage-c.png"
+      },
+      {
+        "pagePath": "pages/shipOwnerManage/shipOwnerList/shipOwnerList",
+        "text": "船东管理",
+        "iconPath": "images/tabBar/voyage.png",
+        "selectedIconPath": "images/tabBar/voyage-c.png"
+      },
+      {
+        "pagePath": "pages/financialManage/financialManage",
+        "text": "金融管理",
+        "iconPath": "images/tabBar/voyage.png",
+        "selectedIconPath": "images/tabBar/voyage-c.png"
+      },
+      {
+        "pagePath": "pages/me/me",
+        "text": "我",
+        "iconPath": "images/tabBar/user.png",
+        "selectedIconPath": "images/tabBar/user-c.png"
+      }
+    ]
+  },
+  "permission": {
+    "scope.userLocation": {
+      "desc": "你的位置信息将用于小程序位置接口的效果展示"
+    }
+  },
+  "sitemapLocation": "sitemap.json",
+  "style": "v2"
+}

+ 205 - 0
miniprogram/app.wxss

@@ -0,0 +1,205 @@
+page {
+  width: 100%;
+  height: 100%;
+  background: #fff;
+}
+
+view,
+scroll-view,
+cover-view {
+  box-sizing: border-box
+}
+
+.tac {
+  text-align: center;
+}
+
+.df {
+  display: flex;
+}
+
+.jcsb {
+  justify-content: space-between;
+}
+
+.jcc {
+  justify-content: center;
+}
+
+.jcfe {
+  justify-content: flex-end;
+}
+
+.jcsa {
+  justify-content: space-around;
+}
+
+.aic {
+  align-items: center;
+}
+
+.m10a {
+  margin: 10rpx auto;
+}
+
+.m20a {
+  margin: 20rpx auto;
+}
+
+.m30a {
+  margin: 30rpx auto;
+}
+
+.m40a {
+  margin: 40rpx auto;
+}
+
+.m50a {
+  margin: 50rpx auto;
+}
+
+.mt10 {
+  margin-top: 10rpx;
+}
+
+.mt20 {
+  margin-top: 20rpx;
+}
+
+.mt30 {
+  margin-top: 30rpx;
+}
+
+.mt40 {
+  margin-top: 40rpx;
+}
+
+.mt50 {
+  margin-top: 50rpx;
+}
+
+.mr10 {
+  margin-right: 10rpx;
+}
+
+.mr20 {
+  margin-right: 20rpx;
+}
+
+.mr30 {
+  margin-right: 30rpx;
+}
+
+.mr40 {
+  margin-right: 40rpx;
+}
+
+.mr50 {
+  margin-right: 50rpx;
+}
+
+.mb10 {
+  margin-bottom: 10rpx;
+}
+
+.mb20 {
+  margin-bottom: 20rpx;
+}
+
+.mb30 {
+  margin-bottom: 30rpx;
+}
+
+.mb40 {
+  margin-bottom: 40rpx;
+}
+
+.mb50 {
+  margin-bottom: 50rpx;
+}
+
+.ml10 {
+  margin-left: 10rpx;
+}
+
+.ml20 {
+  margin-left: 20rpx;
+}
+
+.ml30 {
+  margin-left: 30rpx;
+}
+
+.ml40 {
+  margin-left: 40rpx;
+}
+
+.ml50 {
+  margin-left: 50rpx;
+}
+
+.p10 {
+  padding: 10rpx;
+}
+
+.p20 {
+  padding: 20rpx;
+}
+
+.p30 {
+  padding: 30rpx;
+}
+
+.p40 {
+  padding: 40rpx;
+}
+
+.p50 {
+  padding: 50rpx;
+}
+
+.pb20 {
+  padding-bottom: 20rpx;
+}
+
+.fz20 {
+  font-size: 20rpx;
+}
+
+.fz22 {
+  font-size: 22rpx;
+}
+
+.fz24 {
+  font-size: 24rpx;
+}
+
+.fz28 {
+  font-size: 28rpx;
+}
+
+.fz32 {
+  font-size: 32rpx;
+}
+
+.fz36 {
+  font-size: 36rpx;
+}
+
+.fz40 {
+  font-size: 40rpx;
+}
+
+.scrollx {
+  overflow-x: scroll;
+  white-space: nowrap;
+
+}
+
+.scrolly {
+  overflow-y: scroll;
+}
+
+.c3 {
+  color: #333;
+}

+ 56 - 0
miniprogram/components/getPhoneButton/getPhoneButton.js

@@ -0,0 +1,56 @@
+// components/getPhoneButton/getPhoneButton.js
+import {
+  wxSetSessionKey
+} from "../../utils/wxUtils"
+import {
+  postApi
+} from "../../apis/api"
+import cloudApi from "../../apis/cloudApi"
+Component({
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    style: String,
+    type: String
+  },
+  data: {
+
+  },
+  methods: {
+    async getPhoneNumber(e) {
+      try {
+        if (e.detail.errMsg == "getPhoneNumber:ok") {
+          let session_key = wx.getStorageSync('session_key')
+          let {
+            result
+          } = await cloudApi("getWxPhoneNumber", {
+            ...e.detail,
+            session_key
+          })
+          let {
+            phone,
+          } = result
+          let res = await postApi("/user/wx/login", {
+            openId: wx.getStorageSync('openId'),
+            phone
+          })
+          this.triggerEvent('loginEvent', res)
+        } else {
+          console.log(e)
+          wx.showToast({
+            title: '请授权以登录',
+            icon: "error"
+          })
+        }
+      } catch (error) {
+        console.log(error)
+        wxSetSessionKey()
+        wx.showToast({
+          icon: "none",
+          title: '请重试或联系管理员',
+        })
+      }
+    }
+  }
+})

+ 4 - 0
miniprogram/components/getPhoneButton/getPhoneButton.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 3 - 0
miniprogram/components/getPhoneButton/getPhoneButton.wxml

@@ -0,0 +1,3 @@
+<button type="{{type}}" style="{{style}}" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">
+  <slot></slot>
+</button>

+ 1 - 0
miniprogram/components/getPhoneButton/getPhoneButton.wxss

@@ -0,0 +1 @@
+/* components/getPhoneButton/getPhoneButton.wxss */

+ 158 - 0
miniprogram/components/voyages/voyages.js

@@ -0,0 +1,158 @@
+// components/voyages/Voyages.js
+import {
+  postApi
+} from "../../apis/api"
+Component({
+  properties: {
+    height: {
+      type: Number,
+      value: 620,
+    },
+    type: {
+      type: String,
+      value: ''
+    }
+  },
+  data: {
+    term: '',
+    status: 1,
+    currentPage: 1,
+    size: 20,
+    list: [],
+    total: 0,
+    loginAccountId: 0,
+    isFreshing: false
+  },
+  methods: {
+    async getVoyageList(isScroll) {
+      let loginAccountId = wx.getStorageSync('loginAccountId')
+      if (!loginAccountId) {
+        this.setData({
+          list: [{
+            shipName: '体验船舶#1',
+            loadPort: '南京',
+            dischargeProt: "小池",
+            cargo: '石油焦',
+            tons: '10000',
+          }, {
+            shipName: '体验船舶#2',
+            loadPort: '小池',
+            dischargeProt: "武汉",
+            cargo: '豆粕',
+            tons: '15000',
+          }, {
+            shipName: '体验船舶#3',
+            loadPort: '北仑港',
+            dischargeProt: "小池",
+            cargo: '煤炭',
+            tons: '25000',
+          }, {
+            shipName: '体验船舶#4',
+            loadPort: '张家港',
+            dischargeProt: "汉口",
+            cargo: '玉米',
+            tons: '15000',
+          }, {
+            shipName: '体验船舶#5',
+            loadPort: '武汉',
+            dischargeProt: "小池",
+            cargo: '大豆',
+            tons: '3000',
+          }],
+          total: 1
+        })
+        return
+      } else {
+        this.setData({
+          loginAccountId,
+          list: []
+        })
+      }
+      this.setData({
+        isFreshing: true
+      })
+      let res = await postApi('/voyage/list', {
+        loginAccountId: wx.getStorageSync('loginAccountId'),
+        term: this.data.term,
+        status: this.data.status,
+        currentPage: this.data.currentPage,
+        size: this.data.size,
+        isClient: wx.getStorageSync('isClient'),
+
+      })
+      this.setData({
+        currentPage: this.data.currentPage,
+        isFreshing: false
+      })
+      if (res.data.status == 0) {
+        if (isScroll) {
+          this.setData({
+            list: [...this.data.list, ...res.data.result],
+            total: res.data.total
+          })
+        } else {
+          this.setData({
+            list: res.data.result,
+            total: res.data.total
+          })
+        }
+
+      } else {
+        wx.showToast({
+          icon: "none",
+          title: res.data.msg,
+        })
+      }
+    },
+    changeStatus(e) {
+      let {
+        status
+      } = e.currentTarget.dataset
+      this.setData({
+        status,
+        currentPage: 1,
+        size: 20,
+        total: 0
+      })
+      this.getVoyageList()
+    },
+    goToDetail(e) {
+      let loginAccountId = wx.getStorageSync('loginAccountId')
+      if (!loginAccountId) {
+        wx.showToast({
+          icon: "none",
+          title: '为了保证数据安全,请注册或登录',
+        })
+        return
+      }
+      let rolePermission = wx.getStorageSync('rolePermission')
+
+      if (rolePermission.indexOf('VOYAGEDETAIL') == -1) {
+        wx.showToast({
+          icon: "none",
+          title: '暂无权限,请联系管理员',
+        })
+        return
+      }
+      let {
+        id
+      } = e.currentTarget.dataset
+      wx.navigateTo({
+        url: `/pages/voyages/detail/detail?id=${id}`,
+      })
+    },
+    scrollList() {
+      if (this.data.total == 0 || this.data.total <= this.data.size * this.data.currentPage) return
+      this.data.currentPage += 1
+      this.getVoyageList(true)
+    },
+    scrollDownList() {
+      this.setData({
+        total: 0,
+        currentPage: 1,
+        list: []
+      })
+      this.getVoyageList()
+    }
+  }
+})

+ 4 - 0
miniprogram/components/voyages/voyages.json

@@ -0,0 +1,4 @@
+{
+  "component": true,
+  "usingComponents": {}
+}

+ 15 - 0
miniprogram/components/voyages/voyages.wxml

@@ -0,0 +1,15 @@
+<input disabled="{{cargoOwnerId==0}}" model:value="{{term}}" class="p10 m30a search" type="text" placeholder="搜索船舶信息" />
+<view class="df aic jcsa tabs">
+  <view class="tabsview" bindtap="changeStatus" data-status="{{1}}" style="color:{{status==1?'#0d8fcc':''}};border-bottom:{{status==1?'4rpx solid #0d8fcc':''}}">运输中</view>
+  <view class="tabsview" bindtap="changeStatus" data-status="{{2}}" style="color:{{status==2?'#0d8fcc':''}};border-bottom:{{status==2?'4rpx solid #0d8fcc':''}}">卸货中</view>
+  <view class="tabsview" bindtap="changeStatus" wx:if="{{type=='voyage'}}" data-status="{{3}}" style="color:{{status==3?'#0d8fcc':''}};border-bottom:{{status==3?'4rpx solid #0d8fcc':''}}">历史航次</view>
+</view>
+<scroll-view bindrefresherrefresh="scrollDownList" refresher-triggered="{{isFreshing}}" refresher-enabled="{{true}}" scroll-y="true" style="height:calc(100vh - {{height}}rpx);background: #fff;">
+  <view class="df aic jcsb list" wx:for="{{list}}" wx:key="index" data-id="{{item.id}}" bindtap="goToDetail">
+    <view class="col-1">{{item.shipName}}</view>
+    <view class="col-2">{{item.loadPort}}-{{item.dischargePorts}}</view>
+    <view class="col-3">{{item.cargo}}</view>
+    <view class="col-4">{{item.tons}}</view>
+  </view>
+  <view bindtap="scrollList" class="bottom-text">{{total==0?'暂无数据':(total>size*currentPage?'点击或滑动加载更多...':'已加载完毕')}}</view>
+</scroll-view>

+ 83 - 0
miniprogram/components/voyages/voyages.wxss

@@ -0,0 +1,83 @@
+/* components/voyages/Voyages.wxss */
+
+.df {
+  display: flex;
+}
+
+.jcsb {
+  justify-content: space-between;
+}
+
+.jcc {
+  justify-content: center;
+}
+
+.jcfe {
+  justify-content: flex-end;
+}
+
+.jcsa {
+  justify-content: space-around;
+}
+
+.aic {
+  align-items: center;
+}
+
+.search {
+  border: 1rpx solid grey;
+  width: 80%;
+  background: #fff;
+}
+
+.tabs {
+  width: 100%;
+  height: 100rpx;
+  background: #fff;
+  box-shadow: rgb(209, 206, 206) 5rpx 5rpx 10rpx;
+  border-bottom: 2rpx solid grey;
+}
+
+.tabsview {
+  width: 160rpx;
+  height: 60rpx;
+  text-align: center;
+}
+
+.p10 {
+  padding: 10rpx 20rpx;
+}
+
+.m30a {
+  margin: 30rpx auto;
+}
+
+.list {
+  padding: 30rpx;
+  font-size: 28rpx;
+}
+
+.col-1 {
+  width: 30vw;
+}
+
+.col-2 {
+  width: 30vw;
+}
+
+
+.col-3 {
+  width: 15vw;
+}
+
+.col-4 {
+  width: 10vw;
+}
+
+.bottom-text {
+  text-align: center;
+  padding-top: 30rpx;
+  padding-bottom: 50rpx;
+  font-size: 26rpx;
+  color: #777;
+}

+ 6 - 0
miniprogram/envList.js

@@ -0,0 +1,6 @@
+const envList = [{"envId":"huihenduo-0gwuxs6d1c6824e4","alias":"huihenduo"}]
+const isMac = true
+module.exports = {
+    envList,
+    isMac
+}

BIN
miniprogram/images/bills.png


BIN
miniprogram/images/camera.png


BIN
miniprogram/images/rudder.png


BIN
miniprogram/images/ship.png


BIN
miniprogram/images/tabBar/index-c.png


BIN
miniprogram/images/tabBar/index.png


BIN
miniprogram/images/tabBar/user-c.png


BIN
miniprogram/images/tabBar/user.png


BIN
miniprogram/images/tabBar/voyage-c.png


BIN
miniprogram/images/tabBar/voyage.png


+ 66 - 0
miniprogram/pages/financialManage/financialManage.js

@@ -0,0 +1,66 @@
+// pages/financialManage/financialManage.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad(options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload() {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh() {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom() {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/financialManage/financialManage.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/financialManage/financialManage.wxml

@@ -0,0 +1,2 @@
+<!--pages/financialManage/financialManage.wxml-->
+<text>pages/financialManage/financialManage.wxml</text>

+ 1 - 0
miniprogram/pages/financialManage/financialManage.wxss

@@ -0,0 +1 @@
+/* pages/financialManage/financialManage.wxss */

+ 50 - 0
miniprogram/pages/index/index.js

@@ -0,0 +1,50 @@
+// pages/index/index.js
+import {
+  getApi,
+  postApi
+} from "../../apis/api"
+import cloudApi from "../../apis/cloudApi"
+Page({
+  data: {
+    indexInfo: {},
+  },
+  async getIndexInfo() {
+    if (wx.getStorageSync('isClient')) return
+    let res = await postApi('/voyage/index', {
+      cargoOwnerId: wx.getStorageSync('cargoOwnerId'),
+      isClient: wx.getStorageSync('isClient'),
+    })
+    this.setData({
+      indexInfo: res.data.result
+    })
+  },
+  forbidTouchMove() {
+
+  },
+  onLoad() {
+    wx.removeStorageSync('voyageDetailId')
+  },
+  onShow() {
+    if (wx.getStorageSync('isClient')) return
+    if (wx.getStorageSync('voyageDetailId')) return
+    wx.removeStorageSync('voyageDetailId')
+    let cargoOwnerId = wx.getStorageSync('cargoOwnerId')
+    if (cargoOwnerId) {
+      this.getIndexInfo()
+      this.setData({
+        cargoOwnerId
+      })
+    }
+    let rolePermission = wx.getStorageSync('rolePermission')
+
+    if (rolePermission.indexOf('VOYAGELIST') == -1) {
+      wx.showToast({
+        icon: "none",
+        title: '暂无权限,请联系管理员',
+      })
+      return
+    }
+    const child = this.selectComponent('.voyages');
+    child.getVoyageList()
+  }
+})

+ 5 - 0
miniprogram/pages/index/index.json

@@ -0,0 +1,5 @@
+{
+  "usingComponents": {
+    "Voyages": "/components/voyages/voyages"
+  }
+}

+ 43 - 0
miniprogram/pages/index/index.wxml

@@ -0,0 +1,43 @@
+<view catchtouchmove="forbidTouchMove">
+  <view>
+    <view class="block-line df aic">
+      <view style="width: 100%;">
+        <view>活跃船舶数量</view>
+        <view>{{cargoOwnerId?indexInfo.transShipCount:'*****'}}</view>
+      </view>
+    </view>
+    <view class="block-line df aic">
+      <view>
+        <view>装载吨位</view>
+        <view>{{cargoOwnerId?indexInfo.dischargeTons:'*****'}}</view>
+      </view>
+      <view>
+        <view>卸载吨位</view>
+        <view>{{cargoOwnerId?indexInfo.finshDischargeTons:'*****'}}</view>
+      </view>
+    </view>
+  </view>
+  <view class="tools">
+    <view class="df">
+      <view>
+        <image src="../../images/camera.png"></image>
+        <view>日报</view>
+      </view>
+      <view>
+        <image src="../../images/ship.png"></image>
+        <view>卸货</view>
+      </view>
+    </view>
+    <view class="df">
+      <view>
+        <image src="../../images/bills.png"></image>
+        <view>单据</view>
+      </view>
+      <view>
+        <image src="../../images/rudder.png"></image>
+        <view>创建航次</view>
+      </view>
+    </view>
+
+  </view>
+</view>

+ 64 - 0
miniprogram/pages/index/index.wxss

@@ -0,0 +1,64 @@
+.block-line>view {
+  width: 50%;
+  text-align: center;
+  color: #fff;
+  height: 240rpx;
+}
+
+.block-line:first-child>view:first-child {
+  background: #27ae60;
+}
+
+.block-line:first-child>view:last-child {
+  background: #27ae60;
+}
+
+.block-line:last-child>view:first-child {
+  background: #e67e22;
+}
+
+.block-line:last-child>view:last-child {
+  background: #2980b9;
+}
+
+.block-line>view>view:first-child {
+  margin-top: 40rpx;
+  margin-bottom: 30rpx;
+}
+
+.search {
+  border: 1rpx solid grey;
+  width: 80%;
+  background: #fff;
+}
+
+.tabs {
+  width: 100%;
+  height: 100rpx;
+  background: #fff;
+  box-shadow: rgb(209, 206, 206) 5rpx 5rpx 10rpx
+}
+
+.tabs>view {
+  width: 100rpx;
+  height: 60rpx;
+}
+
+.tools {
+  height: calc(100vh - 480rpx);
+}
+
+.tools>view {
+  height: 50%;
+}
+
+.tools>view>view {
+  width: 50%;
+  text-align: center;
+}
+
+.tools>view>view>image {
+  width: 50%;
+  height: 50%;
+  margin-top: 20%;
+}

+ 34 - 0
miniprogram/pages/login/login.js

@@ -0,0 +1,34 @@
+// pages/login/login.js
+import {
+  getApi,
+  postApi
+} from "../../apis/api"
+import cloudApi from "../../apis/cloudApi"
+Page({
+  data: {
+
+  },
+  goExp() {
+    wx.clearStorage()
+    wx.setStorageSync('cargoOwnerId', '-1')
+    wx.setStorageSync('cargoOwnerCompany', '体验公司')
+    wx.setStorageSync('loginName', '体验用户')
+    wx.setStorageSync('loginPhone', '00000000000')
+    wx.switchTab({
+      url: '/pages/index/index',
+    })
+  },
+  testLogin() {
+    wx.setStorageSync('cargoOwnerId', '31')
+    wx.setStorageSync('cargoOwnerCompany', '物产')
+    wx.setStorageSync('loginName', '严佳宇')
+    wx.setStorageSync('loginPhone', '13331872076')
+    wx.setStorageSync('loginUserId', '15')
+    wx.switchTab({
+      url: '/pages/index/index',
+    })
+  },
+  onShow() {
+    wx.hideHomeButton()
+  }
+})

+ 5 - 0
miniprogram/pages/login/login.json

@@ -0,0 +1,5 @@
+{
+  "usingComponents": {
+    "PhoneButton": "/components/getPhoneButton/getPhoneButton"
+  }
+}

+ 7 - 0
miniprogram/pages/login/login.wxml

@@ -0,0 +1,7 @@
+<image style="margin:0 auto;display:block;width: 400rpx;margin-top: 10vh;height: 140rpx;" mode="aspectFit" src="https://6875-huihenduo-2gx127w7f837b584-1255802371.tcb.qcloud.la/miniapp-static/%E6%B1%87%E5%BE%88%E5%A4%9Alogo-%E5%B7%A6%E5%8F%B3.png?sign=fcd18f89de727b0193395cd2d44a730a&t=1647417257"></image>
+<view style="margin-top: 100rpx;font-size: 50rpx;color: #333;text-align: center;">汇很多运输管家先行版
+</view>
+<view class="df jcc" style="position:absolute;bottom: 15vh;width: 100%;">
+  <PhoneButton type="primary">登录/注册</PhoneButton>
+</view>
+<!-- <button bindtap="goExp">去体验</button> -->

+ 4 - 0
miniprogram/pages/login/login.wxss

@@ -0,0 +1,4 @@
+/* pages/login/login.wxss */
+page{
+  background: #fff;
+}

+ 58 - 0
miniprogram/pages/me/me.js

@@ -0,0 +1,58 @@
+// pages/me/me.js
+import {
+  getApi,
+  postApi
+} from "../../apis/api"
+import cloudApi from "../../apis/cloudApi"
+Page({
+  data: {
+    cargoOwnerCompany: '',
+    loginName: '',
+    loginPhone: '',
+    logoSrc: '',
+  },
+  async getCargoOwnerInfo() {
+
+  },
+  loginEvent(e) {
+    let res = e.detail
+    console.log(res)
+    if (res.data.status == 0) {
+      let data = res.data.result
+      if (!data.isClient) {
+        Object.keys(data).forEach(function (key) {
+          wx.setStorageSync(key, data[key])
+        })
+        wx.switchTab({
+          url: '/pages/index/index',
+        })
+      } else {
+        wx.showToast({
+          icon: "none",
+          title: '暂无权限'
+        })
+      }
+
+
+    } else {
+      wx.showToast({
+        icon: "none",
+        title: res.data.msg
+      })
+    }
+  },
+  onShow() {
+    let cargoOwnerCompany = wx.getStorageSync('cargoOwnerCompany')
+    let loginName = wx.getStorageSync('loginName')
+    let loginPhone = wx.getStorageSync('loginPhone')
+    let logo = wx.getStorageSync('logo')
+    let cargoOwnerId = wx.getStorageSync('cargoOwnerId')
+    this.setData({
+      cargoOwnerCompany,
+      loginName,
+      loginPhone,
+      logo,
+      cargoOwnerId
+    })
+  }
+})

+ 5 - 0
miniprogram/pages/me/me.json

@@ -0,0 +1,5 @@
+{
+  "usingComponents": {
+    "PhoneButton": "/components/getPhoneButton/getPhoneButton"
+  }
+}

+ 28 - 0
miniprogram/pages/me/me.wxml

@@ -0,0 +1,28 @@
+<block wx:if="{{cargoOwnerId}}">
+  <view class=" mtv10 mbv10 tac">
+    <image style="width: 20vw;height: 20vh;" mode="aspectFit" src="{{logo}}"></image>
+  </view>
+  <view class=" mtv10  tac">
+    {{cargoOwnerCompany}}
+  </view>
+  <view class=" mtv10  tac">
+    {{loginName}}
+  </view>
+
+  <view class=" mtv10 tac">
+    {{loginPhone}}
+  </view>
+
+  <view class=" mtv10  tac">
+    欢迎使用 汇很多科技 小程序
+  </view>
+</block>
+<block wx:else>
+  <image style="margin:0 auto;display:block;width: 400rpx;margin-top: 10vh;height: 140rpx;" mode="aspectFit" src="https://6875-huihenduo-2gx127w7f837b584-1255802371.tcb.qcloud.la/miniapp-static/%E6%B1%87%E5%BE%88%E5%A4%9Alogo-%E5%B7%A6%E5%8F%B3.png?sign=fcd18f89de727b0193395cd2d44a730a&t=1647417257"></image>
+  <view style="margin-top: 100rpx;font-size: 50rpx;color: #333;text-align: center;">汇很多运输管家先行版
+  </view>
+  <view class="df jcc" style="position:absolute;bottom: 15vh;width: 100%;">
+    <PhoneButton type="primary" bindloginEvent="loginEvent">登录</PhoneButton>
+  </view>
+  <!-- <button bindtap="goExp">去体验</button> -->
+</block>

+ 12 - 0
miniprogram/pages/me/me.wxss

@@ -0,0 +1,12 @@
+/* pages/me/me.wxss */
+page {
+  background: #fff;
+}
+
+.mtv10 {
+  margin-top: 10vh;
+}
+
+.mbv10 {
+  margin-bottom: 10vh;
+}

+ 360 - 0
miniprogram/pages/sharePage/sharePage.js

@@ -0,0 +1,360 @@
+// pages/voyages/detail/detail.js
+import {
+  postApi
+} from "../../apis/api"
+Page({
+  data: {
+    isLogin: false,
+    id: '',
+    tab: 2,
+    shipDischargeCurrentPage: 1,
+    truckLoadCurrentPage: 1,
+    coordinates: [],
+    medias: [],
+    policys: [],
+    voyage: [],
+    waybills: [],
+    infoType: 'ship',
+    shipDischargeList: [],
+    truckLoadList: [],
+    shipDischargeTotal: 0,
+    truckLoadTotal: 0,
+    polyline: [{
+      points: [],
+      width: 2,
+      dottedLine: true,
+      color: "#eb2f06"
+    }],
+    markers: [],
+    points: [],
+    pageSize: 20,
+    latitude: 31.891992,
+    longitude: 120.551369,
+    currentPortId: 0
+  },
+  changeTab(e) {
+    let {
+      tab
+    } = e.currentTarget.dataset
+    this.setData({
+      tab
+    })
+  },
+
+  async getVoyageDetail() {
+    let res = await postApi("/voyage/detail", {
+      voyageId: this.data.id,
+      isClient: wx.getStorageSync('isClient'),
+      loginAccountId: wx.getStorageSync('loginAccountId'),
+    })
+
+    let {
+      coordinates,
+      medias,
+      policys,
+      voyage,
+      waybills
+    } = res.data.result
+    if (coordinates.length) {
+      let points = []
+      for (let i of coordinates) {
+        points.push({
+          latitude: i.latitude,
+          longitude: i.longitude
+        })
+      }
+      let {
+        latitude,
+        longitude
+      } = points[points.length - 1]
+      this.data.latitude = latitude
+      this.data.longitude = longitude
+      this.data.polyline[0].points = points
+      let id = 1
+      for (let i of points) {
+        this.data.markers.push({
+          id: id + 1,
+          latitude: i.latitude,
+          longitude: i.longitude,
+          iconPath: "https://6875-huihenduo-2gx127w7f837b584-1255802371.tcb.qcloud.la/miniapp-static/red-circle.png?sign=6d208881376358fb4111aa6d7f1a7846&t=1647934972",
+          height: 20,
+          width: 20
+        })
+      }
+
+      this.setData({
+        polyline: this.data.polyline,
+        markers: this.data.markers,
+        // latitude: this.data.latitude,
+        // longitude: this.data.longitude,
+        points
+      })
+
+    }
+    voyage.arrivalLoadPortTime = this.subTimeStr(voyage.arrivalLoadPortTime)
+    voyage.loadStartTime = this.subTimeStr(voyage.loadStartTime)
+    voyage.loadEndTime = this.subTimeStr(voyage.loadEndTime)
+    voyage.setSailTime = this.subTimeStr(voyage.setSailTime)
+
+    this.setData({
+      coordinates,
+      medias,
+      policys,
+      voyage,
+      waybills,
+    })
+  },
+  subTimeStr(str) {
+    if (!str || typeof str != "string") return;
+    let index = str.indexOf(" ");
+    return str.substring(0, index);
+  },
+
+  async getCarLoadRecordList(isScroll) {
+    if (this.data.truckLoadTotal != 0 && this.data.truckLoadTotal < this.data.pageSize * this.data.truckLoadCurrentPage) return
+    if (isScroll) {
+      this.data.truckLoadCurrentPage += 1
+    } else {
+      this.data.truckLoadCurrentPage = 1
+    }
+    let res = await postApi("/voyage/getCarLoadRecordList", {
+      portId: this.data.currentPortId,
+      voyageId: this.data.id,
+      size: this.data.pageSize,
+      currentPage: this.data.truckLoadCurrentPage,
+      isClient: wx.getStorageSync('isClient'),
+      loginAccountId: wx.getStorageSync('loginAccountId')
+    })
+    this.setData({
+      truckLoadCurrentPage: this.data.truckLoadCurrentPage,
+    })
+
+    if (0 == res.data.status) {
+      if (isScroll) {
+        let truckLoadList = [...this.data.truckLoadList, ...res.data.result]
+        for (let i of truckLoadList) {
+          i.weighTime = this.cutTimeString(i.weighTime)
+        }
+        this.setData({
+          truckLoadList,
+          truckLoadTotal: res.data.total
+        })
+      } else {
+        let truckLoadList = res.data.result
+
+        for (let i of truckLoadList) {
+          i.weighTime = this.cutTimeString(i.weighTime)
+        }
+        this.setData({
+          truckLoadList,
+          truckLoadTotal: res.data.total
+        })
+      }
+    } else {
+      // wx.showToast({
+      //   icon: 'none',
+      //   title: res.data.msg,
+      // })
+    }
+  },
+
+  async getDischargeList(isScroll) {
+    if (isScroll) {
+      this.data.shipDischargeCurrentPage += 1
+    } else {
+      this.data.shipDischargeCurrentPage = 1
+    }
+    let res = await postApi("/voyage/getDischargeList", {
+      portId: this.data.currentPortId,
+      voyageId: this.data.id,
+      size: this.data.pageSize,
+      currentPage: this.data.shipDischargeCurrentPage,
+      isClient: wx.getStorageSync('isClient'),
+      loginAccountId: wx.getStorageSync('loginAccountId')
+    })
+    this.setData({
+      shipDischargeCurrentPage: this.data.shipDischargeCurrentPage,
+    })
+    if (0 == res.data.status) {
+      if (isScroll) {
+        let shipDischargeList = [...this.data.shipDischargeList, ...res.data.result]
+        for (let i of shipDischargeList) {
+          i.dischargeTime = this.cutTimeString(i.dischargeTime)
+        }
+        this.setData({
+          shipDischargeList,
+          shipDischargeTotal: res.data.total
+        })
+      } else {
+        let shipDischargeList = res.data.result
+        for (let i of shipDischargeList) {
+          i.dischargeTime = this.cutTimeString(i.dischargeTime)
+        }
+        this.setData({
+          shipDischargeList,
+          shipDischargeTotal: res.data.total
+        })
+      }
+    } else {
+      // wx.showToast({
+      //   icon: "none",
+      //   title: res.data.msg,
+      // })
+    }
+
+  },
+
+  previewImage(e) {
+    let {
+      src
+    } = e.currentTarget.dataset
+    wx.previewImage({
+      current: src, // 当前显示图片的http链接
+      urls: [src] // 需要预览的图片http链接列表
+    })
+  },
+
+  changeInfoType(e) {
+    let {
+      type
+    } = e.currentTarget.dataset
+    this.setData({
+      infoType: type,
+      truckLoadCurrentPage: 1,
+      shipDischargeCurrentPage: 1,
+      shipDischargeList: [],
+      truckLoadList: [],
+      shipDischargeTotal: 0,
+      truckLoadTotal: 0,
+    })
+    if (type == "ship") {
+      this.getDischargeList()
+    } else {
+      this.getCarLoadRecordList()
+    }
+  },
+
+  cutTimeString(str) {
+    let index = str.indexOf(' ')
+    return index == -1 ? str : str.substring(0, index)
+  },
+
+  changeBottomPage() {
+    if (this.data.infoType == "ship") {
+      this.getDischargeList(true)
+    } else {
+      this.getCarLoadRecordList(true)
+    }
+  },
+
+  scrollShip() {
+    if (this.data.shipDischargeTotal == 0 || this.data.shipDischargeTotal <= this.data.pageSize * this.data.shipDischargeCurrentPage) return
+    this.getDischargeList(true)
+  },
+  scrollTruck() {
+    if (this.data.truckLoadTotal == 0 || this.data.truckLoadTotal <= this.data.pageSize * this.data.truckLoadCurrentPage) return
+    this.getCarLoadRecordList(true)
+  },
+
+
+  onShareAppMessage() {
+    let id = wx.getStorageSync('voyageDetailId')
+    return {
+      title: '真实 实时 精准',
+      path: `/pages/sharePage/sharePage?id=${id}`
+    }
+  },
+
+  async getNewDetail() {
+    let res = await postApi("/voyage/share", {
+      voyageId: this.data.id,
+      isClient: wx.getStorageSync('isClient'),
+      loginAccountId: wx.getStorageSync('loginAccountId'),
+    })
+    // for (let i of res.data.result.detailInfos) {
+    //   i.transInfos = res.data.result.detailInfos[0].transInfos
+    // }
+    this.setData({
+      currentPortId: res.data.result.detailInfos[0].portId
+    })
+    res.data.result.detailInfos.sort((a, b) => {
+      return b.sort - a.sort
+    })
+
+    this.setData({
+      ...res.data.result,
+    })
+    this.getCarLoadRecordList()
+    this.getDischargeList()
+  },
+
+  loginEvent(e) {
+    let res = e.detail
+    if (res.data.status == 0) {
+      let data = res.data.result
+      Object.keys(data).forEach(function (key) {
+        wx.setStorageSync(key, data[key])
+      })
+      this.setData({
+        isLogin: true
+      })
+      if ((wx.getStorageSync('isClient') && wx.getStorageSync('sharePermission') || !(wx.getStorageSync('isClient')))) {
+        this.getNewDetail()
+        this.getVoyageDetail()
+      } else {
+        wx.showToast({
+          icon: "none",
+          title: '暂无查看权限'
+        })
+      }
+    } else {
+      wx.showToast({
+        icon: "none",
+        title: res.data.msg
+      })
+    }
+  },
+
+
+  changePort(e) {
+    let currentPortId = e.target.dataset.id
+    this.setData({
+      currentPortId,
+      shipDischargeList: [],
+      truckLoadList: [],
+    })
+    if (this.data.infoType == "ship") {
+      this.getDischargeList()
+    } else {
+      this.getCarLoadRecordList()
+    }
+
+  },
+
+
+  onLoad(options) {
+    let {
+      id
+    } = options
+    wx.setStorageSync('voyageDetailId', id)
+    this.setData({
+      id
+    })
+    let loginAccountId = wx.getStorageSync('loginAccountId')
+    if (loginAccountId) {
+      this.setData({
+        isLogin: true
+      })
+      if ((wx.getStorageSync('isClient') && wx.getStorageSync('sharePermission') || !(wx.getStorageSync('isClient')))) {
+        this.getNewDetail()
+        this.getVoyageDetail()
+      } else {
+        wx.showToast({
+          icon: "none",
+          title: '暂无查看权限'
+        })
+      }
+    }
+
+  },
+})

+ 5 - 0
miniprogram/pages/sharePage/sharePage.json

@@ -0,0 +1,5 @@
+{
+  "usingComponents": {
+    "PhoneButton": "/components/getPhoneButton/getPhoneButton"
+  }
+}

+ 159 - 0
miniprogram/pages/sharePage/sharePage.wxml

@@ -0,0 +1,159 @@
+<block wx:if="{{isLogin}}">
+  <map enable-zoom="{{false}}" enable-scroll="{{false}}" markers="{{markers}}" include-points="{{points}}" style="width: 100%;height: 400rpx;" name="map"></map>
+  <view class="df aic jcsb p20" style="border-bottom: 1px solid #999;border-top: 1px solid #999;">
+    <view class="tabsview" bindtap="changeTab" data-tab="{{2}}" style="color:{{tab==2?'#0d8fcc':''}};border-bottom:{{tab==2?'2rpx solid #0d8fcc':''}}">航次信息</view>
+    <view class="tabsview" bindtap="changeTab" data-tab="{{3}}" style="color:{{tab==3?'#0d8fcc':''}};border-bottom:{{tab==3?'2rpx solid #0d8fcc':''}}">单据信息</view>
+    <view class="tabsview" bindtap="changeTab" data-tab="{{4}}" style="color:{{tab==4?'#0d8fcc':''}};border-bottom:{{tab==4?'2rpx solid #0d8fcc':''}}">卸货信息</view>
+    <view class="tabsview" bindtap="changeTab" data-tab="{{5}}" style="color:{{tab==5?'#0d8fcc':''}};border-bottom:{{tab==5?'2rpx solid #0d8fcc':''}}">航次照片</view>
+  </view>
+  <view class="type2" wx:if="{{tab==2}}">
+    <view class="card">
+      <view style="padding: 10rpx 0;border-bottom: 4rpx solid #ddd;">{{shipName}}</view>
+      <view>
+        <view class="df aic mt20 fz24 c3">
+          <view class="df item">
+            <view>装货港</view> <text class="mr20">:</text> {{loadPort}}
+          </view>
+          <view class="df item">
+            <view>卸货港</view> <text class="mr20">:</text> {{detailInfos[0].portName}}
+          </view>
+        </view>
+        <view class="df aic mt10 fz24 c3">
+          <view class="df item">
+            <view>货种</view> <text class="mr20">:</text> {{cargo}}
+          </view>
+          <view class="df item">
+            <view>吨位</view> <text class="mr20">:</text> {{tons}}
+          </view>
+        </view>
+      </view>
+    </view>
+    <view style="position: relative;">
+      <scroll-view class="card" scroll-y="true" style="height:calc(100vh - 760rpx);position: relative;z-index: 20;" lower-threshold="50">
+
+        <view wx:for="{{detailInfos}}" wx:for-index="index0" wx:for-item="item0" wx:if="{{item0.setSailTime}}">
+          <view class="{{['df','mb20']}}" style="position: relative;z-index: 2;">
+            <view class="{{['mr30','title-circle']}}" style="background: green;"></view>
+            <view class="text">
+              <view class="in-text df">
+                <view class="card-title" style="color:#000;width: 250rpx;margin-right: 30rpx;">卸货港 #{{item0.sort}}</view>
+                <view class="card-title" style="color: #000;">{{item0.arrivalDiscPortTime?"实际到港时间":"预计到港时间"}}</view>
+              </view>
+              <view class="in-text df">
+                <view style="width: 250rpx;margin-right: 30rpx;">{{item0.portName}}</view>
+                <view>{{item0.arrivalDiscPortTime||item0.expectedArrivalTime}}</view>
+              </view>
+            </view>
+          </view>
+          <view class="{{['df','mb20',index==transInfos.length-1?'mb40':'']}}" style="position: relative;z-index: 2;" wx:for="{{item0.transInfos}}" wx:key="index">
+            <view class="{{['mr30',index==0?'title-circle transInfos':'circle',arrivalDiscPortTime?'greyback':'']}}"></view>
+            <view class="text">
+              <view wx:if="{{index==0}}" class="card-title">运输中</view>
+              <view class="in-text df">
+                <view style="width: 250rpx;margin-right: 30rpx;">{{item.createTime}}</view>
+                <view>{{item.province}}/{{item.city}}/{{item.district}}</view>
+              </view>
+            </view>
+          </view>
+          <view class="{{['df','mb20',index==loadingInfos.length-1?'mb40':'']}}" style="position: relative;z-index: 2;" wx:for="{{loadingInfos}}" wx:key="index">
+            <view class="{{['mr30',index==0?'title-circle':'circle']}}"></view>
+            <view class="text">
+              <view wx:if="{{index==0}}" class="card-title">装货中</view>
+              <view class="in-text df">
+                <view style="width: 250rpx;margin-right: 30rpx;">{{item.createTime}}</view>
+                <view>{{item.province}}/{{item.city}}/{{item.district}}</view>
+              </view>
+            </view>
+          </view>
+
+          <view class="{{['df','mb50']}}" style="position: relative;z-index: 2;">
+            <view class="{{['mr30','title-circle']}}"></view>
+            <view class="text">
+              <view class="in-text df">
+                <view class="card-title" style="color:#000;width: 250rpx;margin-right: 30rpx;">开航</view>
+                <view class="card-title" style="color: #000;">{{item0.setSailTime}}</view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+      <view class="long-line"></view>
+    </view>
+  </view>
+  <scroll-view wx:else scroll-y="true" style="height:calc(100vh - 494rpx);padding: 30rpx 50rpx;font-size: 28rpx;color:#222" lower-threshold="50" bindscrolltolower="test">
+
+
+    <view wx:if="{{tab==3}}">
+      <view>保险单</view>
+      <view wx:for="{{policys}}" wx:key="index" style="text-align: center;">
+        <image data-src="{{item.viewUrl}}" bindtap="previewImage" src="{{item.viewUrl}}" style="width: 60%;height: 240rpx;" mode="aspectFit"></image>
+        <view wx:if="{{policys.length&&policys.length!=1}}" class="mt10 mb10" style="border-bottom: 2rpx solid #eee;"></view>
+      </view>
+      <view class="mt30 mb30" style="border-bottom: 2rpx solid #ccc;"></view>
+      <view>运单</view>
+      <view wx:for="{{waybills}}" wx:key="index" style="text-align: center;">
+        <image data-src="{{item.viewUrl}}" bindtap="previewImage" src="{{item.viewUrl}}" style="width: 60%;height: 240rpx;" mode="aspectFit"></image>
+        <view wx:if="{{waybills.length&&waybills.length!=1}}" class="mt10 mb10" style="border-bottom: 2rpx solid #eee;"></view>
+      </view>
+    </view>
+    <view wx:if="{{tab==4}}">
+      <scroll-view scroll-x="{{true}}" style="white-space: nowrap;">
+        <view class="{{['port-btns',currentPortId == item.portId?'current-port-btn':'','mr20']}}" wx:for="{{voyage.voyageDetails}}" bindtap="changePort" data-id="{{item.portId}}">{{item.portName}}</view>
+      </scroll-view>
+      <view class="df aic jcsb pb20" style="border-bottom: 2rpx solid #ddd;">
+        <view bindtap="changeInfoType" data-type="ship" style="color:{{infoType=='ship'?'#0d8fcc':''}};border-bottom:{{infoType=='ship'?'2rpx solid #0d8fcc':''}}">船舶卸货记录</view>
+        <view bindtap="changeInfoType" data-type="truck" style="color:{{infoType=='truck'?'#0d8fcc':''}};border-bottom:{{infoType=='truck'?'2rpx solid #0d8fcc':''}}">汽车装货记录</view>
+      </view>
+      <view class="ship-discharge-list" wx:if="{{infoType=='ship'}}">
+        <view class="df aic jcsb mb20 mt10 fz22">
+          <view>卸货时间</view>
+          <view>卸货吨位</view>
+          <view>卸货件数</view>
+          <view>磅单</view>
+        </view>
+        <view wx:for="{{shipDischargeList}}" wx:key="index" class="df aic jcsb mb20 fz22">
+          <view>{{item.dischargeTime}}</view>
+          <view>{{item.dischargeTons||''}}</view>
+          <view>{{item.dischargePieces||''}}</view>
+          <view wx:if="{{item.files&&item.files.length}}" bindtap="previewImage" data-src="{{item.files[0].viewUrl}}" data-files="{{item.files}}">查看</view>
+          <view wx:else>暂无</view>
+        </view>
+        <view bindtap="scrollShip" class="bottom-text">{{shipDischargeTotal==0?'暂无数据':(shipDischargeTotal>pageSize*shipDischargeCurrentPage?'点击或滑动加载更多...':'已加载完毕')}}</view>
+      </view>
+      <view class="truck-load-list" wx:if="{{infoType=='truck'}}">
+        <view class="df aic jcsb mb20 mt10 fz22">
+          <view>车号</view>
+          <view>毛重</view>
+          <view>皮重</view>
+          <view>净重</view>
+          <view>称重时间</view>
+          <view>单据</view>
+        </view>
+        <view wx:for="{{truckLoadList}}" wx:key="index" class="df aic jcsb mb20 fz22">
+          <view>{{item.carNum}}</view>
+          <view>{{item.grossWeight}}</view>
+          <view>{{item.tare}}</view>
+          <view>{{item.netWeight}}</view>
+          <view>{{item.weighTime}}</view>
+          <view wx:if="{{item.file}}" bindtap="previewImage" data-src="{{item.file.viewUrl}}">查看</view>
+          <view wx:else>暂无</view>
+        </view>
+        <view bindtap="scrollTruck" class="bottom-text">{{truckLoadTotal==0?'暂无数据':(truckLoadTotal>pageSize*truckLoadCurrentPage?'点击或滑动加载更多...':'已加载完毕')}}</view>
+      </view>
+    </view>
+    <view wx:if="{{tab==5}}">
+      <view wx:for="{{medias}}" wx:key="index" style="margin-bottom:50rpx;">
+        <view style="color: #0c81b8;padding-bottom: 10rpx;margin-bottom: 20rpx; border-bottom: 4rpx dashed rgb(197, 194, 194);">{{item.createTime}}</view>
+        <image data-src="{{item.viewUrl}}" bindtap="previewImage" src="{{item.viewUrl}}" style="width: 90%;" mode="aspectFit"></image>
+      </view>
+    </view>
+  </scroll-view>
+</block>
+<block wx:else>
+  <image style="margin:0 auto;display:block;width: 400rpx;margin-top: 10vh;height: 140rpx;" mode="aspectFit" src="https://6875-huihenduo-2gx127w7f837b584-1255802371.tcb.qcloud.la/miniapp-static/%E6%B1%87%E5%BE%88%E5%A4%9Alogo-%E5%B7%A6%E5%8F%B3.png?sign=fcd18f89de727b0193395cd2d44a730a&t=1647417257"></image>
+  <view style="margin-top: 100rpx;font-size: 50rpx;color: #333;text-align: center;">汇很多运输管家先行版
+  </view>
+  <view class="df jcc" style="position:absolute;bottom: 15vh;width: 100%;">
+    <PhoneButton type="primary" bindloginEvent="loginEvent">登录以查看分享</PhoneButton>
+  </view>
+</block>

+ 211 - 0
miniprogram/pages/sharePage/sharePage.wxss

@@ -0,0 +1,211 @@
+/* components/voyages/Voyages.wxss */
+page {
+  background: #fff;
+}
+
+.df {
+  display: flex;
+}
+
+.jcsb {
+  justify-content: space-between;
+}
+
+.jcc {
+  justify-content: center;
+}
+
+.jcfe {
+  justify-content: flex-end;
+}
+
+.jcsa {
+  justify-content: space-around;
+}
+
+.aic {
+  align-items: center;
+}
+
+.search {
+  border: 1rpx solid grey;
+  width: 80%;
+  background: #fff;
+}
+
+.tabs {
+  width: 100%;
+  height: 100rpx;
+  background: #fff;
+  box-shadow: rgb(209, 206, 206) 5rpx 5rpx 10rpx;
+  border-bottom: 2rpx solid grey;
+}
+
+.tabsview {
+  width: 130rpx;
+  height: 50rpx;
+  font-size: 28rpx;
+  text-align: center;
+  color: #333;
+}
+
+.line {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 30rpx;
+  color: #333;
+}
+
+.line-item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 45%;
+}
+
+.line-full-item {
+  width: 100%;
+  display: flex;
+  align-items: center;
+}
+
+.line-full-title {
+  width: 25%;
+}
+
+
+.line-title,
+.line-text {
+  width: 50%;
+}
+
+.line-title,
+.line-full-title {
+  color: #444;
+}
+
+.type2 .line-full-title {
+  width: 50%;
+}
+
+.ship-discharge-list>view:first-child {
+  font-size: 26rpx;
+}
+
+.ship-discharge-list>view>view {
+  width: 160rpx;
+  text-align: center;
+  color: #444;
+}
+
+.truck-load-list>view:first-child {
+  font-size: 26rpx;
+}
+
+.truck-load-list>view>view {
+  width: 160rpx;
+  text-align: center;
+  color: #444;
+}
+
+
+.bottom-text {
+  text-align: center;
+  padding-top: 30rpx;
+  padding-bottom: 50rpx;
+  font-size: 22rpx;
+  color: #777;
+}
+
+page {
+  box-sizing: border-box;
+}
+
+.item {
+  padding: 0 20rpx;
+  width: 50%;
+}
+
+.item>view {
+  width: 90rpx;
+  text-align: justify;
+  text-align-last: justify;
+  margin-right: 16rpx;
+}
+
+.card {
+  padding: 20rpx 30rpx;
+  border: 2rpx solid #ddd;
+  width: 95%;
+  margin: 20rpx auto;
+  border-radius: 20rpx;
+  box-shadow: 3rpx 1rpx 5px #ddd;
+}
+
+.circle {
+  width: 20rpx;
+  height: 20rpx;
+  border-radius: 50%;
+  background: #999;
+  position: relative;
+  left: 4rpx;
+  margin-right: 38rpx;
+  z-index: 20;
+}
+
+.greyback {
+  background: #999 !important;
+}
+
+.title-circle {
+  width: 28rpx;
+  height: 28rpx;
+  border-radius: 50%;
+  background: #999;
+  position: relative;
+  z-index: 20;
+}
+
+
+.in-text {
+  font-size: 22rpx;
+  color: #666;
+}
+
+.long-line {
+  border: 2rpx solid #ddd;
+  height: calc(100vh - 800rpx);
+  position: absolute;
+  left: 62rpx;
+  top: 24rpx;
+  z-index: 0;
+}
+
+.card-title {
+  font-size: 26rpx;
+  margin-bottom: 8rpx;
+  line-height: 30rpx;
+}
+
+.transInfos {
+  background: rgb(197, 56, 56);
+}
+
+
+.port-btns {
+  width: 180rpx !important;
+  height: 70rpx;
+  line-height: 70rpx;
+  text-align: center;
+  margin-bottom: 20rpx;
+  border-radius: 10rpx;
+  border: 1rpx solid grey;
+  display: inline-block;
+}
+
+.current-port-btn {
+  color: #fff;
+  background: #008ebd;
+  border: none;
+}

+ 66 - 0
miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.js

@@ -0,0 +1,66 @@
+// pages/shipOwnerManage/addShipOnwer/addShipOnwer.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad(options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload() {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh() {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom() {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.wxml

@@ -0,0 +1,2 @@
+<!--pages/shipOwnerManage/addShipOnwer/addShipOnwer.wxml-->
+<text>pages/shipOwnerManage/addShipOnwer/addShipOnwer.wxml</text>

+ 1 - 0
miniprogram/pages/shipOwnerManage/addShipOnwer/addShipOnwer.wxss

@@ -0,0 +1 @@
+/* pages/shipOwnerManage/addShipOnwer/addShipOnwer.wxss */

+ 66 - 0
miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.js

@@ -0,0 +1,66 @@
+// pages/shipOwnerManage/shipOwnerList/shipOwnerList.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad(options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload() {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh() {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom() {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.wxml

@@ -0,0 +1,2 @@
+<!--pages/shipOwnerManage/shipOwnerList/shipOwnerList.wxml-->
+<text>pages/shipOwnerManage/shipOwnerList/shipOwnerList.wxml</text>

+ 1 - 0
miniprogram/pages/shipOwnerManage/shipOwnerList/shipOwnerList.wxss

@@ -0,0 +1 @@
+/* pages/shipOwnerManage/shipOwnerList/shipOwnerList.wxss */

+ 66 - 0
miniprogram/pages/voyageManage/myBills/myBills.js

@@ -0,0 +1,66 @@
+// pages/voyageManage/myBills/myBills.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad(options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload() {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh() {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom() {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/voyageManage/myBills/myBills.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/voyageManage/myBills/myBills.wxml

@@ -0,0 +1,2 @@
+<!--pages/voyageManage/myBills/myBills.wxml-->
+<text>pages/voyageManage/myBills/myBills.wxml</text>

+ 1 - 0
miniprogram/pages/voyageManage/myBills/myBills.wxss

@@ -0,0 +1 @@
+/* pages/voyageManage/myBills/myBills.wxss */

+ 66 - 0
miniprogram/pages/voyageManage/myDaily/myDaily.js

@@ -0,0 +1,66 @@
+// pages/voyageManage/myDaily/myDaily.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad(options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload() {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh() {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom() {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/voyageManage/myDaily/myDaily.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/voyageManage/myDaily/myDaily.wxml

@@ -0,0 +1,2 @@
+<!--pages/voyageManage/myDaily/myDaily.wxml-->
+<text>pages/voyageManage/myDaily/myDaily.wxml</text>

+ 1 - 0
miniprogram/pages/voyageManage/myDaily/myDaily.wxss

@@ -0,0 +1 @@
+/* pages/voyageManage/myDaily/myDaily.wxss */

+ 66 - 0
miniprogram/pages/voyageManage/myVoyages/myVoyages.js

@@ -0,0 +1,66 @@
+// pages/voyageManage/myVoyages/myVoyages.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad(options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload() {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh() {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom() {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/voyageManage/myVoyages/myVoyages.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/voyageManage/myVoyages/myVoyages.wxml

@@ -0,0 +1,2 @@
+<!--pages/voyageManage/myVoyages/myVoyages.wxml-->
+<text>pages/voyageManage/myVoyages/myVoyages.wxml</text>

+ 1 - 0
miniprogram/pages/voyageManage/myVoyages/myVoyages.wxss

@@ -0,0 +1 @@
+/* pages/voyageManage/myVoyages/myVoyages.wxss */

+ 66 - 0
miniprogram/pages/voyageManage/voyageManage.js

@@ -0,0 +1,66 @@
+// pages/voyageManage/voyageManage.js
+Page({
+
+  /**
+   * 页面的初始数据
+   */
+  data: {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面加载
+   */
+  onLoad(options) {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面初次渲染完成
+   */
+  onReady() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面显示
+   */
+  onShow() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面隐藏
+   */
+  onHide() {
+
+  },
+
+  /**
+   * 生命周期函数--监听页面卸载
+   */
+  onUnload() {
+
+  },
+
+  /**
+   * 页面相关事件处理函数--监听用户下拉动作
+   */
+  onPullDownRefresh() {
+
+  },
+
+  /**
+   * 页面上拉触底事件的处理函数
+   */
+  onReachBottom() {
+
+  },
+
+  /**
+   * 用户点击右上角分享
+   */
+  onShareAppMessage() {
+
+  }
+})

+ 3 - 0
miniprogram/pages/voyageManage/voyageManage.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 2 - 0
miniprogram/pages/voyageManage/voyageManage.wxml

@@ -0,0 +1,2 @@
+<!--pages/voyageManage/voyageManage.wxml-->
+<text>pages/voyageManage/voyageManage.wxml</text>

+ 1 - 0
miniprogram/pages/voyageManage/voyageManage.wxss

@@ -0,0 +1 @@
+/* pages/voyageManage/voyageManage.wxss */

+ 306 - 0
miniprogram/pages/voyages/detail/detail.js

@@ -0,0 +1,306 @@
+// pages/voyages/detail/detail.js
+import {
+  postApi
+} from "../../../apis/api"
+Page({
+  data: {
+    id: '',
+    tab: 1,
+    shipDischargeCurrentPage: 1,
+    truckLoadCurrentPage: 1,
+    coordinates: [],
+    medias: [],
+    policys: [],
+    voyage: [],
+    waybills: [],
+    infoType: 'ship',
+    shipDischargeList: [],
+    truckLoadList: [],
+    shipDischargeTotal: 0,
+    truckLoadTotal: 0,
+    polyline: [{
+      points: [],
+      width: 2,
+      dottedLine: true,
+      color: "#eb2f06"
+    }],
+    markers: [],
+    points: [],
+    pageSize: 20,
+    latitude: 31.891992,
+    longitude: 120.551369,
+    currentPortId: 0
+  },
+  changeTab(e) {
+    let {
+      tab
+    } = e.currentTarget.dataset
+    this.setData({
+      tab
+    })
+  },
+
+  async getVoyageDetail() {
+    let res = await postApi("/voyage/detail", {
+      voyageId: this.data.id,
+      isClient: wx.getStorageSync('isClient'),
+      loginAccountId: wx.getStorageSync('loginAccountId'),
+    })
+
+    let {
+      coordinates,
+      medias,
+      policys,
+      voyage,
+      waybills
+    } = res.data.result
+    if (coordinates.length) {
+      let points = []
+      for (let i of coordinates) {
+        points.push({
+          latitude: i.latitude,
+          longitude: i.longitude
+        })
+      }
+      let {
+        latitude,
+        longitude
+      } = points[points.length - 1]
+      this.data.latitude = latitude
+      this.data.longitude = longitude
+      this.data.polyline[0].points = points
+      let id = 1
+      for (let i of points) {
+        this.data.markers.push({
+          id: id + 1,
+          latitude: i.latitude,
+          longitude: i.longitude,
+          iconPath: "https://6875-huihenduo-2gx127w7f837b584-1255802371.tcb.qcloud.la/miniapp-static/red-circle.png?sign=6d208881376358fb4111aa6d7f1a7846&t=1647934972",
+          height: 20,
+          width: 20
+        })
+      }
+
+      this.setData({
+        polyline: this.data.polyline,
+        markers: this.data.markers,
+        // latitude: this.data.latitude,
+        // longitude: this.data.lo fngitude,
+        points
+      })
+
+    }
+    voyage.arrivalLoadPortTime = this.subTimeStr(voyage.arrivalLoadPortTime)
+    voyage.loadStartTime = this.subTimeStr(voyage.loadStartTime)
+    voyage.loadEndTime = this.subTimeStr(voyage.loadEndTime)
+    voyage.setSailTime = this.subTimeStr(voyage.setSailTime)
+    voyage.expectedArrivalTime = this.subTimeStr(voyage.expectedArrivalTime)
+
+    for (let item of voyage.voyageDetails) {
+
+      item.setSailTime = this.subTimeStr(item.setSailTime)
+      item.expectedArrivalTime = this.subTimeStr(item.expectedArrivalTime)
+      item.actualArrivalTime = this.subTimeStr(item.actualArrivalTime)
+      item.dischargeStartTime = this.subTimeStr(item.dischargeStartTime)
+      item.dischargeEndTime = this.subTimeStr(item.dischargeEndTime)
+    }
+    this.setData({
+      coordinates,
+      medias,
+      policys,
+      voyage,
+      waybills,
+      currentPortId: voyage?.voyageDetails[0].portId
+    })
+    this.getCarLoadRecordList()
+    this.getDischargeList()
+  },
+  subTimeStr(str) {
+    if (!str || typeof str != "string") return;
+    let index = str.indexOf(" ");
+    return str.substring(0, index);
+  },
+
+  async getCarLoadRecordList(isScroll) {
+    if (this.data.truckLoadTotal != 0 && this.data.truckLoadTotal < this.data.pageSize * this.data.truckLoadCurrentPage) return
+    if (isScroll) {
+      this.data.truckLoadCurrentPage += 1
+    } else {
+      this.data.truckLoadCurrentPage = 1
+    }
+    let res = await postApi("/voyage/getCarLoadRecordList", {
+      portId: this.data.currentPortId,
+      voyageId: this.data.id,
+      size: this.data.pageSize,
+      currentPage: this.data.truckLoadCurrentPage,
+      isClient: wx.getStorageSync('isClient'),
+      loginAccountId: wx.getStorageSync('loginAccountId')
+    })
+    this.setData({
+      truckLoadCurrentPage: this.data.truckLoadCurrentPage,
+    })
+
+    if (0 == res.data.status) {
+      if (isScroll) {
+        let truckLoadList = [...this.data.truckLoadList, ...res.data.result]
+        for (let i of truckLoadList) {
+          i.weighTime = this.cutTimeString(i.weighTime)
+        }
+        this.setData({
+          truckLoadList,
+          truckLoadTotal: res.data.total
+        })
+      } else {
+        let truckLoadList = res.data.result
+
+        for (let i of truckLoadList) {
+          i.weighTime = this.cutTimeString(i.weighTime)
+        }
+        this.setData({
+          truckLoadList,
+          truckLoadTotal: res.data.total
+        })
+      }
+    } else {
+      // wx.showToast({
+      //   icon: 'none',
+      //   title: res.data.msg,
+      // })
+    }
+  },
+
+  async getDischargeList(isScroll) {
+    if (isScroll) {
+      this.data.shipDischargeCurrentPage += 1
+    } else {
+      this.data.shipDischargeCurrentPage = 1
+    }
+    let res = await postApi("/voyage/getDischargeList", {
+      portId: this.data.currentPortId,
+      voyageId: this.data.id,
+      size: this.data.pageSize,
+      currentPage: this.data.shipDischargeCurrentPage,
+      isClient: wx.getStorageSync('isClient'),
+      loginAccountId: wx.getStorageSync('loginAccountId')
+    })
+    this.setData({
+      shipDischargeCurrentPage: this.data.shipDischargeCurrentPage,
+    })
+    if (0 == res.data.status) {
+      if (isScroll) {
+        let shipDischargeList = [...this.data.shipDischargeList, ...res.data.result]
+        for (let i of shipDischargeList) {
+          i.dischargeTime = this.cutTimeString(i.dischargeTime)
+        }
+        this.setData({
+          shipDischargeList,
+          shipDischargeTotal: res.data.total
+        })
+      } else {
+        let shipDischargeList = res.data.result
+        for (let i of shipDischargeList) {
+          i.dischargeTime = this.cutTimeString(i.dischargeTime)
+        }
+        this.setData({
+          shipDischargeList,
+          shipDischargeTotal: res.data.total
+        })
+      }
+    } else {
+      // wx.showToast({
+      //   icon: "none",
+      //   title: res.data.msg,
+      // })
+    }
+
+  },
+
+  previewImage(e) {
+    let {
+      src
+    } = e.currentTarget.dataset
+    wx.previewImage({
+      current: src, // 当前显示图片的http链接
+      urls: [src] // 需要预览的图片http链接列表
+    })
+  },
+
+  changeInfoType(e) {
+    let {
+      type
+    } = e.currentTarget.dataset
+    this.setData({
+      infoType: type,
+      truckLoadCurrentPage: 1,
+      shipDischargeCurrentPage: 1,
+      shipDischargeList: [],
+      truckLoadList: [],
+      shipDischargeTotal: 0,
+      truckLoadTotal: 0,
+    })
+    if (type == "ship") {
+      this.getDischargeList()
+    } else {
+      this.getCarLoadRecordList()
+    }
+  },
+
+  cutTimeString(str) {
+    let index = str.indexOf(' ')
+    return index == -1 ? str : str.substring(0, index)
+  },
+
+  changeBottomPage() {
+    if (this.data.infoType == "ship") {
+      this.getDischargeList(true)
+    } else {
+      this.getCarLoadRecordList(true)
+    }
+  },
+
+  scrollShip() {
+    if (this.data.shipDischargeTotal == 0 || this.data.shipDischargeTotal <= this.data.pageSize * this.data.shipDischargeCurrentPage) return
+    this.getDischargeList(true)
+  },
+  scrollTruck() {
+    if (this.data.truckLoadTotal == 0 || this.data.truckLoadTotal <= this.data.pageSize * this.data.truckLoadCurrentPage) return
+    this.getCarLoadRecordList(true)
+  },
+
+  changePort(e) {
+    let currentPortId = e.target.dataset.id
+    this.setData({
+      currentPortId,
+      shipDischargeList: [],
+      truckLoadList: [],
+    })
+    if (this.data.infoType == "ship") {
+      this.getDischargeList()
+    } else {
+      this.getCarLoadRecordList()
+    }
+
+  },
+
+
+  onShareAppMessage() {
+    let id = wx.getStorageSync('voyageDetailId')
+    return {
+      title: '真实 实时 精准',
+      path: `/pages/sharePage/sharePage?id=${id}`
+    }
+  },
+
+
+  onLoad(options) {
+    let {
+      id
+    } = options
+    wx.setStorageSync('voyageDetailId', id)
+    this.setData({
+      id
+    })
+    this.getVoyageDetail()
+
+  },
+})

+ 3 - 0
miniprogram/pages/voyages/detail/detail.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 183 - 0
miniprogram/pages/voyages/detail/detail.wxml

@@ -0,0 +1,183 @@
+<map enable-zoom="{{false}}" enable-scroll="{{false}}" markers="{{markers}}" include-points="{{points}}" style="width: 100%;height: 400rpx;" name="map"></map>
+<view class="df aic jcsb p20" style="border-bottom: 1px solid #999;border-top: 1px solid #999;">
+  <view class="tabsview" bindtap="changeTab" data-tab="{{1}}" style="color:{{tab==1?'#0d8fcc':''}};border-bottom:{{tab==1?'2rpx solid #0d8fcc':''}}">航次信息</view>
+  <view class="tabsview" bindtap="changeTab" data-tab="{{2}}" style="color:{{tab==2?'#0d8fcc':''}};border-bottom:{{tab==2?'2rpx solid #0d8fcc':''}}">航次详情</view>
+  <view class="tabsview" bindtap="changeTab" data-tab="{{3}}" style="color:{{tab==3?'#0d8fcc':''}};border-bottom:{{tab==3?'2rpx solid #0d8fcc':''}}">单据信息</view>
+  <view class="tabsview" bindtap="changeTab" data-tab="{{4}}" style="color:{{tab==4?'#0d8fcc':''}};border-bottom:{{tab==4?'2rpx solid #0d8fcc':''}}">卸货信息</view>
+  <view class="tabsview" bindtap="changeTab" data-tab="{{5}}" style="color:{{tab==5?'#0d8fcc':''}};border-bottom:{{tab==5?'2rpx solid #0d8fcc':''}}">航次照片</view>
+</view>
+<scroll-view scroll-y="true" style="height:calc(100vh - 494rpx);padding: 30rpx 50rpx;font-size: 28rpx;color:#222" lower-threshold="50" bindscrolltolower="test">
+  <view wx:if="{{tab==1}}">
+    <view class="line">
+      <view class="line-full-item">
+        <view class="line-full-title">航次名称:</view>
+        <view class="line-full-text">{{voyage.voyageName}}</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="line-full-item">
+        <view class="line-full-title">船舶名称:</view>
+        <view class="line-text">{{voyage.shipName}}</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="line-full-item">
+        <view class="line-full-title">MMSI:</view>
+        <view class="line-text">{{voyage.shipMmsi}}</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="line-item">
+        <view class="line-title">装货港:</view>
+        <view class="line-text">{{voyage.loadPort}}</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="df">
+        <view style="width: 150rpx;"> 卸货港:</view>
+        <view>{{voyage.dischargePorts}}</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="line-item">
+        <view class="line-title">货种:</view>
+        <view class="line-text">{{voyage.cargo}}</view>
+      </view>
+      <view class="line-item">
+        <view class="line-title">吨位:</view>
+        <view class="line-text">{{voyage.tons}}</view>
+      </view>
+    </view>
+  </view>
+  <view class="type2" wx:if="{{tab==2}}">
+    <view class="line">
+      <view class="line-full-item">
+        <view class="line-full-title">到达装货港时间:</view>
+        <view class="line-full-text">{{voyage.arrivalLoadPortTime}}</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="line-full-item">
+        <view class="line-full-title">实际货量:</view>
+        <view class="line-full-text">{{voyage.actualLoadTons}}吨-{{voyage.actualLoadPieces}}件</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="line-full-item">
+        <view class="line-full-title">装货开始时间:</view>
+        <view class="line-full-text">{{voyage.loadStartTime}}</view>
+      </view>
+    </view>
+    <view class="line">
+      <view class="line-full-item">
+        <view class="line-full-title">装货结束时间:</view>
+        <view class="line-full-text">{{voyage.loadEndTime}}</view>
+      </view>
+    </view>
+    <block wx:for="{{voyage.voyageDetails}}">
+      <view class="line" style="padding: 20rpx 0 10rpx 0;border-top: 1px solid grey;">
+        {{item.portName}} # {{index+1}}
+      </view>
+      <view class="line">
+        <view class="line-full-item">
+          <view class="line-full-title">开航时间:</view>
+          <view class="line-full-text">{{item.setSailTime}}</view>
+        </view>
+      </view>
+      <view class="line">
+        <view class="line-full-item">
+          <view class="line-full-title">预计到港时间:</view>
+          <view class="line-full-text">{{item.expectedArrivalTime}}</view>
+        </view>
+      </view>
+      <view class="line">
+        <view class="line-full-item">
+          <view class="line-full-title">实际到港时间:</view>
+          <view class="line-full-text">{{item.actualArrivalTime}}</view>
+        </view>
+      </view>
+      <view class="line">
+        <view class="line-full-item">
+          <view class="line-full-title">卸货开始时间:</view>
+          <view class="line-full-text">{{item.dischargeStartTime}}</view>
+        </view>
+      </view>
+      <view class="line">
+        <view class="line-full-item">
+          <view class="line-full-title">卸货结束时间:</view>
+          <view class="line-full-text">{{item.dischargeEndTime}}</view>
+        </view>
+      </view>
+      <view class="line">
+        <view class="line-full-item">
+          <view class="line-full-title">实际卸货量:</view>
+          <view class="line-full-text">{{item.actualDischargeTons}}吨-{{item.actualDischargePieces}}件</view>
+        </view>
+      </view>
+    </block>
+  </view>
+  <view wx:if="{{tab==3}}">
+    <view>保险单</view>
+    <view wx:for="{{policys}}" wx:key="index" style="text-align: center;">
+      <image data-src="{{item.viewUrl}}" bindtap="previewImage" src="{{item.viewUrl}}" style="width: 60%;height: 240rpx;" mode="aspectFit"></image>
+      <view wx:if="{{policys.length&&policys.length!=1}}" class="mt10 mb10" style="border-bottom: 2rpx solid #eee;"></view>
+    </view>
+    <view class="mt30 mb30" style="border-bottom: 2rpx solid #ccc;"></view>
+    <view>运单</view>
+    <view wx:for="{{waybills}}" wx:key="index" style="text-align: center;">
+      <image data-src="{{item.viewUrl}}" bindtap="previewImage" src="{{item.viewUrl}}" style="width: 60%;height: 240rpx;" mode="aspectFit"></image>
+      <view wx:if="{{waybills.length&&waybills.length!=1}}" class="mt10 mb10" style="border-bottom: 2rpx solid #eee;"></view>
+    </view>
+  </view>
+  <view wx:if="{{tab==4}}">
+    <scroll-view scroll-x="{{true}}" style="white-space: nowrap;">
+      <view class="{{['port-btns',currentPortId == item.portId?'current-port-btn':'','mr20']}}" wx:for="{{voyage.voyageDetails}}" bindtap="changePort" data-id="{{item.portId}}">{{item.portName}}</view>
+    </scroll-view>
+    <view class="df aic jcsb pb20" style="border-bottom: 2rpx solid #ddd;">
+      <view bindtap="changeInfoType" data-type="ship" style="color:{{infoType=='ship'?'#0d8fcc':''}};border-bottom:{{infoType=='ship'?'2rpx solid #0d8fcc':''}}">船舶卸货记录</view>
+      <view bindtap="changeInfoType" data-type="truck" style="color:{{infoType=='truck'?'#0d8fcc':''}};border-bottom:{{infoType=='truck'?'2rpx solid #0d8fcc':''}}">汽车装货记录</view>
+    </view>
+    <view class="ship-discharge-list" wx:if="{{infoType=='ship'}}">
+      <view class="df aic jcsb mb20 mt10 fz22">
+        <view>卸货时间</view>
+        <view>卸货吨位</view>
+        <view>卸货件数</view>
+        <view>磅单</view>
+      </view>
+      <view wx:for="{{shipDischargeList}}" wx:key="index" class="df aic jcsb mb20 fz22">
+        <view>{{item.dischargeTime}}</view>
+        <view>{{item.dischargeTons||''}}</view>
+        <view>{{item.dischargePieces||''}}</view>
+        <view wx:if="{{item.files&&item.files.length}}" bindtap="previewImage" data-src="{{item.files[0].viewUrl}}" data-files="{{item.files}}">查看</view>
+        <view wx:else>暂无</view>
+      </view>
+      <view bindtap="scrollShip" class="bottom-text">{{shipDischargeTotal==0?'暂无数据':(shipDischargeTotal>pageSize*shipDischargeCurrentPage?'点击或滑动加载更多...':'已加载完毕')}}</view>
+    </view>
+    <view class="truck-load-list" wx:if="{{infoType=='truck'}}">
+      <view class="df aic jcsb mb20 mt10 fz22">
+        <view>车号</view>
+        <view>毛重</view>
+        <view>皮重</view>
+        <view>净重</view>
+        <view>称重时间</view>
+        <view>单据</view>
+      </view>
+      <view wx:for="{{truckLoadList}}" wx:key="index" class="df aic jcsb mb20 fz22">
+        <view>{{item.carNum}}</view>
+        <view>{{item.grossWeight}}</view>
+        <view>{{item.tare}}</view>
+        <view>{{item.netWeight}}</view>
+        <view>{{item.weighTime}}</view>
+        <view wx:if="{{item.file}}" bindtap="previewImage" data-src="{{item.file.viewUrl}}">查看</view>
+        <view wx:else>暂无</view>
+      </view>
+      <view bindtap="scrollTruck" class="bottom-text">{{truckLoadTotal==0?'暂无数据':(truckLoadTotal>pageSize*truckLoadCurrentPage?'点击或滑动加载更多...':'已加载完毕')}}</view>
+    </view>
+  </view>
+  <view wx:if="{{tab==5}}">
+    <view wx:for="{{medias}}" wx:key="index" style="margin-bottom:50rpx;">
+      <view style="color: #0c81b8;padding-bottom: 10rpx;margin-bottom: 20rpx; border-bottom: 4rpx dashed rgb(197, 194, 194);">{{item.createTime}}</view>
+      <image data-src="{{item.viewUrl}}" bindtap="previewImage" src="{{item.viewUrl}}" style="width: 90%;" mode="aspectFit"></image>
+    </view>
+  </view>
+</scroll-view>

+ 136 - 0
miniprogram/pages/voyages/detail/detail.wxss

@@ -0,0 +1,136 @@
+/* components/voyages/Voyages.wxss */
+page {
+  background: #fff;
+}
+
+.df {
+  display: flex;
+}
+
+.jcsb {
+  justify-content: space-between;
+}
+
+.jcc {
+  justify-content: center;
+}
+
+.jcfe {
+  justify-content: flex-end;
+}
+
+.jcsa {
+  justify-content: space-around;
+}
+
+.aic {
+  align-items: center;
+}
+
+.search {
+  border: 1rpx solid grey;
+  width: 80%;
+  background: #fff;
+}
+
+.tabs {
+  width: 100%;
+  height: 100rpx;
+  background: #fff;
+  box-shadow: rgb(209, 206, 206) 5rpx 5rpx 10rpx;
+  border-bottom: 2rpx solid grey;
+}
+
+.tabsview {
+  width: 130rpx;
+  height: 50rpx;
+  font-size: 28rpx;
+  text-align: center;
+  color: #333;
+}
+
+.line {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 30rpx;
+  color: #333;
+}
+
+.line-item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 45%;
+}
+
+.line-full-item {
+  width: 100%;
+  display: flex;
+  align-items: center;
+}
+
+.line-full-title {
+  width: 25%;
+}
+
+
+.line-title,
+.line-text {
+  width: 50%;
+}
+
+.line-title,
+.line-full-title {
+  color: #444;
+}
+
+.type2 .line-full-title {
+  width: 50%;
+}
+
+.ship-discharge-list>view:first-child {
+  font-size: 26rpx;
+}
+
+.ship-discharge-list>view>view {
+  width: 160rpx;
+  text-align: center;
+  color: #444;
+}
+
+.truck-load-list>view:first-child {
+  font-size: 26rpx;
+}
+
+.truck-load-list>view>view {
+  width: 160rpx;
+  text-align: center;
+  color: #444;
+}
+
+
+.bottom-text {
+  text-align: center;
+  padding-top: 30rpx;
+  padding-bottom: 50rpx;
+  font-size: 22rpx;
+  color: #777;
+}
+
+.port-btns {
+  width: 180rpx !important;
+  height: 70rpx;
+  line-height: 70rpx;
+  text-align: center;
+  margin-bottom: 20rpx;
+  border-radius: 10rpx;
+  border: 1rpx solid grey;
+  display: inline-block;
+}
+
+.current-port-btn {
+  color: #fff;
+  background: #008ebd;
+  border: none;
+}

+ 17 - 0
miniprogram/pages/voyages/voyages.js

@@ -0,0 +1,17 @@
+// pages/voyages/voyages.js
+Page({
+
+  data: {
+
+  },
+  onLoad() {
+    wx.removeStorageSync('voyageDetailId')
+  },
+  onShow: function (options) {
+    if (wx.getStorageSync('isClient')) return
+    if (wx.getStorageSync('voyageDetailId')) return
+    wx.removeStorageSync('voyageDetailId')
+    const child = this.selectComponent('.voyages');
+    child.getVoyageList()
+  },
+})

+ 5 - 0
miniprogram/pages/voyages/voyages.json

@@ -0,0 +1,5 @@
+{
+  "usingComponents": {
+    "Voyages": "/components/voyages/voyages"
+  }
+}

+ 1 - 0
miniprogram/pages/voyages/voyages.wxml

@@ -0,0 +1 @@
+<Voyages height="{{220}}" class="voyages" type="{{'voyage'}}"></Voyages>

+ 4 - 0
miniprogram/pages/voyages/voyages.wxss

@@ -0,0 +1,4 @@
+/* pages/voyages/voyages.wxss */
+page{
+  background: #fff;
+}

+ 7 - 0
miniprogram/sitemap.json

@@ -0,0 +1,7 @@
+{
+  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+  "rules": [{
+    "action": "allow",
+    "page": "*"
+  }]
+}

+ 22 - 0
miniprogram/utils/upload.js

@@ -0,0 +1,22 @@
+import {
+  apiUrl
+} from "../apis/apiConfig"
+
+function uploadFile(filePath, formData) {
+  return new Promise((resolve, reject) => {
+    wx.uploadFile({
+      url: `${apiUrl}/cos/upload`,
+      filePath,
+      name: 'file',
+      formData,
+      success: e => {
+        resolve(JSON.parse(e.data))
+      },
+      fail: reject
+    })
+  })
+}
+
+module.exports = {
+  uploadFile
+}

+ 9 - 0
miniprogram/utils/utils.js

@@ -0,0 +1,9 @@
+function subTimeStr(str) {
+  if (!str || typeof str != "string") return;
+  let index = str.indexOf(" ");
+  return str.substring(0, index);
+}
+
+export {
+  subTimeStr
+};

+ 57 - 0
miniprogram/utils/wxUtils.js

@@ -0,0 +1,57 @@
+import cloudApi from "../apis/cloudApi"
+
+function wxSetSessionKey() {
+  return new Promise((resolve, reject) => {
+    wx.login({
+      success: async res => {
+        let res1 = await cloudApi('code2Session', {
+          JSCODE: res.code
+        })
+        wx.setStorageSync('session_key', res1.result.session_key)
+        wx.setStorageSync('openId', res1.result._openid)
+        resolve({
+          session_key: res1.result.session_key,
+          openId: res1.result._openid
+        })
+      }
+    })
+  })
+
+}
+
+function getUserProfile() {
+  return new Promise((resolve, reject) => {
+    wx.getUserProfile({
+      desc: "'用于完善用户信息",
+      success: e => {
+        let {
+          userInfo
+        } = e
+        resolve({
+          status: 0,
+          userInfo
+        })
+      },
+      fail: e => {
+        resolve({
+          errMsg: e.errMsg,
+          status: 1
+        })
+      }
+    })
+  })
+}
+
+function getOpenId() {
+  return new Promise(async (resolve, reject) => {
+    let res1 = await cloudApi('getOpenId')
+    resolve(res1.result.openId)
+  })
+
+}
+
+module.exports = {
+  wxSetSessionKey,
+  getUserProfile,
+  getOpenId
+}

+ 80 - 0
project.config.json

@@ -0,0 +1,80 @@
+{
+  "description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "miniprogramRoot": "miniprogram/",
+  "cloudfunctionRoot": "cloudfunctions/",
+  "setting": {
+    "urlCheck": true,
+    "es6": true,
+    "enhance": true,
+    "postcss": true,
+    "preloadBackgroundData": false,
+    "minified": true,
+    "newFeature": true,
+    "coverView": true,
+    "nodeModules": false,
+    "autoAudits": false,
+    "showShadowRootInWxmlPanel": true,
+    "scopeDataCheck": false,
+    "uglifyFileName": false,
+    "checkInvalidKey": true,
+    "checkSiteMap": true,
+    "uploadWithSourceMap": true,
+    "compileHotReLoad": false,
+    "lazyloadPlaceholderEnable": false,
+    "useMultiFrameRuntime": false,
+    "useApiHook": false,
+    "useApiHostProcess": false,
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    },
+    "useIsolateContext": false,
+    "userConfirmedBundleSwitch": false,
+    "packNpmManually": false,
+    "packNpmRelationList": [],
+    "minifyWXSS": true,
+    "disableUseStrict": false,
+    "minifyWXML": true,
+    "showES6CompileOption": false,
+    "useCompilerPlugins": false,
+    "ignoreUploadUnusedFiles": true
+  },
+  "appid": "wxd2dff8f427e787d7",
+  "projectname": "汇很多代理",
+  "libVersion": "2.19.6",
+  "cloudfunctionTemplateRoot": "cloudfunctionTemplate/",
+  "condition": {
+    "search": {
+      "list": []
+    },
+    "conversation": {
+      "list": []
+    },
+    "plugin": {
+      "list": []
+    },
+    "game": {
+      "list": []
+    },
+    "miniprogram": {
+      "list": [
+        {
+          "id": -1,
+          "name": "db guide",
+          "pathName": "pages/databaseGuide/databaseGuide"
+        }
+      ]
+    }
+  },
+  "compileType": "miniprogram",
+  "packOptions": {
+    "ignore": [],
+    "include": []
+  },
+  "srcMiniprogramRoot": "miniprogram/",
+  "editorSetting": {
+    "tabIndent": "insertSpaces",
+    "tabSize": 2
+  }
+}

+ 56 - 0
project.private.config.json

@@ -0,0 +1,56 @@
+{
+  "condition": {
+    "miniprogram": {
+      "list": [
+        {
+          "name": "",
+          "pathName": "pages/me/me",
+          "query": "",
+          "launchMode": "default",
+          "scene": null
+        },
+        {
+          "name": "",
+          "pathName": "pages/login/login",
+          "query": "",
+          "launchMode": "default",
+          "scene": null
+        },
+        {
+          "name": "",
+          "pathName": "pages/voyages/detail/detail",
+          "query": "id=155",
+          "launchMode": "default",
+          "scene": null
+        },
+        {
+          "name": "",
+          "pathName": "pages/share/sharePage",
+          "query": "id=42",
+          "launchMode": "default",
+          "scene": null
+        },
+        {
+          "name": "",
+          "pathName": "pages/sharePage/sharePage",
+          "query": "id=159",
+          "launchMode": "default",
+          "scene": null
+        }
+      ]
+    }
+  },
+  "setting": {
+    "urlCheck": true,
+    "coverView": true,
+    "compileHotReLoad": false,
+    "lazyloadPlaceholderEnable": false,
+    "preloadBackgroundData": false,
+    "autoAudits": false,
+    "showShadowRootInWxmlPanel": true,
+    "useStaticServer": true,
+    "showES6CompileOption": false,
+    "checkInvalidKey": true
+  },
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html"
+}

+ 1 - 0
uploadCloudFunction.sh

@@ -0,0 +1 @@
+"/Applications/wechatwebdevtools.app/Contents/MacOS/cli" cloud functions deploy --e huihenduo-0gwuxs6d1c6824e4 --n quickstartFunctions --r --project "/Users/wangzhihui/Desktop/汇很多/weapp/JiangYunPhotos" --report_first --report

+ 21 - 0
隐私协议.txt

@@ -0,0 +1,21 @@
+本隐私政策介绍本公司的隐私数据相关政策和惯例,包括在使用汇很多小程序时上传至云端的数据将受到保护,防止以及追究某些非法手段获取本公司所保管的关于您的数据资料。请你仔细阅读我们的隐私政策。
+一、本公司如何收集您的个人信息
+汇很多小程序以个人电话号码作为唯一身份识别方式,用于个人登录使用以及密码遗忘、找回的唯一途径。
+当您使用本公司的微信小程序,注册过程中我们将仅收集您的电话号码作为唯一身份识别,使用期间终身有效。
+二、本公司如何使用您的个人信息
+1、通过您的手机号码实现密码找回功能。
+2、本公司不会向任何无关第三方提供、出售、出租、分享或交易您的个人信息,除非事先得到您的许可,或该第三方和本公司单独或共同为您提供服务,且在该服务结束后,其将被禁止访问包括其以前能够访问的所有这些信息。
+三、个人信息安全
+保证您的数据的安全对我们来说至关重要。当您在本公司的微信小程序中注册输入个人信息时,我们对这些信息进行加密。
+在数据传输和数据保管两个阶段里,我们会通过广为接受的行业标准(如防火墙、加密和数据隐私法律要求)来保护您向我们提交的信息。
+然而,没有任何一种互联网传输或电子存储方法是100%安全的。因此,尽管我们通过商业上可接受的方式来保护您的个人信息,但仍无法保证信息的绝对安全。
+四、本公司会将个人信息保存多久
+一般来说,本公司仅在您使用本公司微信小程序期间保留您的个人信息,同时将遵守适用法律规定的数据保留期限。
+五、法律免责声明
+在法律要求的情况下(如协助公安机关)或遵守司法程序、法院指令,以及因用户行为而致使本公司的法定权益收到威胁,或适用于本公司的微信小程序的法律程序时,我们有权透露您的个人信息。
+如果本公司确定为了执行本公司的条款和条件或保护我们的经营,披露是合理必须的,则我们可能会披露与您有关的信息。
+六、本隐私政策的更改
+本公司会根据国家法律法规不定时更改本政策协议。修改执行之前,本公司将会在小程序用户协议、以及本公司网站通知本次政策更改,以便您了解我们如何收集、使用您的个人信息,哪些人可以访问这些信息,以及在什么情况下我们会披露这些信息。
+本公司保留随时修改本政策的权利,因此请经常查看。
+七、隐私问题
+如果你对本公司的隐私政策或数据处理有任何问题或顾虑,请通过+86 18049981341与本公司联系。