Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

jshttp

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jshttp - npm Package Compare versions

Comparing version
0.4.2
to
0.5.0
+36
lib/adapters/wx-miniprogram.js
'use strict'
const { settle, createError } = require('../axios-modules')
const statuses = require('../static/statuses')
const getUrl = require('../core/getUrl')
module.exports = function wxMiniprogramAdapter(config) {
const url = getUrl(config.baseURL, config.url, config.params)
return new Promise(function dispatchWxMiniprogramRequest(resolve, reject) {
let request = wx.request({
url: url,
data: config.data,
header: config.headers,
timeout: typeof config.timeout === 'number' && config.timeout > 0 ? config.timeout : undefined,
method: config.method.toUpperCase(),
success(res) {
const response = {
data: res.data,
status: res.statusCode,
statusText: statuses[res.statusCode] || 'UnKnown',
headers: res.header,
config,
request,
}
settle(resolve, reject, response)
},
fail() {
reject(createError('Network Error', config, null, request))
request = null
},
})
})
}
'use strict'
/**
* 当前文件用于引入原生 `axios` 的方法,所有需要使用 `axios` 源代码的方法均从此文件引入
*
* 说明:
* 1. 为保持代码简略,部分方法略有修改,但未改变原意。
*/
function createError(message, config, code, request, response) {
const error = new Error(message)
error.config = config
error.request = request
error.response = response
error.isAxiosError = true
if (code) {
error.code = code
}
error.toJSON = function toJSON() {
return {
message: this.message,
config: this.config,
code: this.code,
}
}
}
function settle(resolve, reject, response) {
const validateStatus = response.config.validateStatus
if (!response.status || !validateStatus || validateStatus(response.status)) {
resolve(response)
} else {
reject(createError('Request failed with status code ' + response.status, response.config, null, response.request, response))
}
}
module.exports = { createError, settle }
'use strict'
function isWxMiniprogram() {
return typeof wx === 'object' && typeof wx.request === 'function'
}
/**
* 获取默认请求适配器
*
* 说明:
* 1. 仅处理附加的适配器
* 2. `xhr` 和 `nodejs` 的适配器不处理,由 `axios` 接管
*/
module.exports = function getDefaultAdapter() {
let adapter
if (isWxMiniprogram()) {
adapter = require('../adapters/wx-miniprogram')
}
return adapter
}
'use strict'
function getType(val) {
return Object.prototype.toString.call(val).slice(8, -1).toLowerCase()
}
/**
* 重写 `axios` 默认的 `paramsSerializer` 方法,增加以下逻辑:
*
* 1. 按键名字典排序
*/
module.exports = function paramsSerializer(params) {
const parts = []
const basicType = ['number', 'string', 'boolean']
const keys = Object.keys(params)
keys.forEach((key) => {
const val = params[key]
const type = getType(val)
if (basicType.includes(type)) {
parts.push(`${key}=${String(val)}`)
} else if (type === 'array') {
val.forEach((item) => {
if (basicType.includes(getType(item))) {
parts.push(`${key + '[]'}=${String(item)}`)
}
})
} else if (type === 'date') {
parts.push(`${key}=${val.toISOString()}`)
} else if (type === 'object') {
parts.push(`${key}=${JSON.stringify(val)}`)
} else {
// 其余均不处理
}
})
parts.sort()
return parts.join('&')
}
'use strict'
const getDefaultAdapter = require('./core/default-adapter')
const defaults = {
adapter: getDefaultAdapter(),
}
module.exports = defaults
'use strict'
const CryptoJS = require('crypto-js')
const getUrl = require('../core/getUrl')
/** 放在 `config.headers` 中但是非正常请求头字段的字段 */
const axiosExtHeader = ['common', 'delete', 'get', 'head', 'patch', 'post', 'put']
/**
* 规格化请求头
* 1. 将字段名变为小写
* 2. 去除重复的字段
*/
function normalizeHeaders(headers) {
if (typeof headers !== 'object') {
return {}
} else {
return Object.keys(headers).reduce((result, field) => {
console.log('field: ', field)
const lowerField = field.toLowerCase()
if (!result[lowerField] && headers[field] && !axiosExtHeader.includes(field)) {
result[lowerField] = headers[field]
}
return result
}, {})
}
}
/**
* 获取参与签名的请求头字段
* @param {object} headers 请求头
* @returns {string[]}
*/
function getSignHeaderKeys(headers) {
/** 不参与 Header 签名的请求头 */
const EXCLUDE_SIGN_HEADERS = ['x-ca-signature', 'x-xa-signature-headers', 'accept', 'content-md5', 'content-type', 'date']
const signHeaderKeys = []
Object.keys(headers).forEach((field) => {
if (!EXCLUDE_SIGN_HEADERS.includes(field)) {
signHeaderKeys.push(field)
}
})
return signHeaderKeys.sort()
}
function getSignedHeadersString(signHeaderKeys, headers) {
const list = []
for (let i = 0; i < signHeaderKeys.length; i++) {
const key = signHeaderKeys[i]
const value = headers[key]
list.push(key + ':' + (value ? value : ''))
}
return list.join('\n')
}
function getPathAndParams(url) {
const urlRaw = url.replace('https://', '').replace('http://', '')
return urlRaw.substr(urlRaw.indexOf('/'))
}
function md5(content) {
return CryptoJS.MD5(content).toString(CryptoJS.enc.Base64)
}
function buildStringToSign(method, headers, signedHeadersString, pathAndParams) {
const lf = '\n'
const list = [method.toUpperCase(), lf]
const arr = ['accept', 'content-md5', 'content-type', 'date']
for (let i = 0; i < arr.length; i++) {
const key = arr[i]
if (headers[key]) {
list.push(headers[key])
}
list.push(lf)
}
if (signedHeadersString) {
list.push(signedHeadersString)
list.push(lf)
}
if (pathAndParams) {
list.push(pathAndParams)
}
return list.join('')
}
/**
* 阿里云 API 网关签名加密
* @see https://help.aliyun.com/document_detail/29475.html
*/
module.exports = function aliyunApigwSignatureInterceptor(config) {
// 未配置签名参数,则直接跳过
if (typeof config.signature !== 'object') {
return config
}
const { key, secret, debug } = config.signature
if (!(key && secret)) {
throw new Error('配置了 `signature` 参数但是未配置 `key` 或 `secret`')
}
const headers = normalizeHeaders(config.headers)
// 给请求头添加一些要求添加的字段
headers['x-ca-key'] = key
headers['x-ca-timestamp'] = Date.now()
headers['accept'] = headers['accept'] || '*/*'
headers['content-type'] = headers['content-type'] || 'application/json'
// 该请求头要求为一个随机字符串,理论上使用 `UUID` 更好,为了少引入依赖,使用这种方法
headers['x-ca-nonce'] = CryptoJS.MD5(Date.now().toString() + Math.random() * 10000).toString(CryptoJS.enc.Hex)
/** 允许包含 `body` 的请求方法 */
const bodyValidMethod = ['post', 'put', 'patch']
if (bodyValidMethod.includes(config.method.toLowerCase())) {
if (config.data) {
headers['content-md5'] = md5(JSON.stringify(config.data))
} else {
console.warn(`当前请求方法为 \`${config.method}\` 但是未配置请求数据(\`data\`)`)
}
} else {
if (config.data) {
console.warn('如果要提交请求数据 `data`,请使用以下请求方法:`post`, `put`, `patch` ')
}
}
const signHeaderKeys = getSignHeaderKeys(headers)
headers['x-ca-signature-headers'] = signHeaderKeys.join(',')
const url = getUrl(config.baseURL, config.url, config.params)
const pathAndParams = getPathAndParams(url)
const signedHeadersString = getSignedHeadersString(signHeaderKeys, headers)
const stringToSign = buildStringToSign(config.method, headers, signedHeadersString, pathAndParams)
headers['x-ca-signature'] = CryptoJS.HmacSHA256(stringToSign, secret).toString(CryptoJS.enc.Base64)
if (debug) {
console.info(`当前签名字符串:\`${stringToSign.replace(/\n/g, '#')}\``)
}
config.headers = headers
return config
}
'use strict'
const getDefaultAdapter = require('../core/default-adapter')
const mockAdapter = require('../adapters/mock')
module.exports = function coreInterceptor(config) {
/**
* 处理 `mock` 参数,优先级高于 `adapter` 参数
*
* 说明:
* 1. 只要存在有效的 `mock` 参数,则挂载 `mockAdapter` 适配器
*/
if (typeof config.mock === 'object' && Object.keys(config.mock).length > 0) {
config.adapter = mockAdapter
}
/**
* `adapter` 参数为空,则挂载对应的请求适配器
*/
if (!config.adapter) {
config.adapter = getDefaultAdapter()
}
return config
}
+4
-0
# 版本更新说明
## v0.5.0 - 2021.06.18
1. 重构版本
## v0.4.1 - 2021.05.07

@@ -4,0 +8,0 @@

+2
-1
'use strict'
const jshttp = require('./lib/jshttp.js')
const jshttp = require('./lib/jshttp')
module.exports = jshttp

@@ -5,0 +6,0 @@

'use strict'
const { settle, createError } = require('../axios-modules')
const statuses = require('../static/statuses')
/**
* 用于 Mock 数据,未发送真实请求
* 用于客户端 Mock 请求数据,并未发送真实的 HTTP 请求。
*/
/** 文档地址 */
const docUrl = 'https://www.npmjs.com/package/jshttp#使用'
module.exports = function mockAdapter(config) {

@@ -11,21 +17,50 @@ const { mock } = config

if (typeof mock !== 'object') {
throw new Error(`配置项 \`mock\` 要求是一个 \`object\` 类型的值,但是你设置的 \`mock\` = \`${mock}\` 为 \`${typeof mock}\` 类型`)
throw new Error(`配置项 \`mock\` 要求是一个 \`object\` 类型的值,详情请查看文档 ${docUrl}`)
}
const { status, statusText, headers, data, error } = mock
// 处理参数,所有参数均为选填
const status = mock.status || 200
const statusText = mock.statusText || statuses[status] || 'UnKnown'
const headers = mock.headers || {}
const data = mock.data
const delay = (mock.delay && parseInt(mock.delay, 10)) || 1
const error = mock.error
return new Promise((resolve, reject) => {
/** 各个平台的 `request` 均不同,这个无法模拟,只能模拟一些基础属性 */
let request = mock.request || {
method: config.method,
headers: config.headers,
data: config.data,
}
// 超时时间,用于模拟请求超时
const timeout = config.timeout || 0
return new Promise(function dispatchMockRequest(resolve, reject) {
/** 请求是否完成 */
let isRequestFinished = false
// 模拟请求超时的 `ontimeout` 事件
if (timeout > 0) {
setTimeout(() => {
if (!isRequestFinished) {
const timeoutErrorMessage = config.timeoutErrorMessage || `timeout of ${timeout} ms exceeded`
reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', request))
request = null
}
}, timeout)
}
// 模拟正常请求流程
setTimeout(() => {
isRequestFinished = true
if (error) {
reject(new Error(error))
// 模拟发生错误的 `onerror` 事件
reject(createError('Network Error', config, null, request))
request = null
} else {
resolve({
status: status || 200,
statusText: statusText || '',
headers: headers || {},
data: data,
config: config,
request: Object.create(null),
})
// 请求成功情况
const response = { data, status, statusText, headers, config, request }
settle(resolve, reject, response)
}

@@ -32,0 +67,0 @@ }, delay)

'use strict'
const paramsSerializer = require('./params-serializer')
function isHttpUrl(url) {

@@ -45,13 +47,3 @@ if (url && typeof url === 'string' && (url.startsWith('http://') || url.startsWith('https://'))) {

function encodeQs(obj) {
const arr = []
Object.keys(obj)
.sort()
.forEach((name) => {
const value = obj[name].toString()
if (value && typeof value === 'string' && value !== '[object Object]') {
// 兼容数组,name=['a','b'] 会转变为 name=a,b
arr.push(`${name}=${value}`)
}
})
return arr.join('&')
return paramsSerializer(obj)
}

@@ -58,0 +50,0 @@

'use strict'
const Application = require('./core/applocation.js')
const getDefaults = require('./config/defaults.js')
const axios = require('axios')
const defaults = require('./defaults')
const coreInterceptor = require('./interceptors/core-interceptor')
const aliyunApigwSignatureInterceptor = require('./interceptors/aliyun-apigw-signature')
function createInstance(defaultConfig) {
const instance = new Application(defaultConfig)
function create(defaultConfig) {
const instance = axios.create(defaultConfig)
instance.interceptors.request.use(aliyunApigwSignatureInterceptor)
instance.interceptors.request.use(coreInterceptor)
return instance
}
function request(...args) {
return instance.request(...args)
}
const jshttp = create(defaults)
jshttp.create = create
// 挂载常用方法
const methods = ['get', 'post', 'delete', 'put', 'patch']
methods.forEach((method) => {
request[method] = function (...args) {
return request(method.toUpperCase(), ...args)
}
})
return request
}
module.exports = createInstance(getDefaults())
module.exports.create = createInstance
module.exports = jshttp

@@ -0,0 +0,0 @@ 'use strict'

@@ -0,0 +0,0 @@ MIT License

{
"name": "jshttp",
"version": "0.4.2",
"description": "能在任何 Javascript 环境使用的 HTTP 请求库,支持 Node.js,浏览器,微信小程序,支付宝小程序,百度小程序 ...",
"version": "0.5.0",
"description": "基于 Axios 的 HTTP 请求库,内置了一些常用功能,支持在任何 Javascript 环境下运行",
"main": "index.js",

@@ -14,2 +14,3 @@ "scripts": {

"keywords": [
"axios",
"request",

@@ -30,3 +31,7 @@ "http",

"mocha": "^8.4.0"
},
"dependencies": {
"axios": "^0.21.1",
"crypto-js": "^4.0.0"
}
}
+6
-167

@@ -16,3 +16,3 @@ # jshttp

`JsHttp` 是一个基于 `Promise` 的 `Javascript` HTTP 请求库,支持在任何 `Javascript` 环境中发起 HTTP 请求(目前已支持 `Node.js`,`浏览器`,各大平台小程序,包含`微信`、`QQ`、`支付宝`、`字节跳动`等平台),在各个环境提供完全一致 `API`。同时集成了强大的 **中间件** 功能,可以自由灵活地对请求和响应进行操作。
`JsHttp` 是一个基于 `Axios` 的 `Javascript` HTTP 请求库,支持在任何 `Javascript` 环境中发起 HTTP 请求(目前已支持 `Node.js`,`浏览器`,各大平台小程序,包含`微信`、`QQ`、`支付宝`、`字节跳动`等平台),在各个环境提供完全一致 `API`。

@@ -31,11 +31,2 @@ ## 目录

- [配置项](#配置项)
- [进阶](#进阶)
- [默认值](#默认值)
- [设置默认值的方式](#设置默认值的方式)
- [默认值合并方式](#默认值合并方式)
- [中间件](#中间件)
- [中间件简介](#中间件简介)
- [中间件实现](#中间件实现)
- [使用中间件](#使用中间件)
- [中间件顺序](#中间件顺序)
- [作者](#作者)

@@ -51,2 +42,4 @@ - [参与](#参与)

另外,常用的 HTTP 请求库 `Axios` 本身已经非常成熟了,因此笔者基于 `Axios` 进行开发,拓展了 `Axios` 原生的 `adapter` 和 `interceptor` 来完成对应功能。
### 特点

@@ -57,6 +50,5 @@

1. 支持所有的 `Javascript` 环境(也就是说,只要你在用 `Javascript` 写代码,你可以可以使用 `JsHttp` 来发起请求)。
2. 兼容 `Axios` 参数,可以从 `Axios` 无缝迁移到 `JsHttp`。
3. 强大的中间件功能,可以非常方便灵活地操作请求和响应(中间件逻辑参考了 `Koa`,特此说明)。
4. 内置了一些中间件,例如请求内容签名、格式转换等,进行简单配置后就可以直接使用。
5. 全中文错误提示,更利于开发和调试。
2. 完全兼容 `Axios` 参数,可以从 `Axios` 无缝迁移到 `JsHttp`。
3. 内置了一些中间件,例如请求内容签名、格式转换等,进行简单配置后就可以直接使用。
4. 全中文错误提示,更利于开发和调试。

@@ -319,155 +311,2 @@ ## 安装

## 进阶
### 默认值
#### 设置默认值的方式
在实际开发中,你可能会希望自定义一些默认值,例如往往后端请求地址是固定的,不希望每次请求时都配置 `baseURL`,你希望能够将其设定为全局的默认值,`jshttp` 提供了两种方式来修改默认值。
比较简单的方式为直接修改 `jshttp.defaults[attribute]` 的值,例如:
```javascript
jshttp.defaults.baseURL = 'https://api.inlym.com/
```
其他的配置项也可以用同样的方式去设置。
另一种更为复杂的情况是,在一个前端项目中,需要配置多套不同的默认值,这种情况建议使用 `jshttp.create(defaultConfig)` 方法去创建一个新的实例,例如:
```javascript
const request1 = jshttp.create({
baseURL: 'https://api1.inlym.com',
responseType: 'text',
})
const request2 = jshttp.create({
baseURL: 'https://api2.inlym.com',
responseType: 'text',
timeout: 2000,
})
```
对于通过以上方式创建的 `request1` 和 `request2`,你可以像使用 `jshttp` 一样去使用它们。
#### 默认值合并方式
实际上,存在 3 组配置项:
1. `jshttp` 内置的全局默认值
2. 实例的自定义默认值
3. 本次请求的配置项
3 组配置项的优先级由低到高,在发起请求前会将配置项合并,生成最终的请求配置项,但实际上,各个配置项的合并方式还有有一些不一样的,对于除 `headers` 和 `params` 以外的其他配置项,更高优先级直接覆盖低优先级中的配置项。
对于 `headers` 和 `params` 这 2 个配置项,合并方式略有不同,采用 **合并** 而不是 **覆盖**(对象内同名字段采用 **覆盖**),例如:
```javascript
jshttp.defaults.headers = {
'header-a': 'aaa',
'header-b': 'bbb',
}
const config = {
headers: {
'header-b': 'BBB',
'header-c': 'ccc',
}
}
// 使用 `jshttp(config)` 发起请求时,实际合成的 `headers` 为
{
'header-a': 'aaa',
'header-b': 'BBB',
'header-c': 'ccc',
}
```
### 中间件
#### 中间件简介
`jshttp` 的中间件是与 `Axios` 的中间件采用了完全不同的实现方式,在实现逻辑上借鉴了 `Koa` 的中间件实现方式,你可以将其称之为 **洋葱模型**。在 `ctx` 变量上挂载了以下对象:
1. `config` - 配置项
2. `adapter` - 请求适配器
3. `response` - 响应(在适配器发送请求成功后创建)
你可以通过操作以上挂载的变量来实现中间件功能,中间件函数既可以是一个标准的异步函数,也可以是同步函数(会被封装为异步函数)。
#### 中间件实现
下面演示几个中间件实现。
示例 1:(模拟常见的请求签名逻辑)对 `headers` 签名,并使用 `x-ca-signature-headers` 字段记录被签名的字段,使用 `x-ca-signature` 记录签名内容:
```javascript
// 备注:只是用来演示中间件写法,并不是严谨的签名实现方法
function sign(ctx) {
// 从 `ctx` 中获取 `headers`
const requestHeaders = ctx.config.headers
const fields = Object.keys(requestHeaders)
const valueList = fields.map((field) => {
return requestHeaders[field]
})
requestHeaders['x-ca-signature-headers'] = fields.join(',')
requestHeaders['x-ca-signature'] = md5(valueList.join('\n'))
}
```
示例 2:微信小程序请求查询字符串加上 `code` 作为鉴权方式
```javascript
// 第一步:封装获取 `code` 的方法为 `Promise`
function getCode() {
return new Promise((resolve) => {
wx.login({
success(res) {
resolve(res.code)
},
})
})
}
// 第二步:在中间件中使用,需要用到 `await`
async function appendCode(ctx, next) {
const code = await getCode()
ctx.config.params.code = code
await next()
}
```
#### 使用中间件
中间件的配置和其他配置项一样,既可以定义为默认配置项,也可以只放在本次请求中使用。
使用方式 1:仅在本次请求中使用中间件,在配置项 `middleware` 中设置就行了
```javascript
jshttp({
// ... 其他配置项
middleware: [appendCode, sign],
})
```
使用方式 2:添加到默认配置项
`middleware` 配置项定义为默认配置项的方式和其他参数完全一致,除此之外,还可以使用 `jshttp.use(fn)` 方法添加一个新的中间件到中间件列表中(本质上只是对列表进行了一个 `push` 操作)
#### 中间件顺序
少数中间件对于执行顺序是有要求的,例如 **签名中间件** 就应该放在所有的中间件之后,在发送请求之前,`jshttp` 内置提供了定义中间件执行顺序的方法,在以上说明的任何放置中间件的地方,可以替换为以下对象,定义中间件顺序:
```javascript
// 以上述的 `sign` 中间件为例
{
fn: sign,
order: 9999,
}
```
使用普通方式添加中间件或者未定义 `order` 参数的中间件,将自动将 `order` 设置为 `100`,最终会将所有中间件按 `order` 升序执行。
## 作者

@@ -474,0 +313,0 @@

'use strict'
/**
* 生成一个小程序适配器
* @param {object} options 构造适配器的配置项
*
* 说明:
* 1. 由于平台的小程序的 `request` 方法大同小异,因此没必要各个单独写,只需要兼容一下参数就可以了
* 2. 适配参数,然后输出一个函数
*
* 小程序平台:
* 1. 微信小程序
* @see https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html
*
* 2. QQ 小程序
* @see https://q.qq.com/wiki/develop/miniprogram/API/network/network_request.html
*
* 3. 支付宝小程序
* @see https://opendocs.alipay.com/mini/api/owycmh
*
* 4. 字节跳动小程序
* @see https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/api/network/http/tt-request
*/
const getUrl = require('../core/getUrl.js')
/**
* 将配置项中的 `responseType` 参数转换为小程序请求所需的 `dataType` 和 `dataType` 参数
* @param {string} responseType 响应数据类型
*/
function convertResponseType(responseType) {
if (typeof my === 'object') {
if (responseType === undefined || responseType === 'json') {
return { dataType: 'JSON' }
} else {
return { dataType: responseType }
}
} else {
if (responseType === undefined || responseType === 'json') {
return {
dataType: 'json',
responseType: 'text',
}
} else if (['arraybuffer', 'blob', 'stream'].includes(responseType)) {
return {
dataType: 'arraybuffer',
responseType: 'arraybuffer',
}
} else {
return {
dataType: 'string',
responseType: 'text',
}
}
}
}
module.exports = function createMiniAdapter(options) {
/** 请求头字段名称,默认 `headers` */
const requestHeaders = (options.alias && options.alias.requestHeaders) || 'headers'
/** 响应头字段名称,默认 `headers` */
const responseHeaders = (options.alias && options.alias.responseHeaders) || 'headers'
/** 响应码字段名称,默认 `statusCode` */
const statusCode = (options.alias && options.alias.statusCode) || 'statusCode'
return function miniAdapter(config) {
const requestOptions = {
method: config.method,
url: getUrl(config.baseURL, config.url, config.params),
timeout: config.timeout,
[requestHeaders]: config.headers,
}
/** 不应该有请求体的请求方法 */
const NO_BODY_METHODS = ['GET', 'HEAD', 'OPTIONS']
if (!NO_BODY_METHODS.includes(config.method) && config !== undefined) {
requestOptions.data = config.data
}
/**
* 备注:
* 笔者认为,当请求方法为 `GET` 时,将 `data` 插入到 `quertstirng` 中,这种做法很怪异!非常容易造成难以预料的问题!
* 因此在 `jshttp` 中,直接屏蔽了这种做法。
*/
/** 附加的参数 */
const extraConfigKeys = ['enableHttp2', 'enableQuic', 'enableCache']
extraConfigKeys.forEach((key) => {
if (config[key]) {
requestOptions[key] = config[key]
}
})
return new Promise((resolve, reject) => {
const request = options.platform.request(
Object.assign({}, convertResponseType(config.responseType), requestOptions, {
success(res) {
resolve({
status: res[statusCode],
headers: res[responseHeaders],
data: res.data,
config: config,
request: request,
})
},
fail(res) {
if (!res) {
reject(new Error('请求错误,发起请求失败!'))
} else {
if (typeof res === 'object' && typeof res.errMsg === 'string') {
reject(new Error('请求失败,错误原因:' + res.errMsg))
}
}
},
})
)
})
}
}
'use strict'
/**
* 支付宝小程序
* @see https://opendocs.alipay.com/mini/api/owycmh
*/
const createMiniAdapter = require('./mini-base.js')
const options = {
/** 所在平台简称 */
name: 'my',
/** 对应的全局变量 */
platform: my,
/** 支持的请求方法 */
methods: ['GET', 'POST', 'PUT', 'DELETE'],
/** 参数别名 */
alias: {
requestHeaders: 'headers',
responseHeaders: 'headers',
statusCode: 'status',
},
}
module.exports = createMiniAdapter(options)
'use strict'
/**
* QQ 小程序
* @see https://q.qq.com/wiki/develop/miniprogram/API/network/network_request.html
*/
const createMiniAdapter = require('./mini-base.js')
const options = {
/** 所在平台简称 */
name: 'qq',
/** 对应的全局变量 */
platform: qq,
/** 支持的请求方法 */
methods: ['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'],
/** 参数别名 */
alias: {
requestHeaders: 'header',
responseHeaders: 'header',
statusCode: 'statusCode',
},
}
module.exports = createMiniAdapter(options)
'use strict'
/**
* 字节跳动小程序
* @see https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/api/network/http/tt-request
*/
const createMiniAdapter = require('./mini-base.js')
const options = {
/** 所在平台简称 */
name: 'tt',
/** 对应的全局变量 */
platform: tt,
/** 支持的请求方法
*
*
* GET/POST/OPTIONS/PUT/HEAD/DELETE
*/
methods: ['GET', 'HEAD', 'POST', 'OPTIONS', 'PUT', 'DELETE'],
/** 参数别名 */
alias: {
requestHeaders: 'header',
responseHeaders: 'header',
statusCode: 'statusCode',
},
}
module.exports = createMiniAdapter(options)
'use strict'
const createMiniAdapter = require('./mini-base.js')
const options = {
/** 所在平台简称 */
name: 'wx',
/** 对应的全局变量 */
platform: wx,
/** 支持的请求方法 */
methods: ['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'],
/** 参数别名 */
alias: {
requestHeaders: 'header',
responseHeaders: 'header',
statusCode: 'statusCode',
},
}
module.exports = createMiniAdapter(options)
'use strict'
/**
* Node.js HTTP
* @see https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_http_request_options_callback
*/
const http = require('http')
const https = require('https')
const getUrl = require('../core/getUrl.js')
const packageInfo = require('../../package.json')
/**
* Node.js 发起请求适配器
* @param {object} config 配置项
*
* 说明:
* 1. 本期版本统一不支持 proxy
* 2. 后续版本支持自定义 agent
*/
module.exports = function nodeAdapter(config) {
const url = getUrl(config.baseURL, config.url, config.params)
// 根据 `http` 或 `https` 协议选用对应的模块
let httpModule = null
if (url.startsWith('http://')) {
httpModule = http
} else if (url.startsWith('https://')) {
httpModule = https
} else {
throw new Error('请求地址请以 `http://` 或 `https://` 开头!')
}
const { headers, method } = config
// 处理 `data`
let requestData = null
let contentType = ''
if (typeof config.data === 'object') {
requestData = JSON.stringify(config.data)
contentType = 'application/json'
} else if (typeof config.data === 'string') {
requestData = config.data
contentType = 'text/plain'
}
const options = {
method: method,
headers: headers,
}
if (config.timeout && config.timeout > 0) {
options.timeout = config.timeout
}
return new Promise((resolve, reject) => {
const request = httpModule.request(url, options, function handleResponse(response) {
const responseBufferList = []
response.on('data', function handleResponseData(buf) {
responseBufferList.push(buf)
})
response.on('end', function handleResponseEnd() {
let responseData = Buffer.concat(responseBufferList)
if (config.responseType !== 'arraybuffer') {
responseData = responseData.toString(config.responseEncoding)
}
resolve({
status: response.statusCode,
statusText: response.statusMessage,
headers: response.headers,
data: responseData,
config: config,
request: request,
})
})
})
// 监听 `error` 事件
request.on('error', function handleRequestError(err) {
reject(new Error(`请求时发生错误,触发 \`error\` 事件,以下是错误原因:${err}`))
})
request.on('timeout', function handleRequestTimeout() {
/**
* 请求超时时,需要手动中止请求
* @see https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_event_timeout
*
* `request.abort()` 方法已启用,改用 `request.destroy()`
* @see https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_request_abort
*/
request.destroy()
reject(new Error(`请求已超时(你设置的超时时间为 \`timeout: ${config.timeout}\`,单位:ms)`))
})
// 附加一些请求头
if (!request.getHeader('User-Agent')) {
request.setHeader('User-Agent', `JsHttp/${packageInfo.version}`)
}
if (!request.getHeader('Content-Type') && contentType) {
request.setHeader('Content-Type', contentType)
}
request.end(requestData)
})
}
'use strict'
const getUrl = require('../core/getUrl.js')
/**
* XMLHttpRequest
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
*/
/**
* 获取并解析响应头
* @param {XMLHttpRequest} xhr
* @returns {object} 解析成对象的响应头
*
* 调用 `XMLHttpRequest.getAllResponseHeaders()` 获取的响应头,是以 `CRLF` 分割的字符串,需要手工解析
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/getAllResponseHeaders
*/
function getHeaders(xhr) {
/**
* 关于 `CRLF`
* @see https://developer.mozilla.org/zh-CN/docs/Glossary/CRLF
*/
const CRLF = '\r\n'
// 裸响应头,以 `CRLF` 分割的字符串
const rawHeaders = xhr.getAllResponseHeaders()
// 以分隔符拆分响应头字符串
const headerList = rawHeaders.split(CRLF)
// 获取响应头字段名列表
const fieldList = headerList.map((v) => {
return v.split(':')[0]
})
const headers = {}
fieldList.forEach((field) => {
if (field) {
headers[field] = xhr.getResponseHeader(field)
}
})
return headers
}
/**
* 检查指定请求头是否被禁用修改(仅提示)
* @param {string} field 请求头字段(请求首部)
*
* 部分请求头不能在代码中通过编程的方式进行修改,应该由由浏览器控制
* @see https://developer.mozilla.org/zh-CN/docs/Glossary/Forbidden_header_name
*/
function warnIfHeaderNameForbidden(field) {
const forbiddenHeaderNames = [
'Accept-Charset',
'Accept-Encoding',
'Access-Control-Request-Headers',
'Access-Control-Request-Method',
'Connection',
'Content-Length',
'Cookie',
'Cookie2',
'Date',
'DNT',
'Expect',
'Host',
'Keep-Alive',
'Origin',
'Referer',
'TE',
'Trailer',
'Transfer-Encoding',
'Upgrade',
'Via',
]
const forbiddenHeaderNamePrefix = ['Proxy-', 'Sec-']
forbiddenHeaderNames.forEach((key) => {
if (key.toUpperCase() === field.toUpperCase()) {
const message = `请求头 \`${field}\` 不允许自主设置,应当由浏览器自动设置,建议删除该请求头!详见文档 https://developer.mozilla.org/zh-CN/docs/Glossary/Forbidden_header_name`
console.error(message)
}
})
forbiddenHeaderNamePrefix.forEach((pre) => {
if (field.toUpperCase().startsWith(pre.toUpperCase())) {
const message = `以 \`${pre}\` 开头的请求头不允许自主设置,应当由浏览器自动设置,建议删除 \`${field}\` 请求头!详见文档 https://developer.mozilla.org/zh-CN/docs/Glossary/Forbidden_header_name`
console.error(message)
}
})
}
/**
* 检查响应数据类型(即 `responseType` 值)是否合规
* @param {string} responseType 响应数据的类型
*
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/responseType
*/
function throwErrorIfInvalidResponseType(responseType) {
const valid = ['', 'arraybuffer', 'blob', 'document', 'json', 'text']
if (!valid.includes(responseType)) {
throw new Error(`你设置的 \`responseType\` 为 \`${responseType}\` 不是一个有效的值!`)
}
}
module.exports = function xhrAdapter(config) {
const url = getUrl(config.baseURL, config.url, config.params)
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open(config.method, url, true)
// 设置超时时间
if (config.timeout > 0) {
xhr.timeout = config.timeout
}
// 设置响应值类型
throwErrorIfInvalidResponseType(config.responseType)
xhr.responseType = config.responseType
// 设置 `withCredentials`
if (config.withCredentials) {
xhr.withCredentials = true
}
// 监听发生请求错误
xhr.onerror = function handleRequestError() {
reject(new Error('请求时发生错误,触发 `error` 事件'))
}
/**
* 监听请求完成,`onload` 相比 `onreadystatechange` 更智能一些
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequestEventTarget/onload
*/
xhr.onload = function handleRequestLoad() {
const responseHeaders = getHeaders(xhr)
resolve({
status: xhr.status,
statusText: xhr.statusText,
headers: responseHeaders,
data: xhr.response,
config: config,
request: xhr,
})
}
// 监听请求超时
xhr.ontimeout = function handleRequestTimeout() {
reject(new Error(`请求已超时(你设置的超时时间为 \`timeout: ${config.timeout}\`,单位:ms)`))
}
// 处理请求数据
let requestData = config.data || null
/**
* 如果请求方法是 GET 或者 HEAD,则应将请求主体设置为 null
* @see https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/send
*/
if (['GET', 'HEAD'].includes(config.method)) {
requestData = null
}
if (requestData && typeof requestData === 'object') {
requestData = JSON.stringify(requestData)
}
// 最终处理请求头,逐个设置
Object.keys(config.headers).forEach((field) => {
warnIfHeaderNameForbidden(field)
xhr.setRequestHeader(field, config.headers[field])
})
xhr.send(requestData)
})
}
'use strict'
const methods = require('../static/methods.js')
/**
* 支持不定长度的参数形式,合成一个参数对象
*
* 格式演示:
* 1. `('get', '/path.to?name=mark', { baseURL: 'https://www.jshttp.com' })`
* 2. `('/path.to?name=mark')`
* 3. `({ baseURL: 'https://www.jshttp.com', method: 'post'})`
* 4. `({ baseURL: 'https://www.jshttp.com' }, 'get', '/path.to?name=mark',)`
*/
module.exports = function buildConfig(...args) {
if (args.length === 0) {
throw new Error('请求配置项 `config` 不能为空')
}
// 首先生成一个对象列表
const configList = args.map((value) => {
if (typeof value === 'object' && value !== null) {
return value
} else if (typeof value === 'string') {
if (methods.includes(value.toUpperCase())) {
return { method: value.toUpperCase() }
} else {
return { url: value }
}
}
})
const config = {}
Object.assign(config, ...configList)
return config
}
'use strict'
const getAdapter = require('../core/getAdapter.js')
const defaultAdapter = getAdapter()
/**
* 当前文件放置 [ 默认配置 ]
*
* 用途说明:
* 1. 生成实例时,作为默认配置
* 2. 开发者可以从当前文件查看支持的参数,以及含义
* 3. 未避免全局污染,封装为函数
*/
module.exports = function getDefaults() {
return {
/*********************************** 基本类型值配置 **********************************/
/**
* 请求方法
*
* 常用值:
* 1. `GET`
* 2. `POST`
* 3. `PUT`
* 4. `DELETE`
* 5. `HEAD`
*/
method: 'GET',
/**
* 请求基础地址
*
* 说明:
* 1. 不为空时要求以 `http://` 或 `https://` 开头
* 2. 配置项 `url` 以 `http://` 或 `https://` 开头时,配置项 `baseURL` 无效
* 3. 配置项 `url` 为普通路径时(即以非 `http://` 或 `https://` 开头),将两者连接合成请求地址
*/
baseURL: undefined,
/**
* 请求地址
*
* 说明:
* 1. 可单独存在,或者和 `baseURL` 拼接合成请求地址
* 2. 和 `baseURL` 不能同时为空
*/
url: undefined,
/**
* 请求的数据类型
*
* 合法值:
* 1. `json`
* 2. `text`
* 3. `form`
* 4. `arraybuffer`
*/
requestType: 'json',
/**
* 响应的数据类型
*
* 合法值:
* 1. `json` - 全部适用
* 2. `arraybuffer` - 全部适用
* 3. `text` - 全部适用
* 4. `blob` - 仅用于 `XMLHttpRequest`
* 5. `document` - 仅用于 `XMLHttpRequest`
* 6. `stream` - 仅用于 `Node.js`
*/
responseType: 'json',
/**
* 响应的字符编码
*
* 合法值:
* 'utf8', 'utf-8', 'utf16le', 'latin1', 'base64', 'hex', 'ascii', 'binary', 'ucs2'
*/
responseEncoding: 'utf8',
/**
* 请求超时时间
*
* 说明:
* 1. `0` 表示无超时时间
* 2. 单位:毫秒(ms)
*/
timeout: 0,
/**
* 重试次数
*
* 说明:
* 1. `0` 表示不重试
*/
retry: 0,
/**
* 是否开启调试模式
*
* 开启后,包含以下功能:
* 1. 打印请求日志
*/
debug: false,
/**
* 用于打印日志的函数
* @param {object} content 日志内容对象
* @param {number} content.status 响应状态码
* @param {string} content.url 请求地址
* @param {object} content.config 配置项
* @param {number} content.startTime 发起请求任务时间(时间戳)
* @param {number} content.endTime 结束请求任务时间(时间戳)
* @param {number} content.requestTime 本次发起请求时间(时间戳)
* @param {number} content.responseTime 本次结束响应时间(时间戳)
* @param {string} content.startTimeText 发起请求任务时间(文本格式)
* @param {string} content.endTimeText 结束请求任务时间(文本格式)
* @param {string} content.requestTimeText 本次发起请求时间(文本格式)
* @param {string} content.responseTimeText 本次结束响应时间(文本格式)
*/
logging: function logging(content) {
const message = `${content.startTimeText} ${content.responseTime - content.requestTime}ms ${content.config.method} ${content.url} ${content.status}`
console.log(message)
},
/*********************************** 对象类配置 **********************************/
/**
* 请求头
*/
headers: {},
/**
* 请求参数,最终以 `name=mark&age=19` 的形式合并到 `url` 中
*/
params: {},
/**
* mock 响应对象
*/
mock: undefined,
/*********************************** 函数类配置 **********************************/
/**
* 请求适配器,将最终使用该适配器发送请求
*/
adapter: defaultAdapter,
/**
* 是否是正常的响应状态码,函数返回为 `false` 将直接报错
* @param {number} status 响应状态码
* @returns {boolean}
*/
validateStatus: function validateStatus(status) {
return typeof status === 'number' && status >= 200 && status < 300
},
/*********************************** 其他配置 **********************************/
/**
* 请求数据
*/
data: undefined,
/**
* 用户自定义中间件列表
*/
middleware: [],
/**
* 响应的返回内容项
*
* 合法值:
* 1. `status`
* 2. `statusText`
* 3. `headers`
* 4. `data`
* 5. `config`
* 6. `request`
*
* 支持别名,格式:
* ```js
* {
* item: 'status,
* alias: 'statusCode'
* }
* ```
*/
responseItems: ['status', 'statusText', 'headers', 'data'],
}
}
'use strict'
const base = require('./defaults.js')
/**
* 合并配置项
* @param {object} base 基础配置项,包含所有可配置键名
* @param {object} defaults 实例的默认配置项
* @param {object} comtom 本次请求设置的配置项
*
* 说明:
* 1. 优先级:`comtom` > `defaults` > `base`
*/
module.exports = function mergeConfig(base, defaults, custom) {
/**
* 第一类键名
*
* 说明:
* 1. 更高优先级存在值,则直接覆盖低优先级配置
*/
const firstTypeKeys = [
'method',
'baseURL',
'url',
'requestType',
'responseType',
'responseEncoding',
'timeout',
'retry',
'mock',
'adapter',
'data',
'middleware',
'responseItems',
'validateStatus',
'sign',
'debug',
'logging',
]
/**
* 第二类键名
*
* 说明:
* 1. 更高优先级存在对应值,不会覆盖低优先级,而是做合并处理
* 2. 对应值类型应为 `object`
* 3. 对象内同名键,更高优先级覆盖低优先级
*/
const secondTypeKeys = ['headers', 'params']
firstTypeKeys.forEach((key) => {
custom[key] = custom[key] || defaults[key] || base[key]
})
secondTypeKeys.forEach((key) => {
custom[key] = Object.assign({}, base[key], defaults[key] || {}, custom[key] || {})
})
return custom
}
'use strict'
const methods = require('../static/methods.js')
/**
* 检验一个值是否是指定的类型,如果不是则报错
* @param {*} value 要检验的数据
* @param {*} type 类型
* @param {*} name 名称
*/
function throwErrorIfWrongType(name, value, type) {
if (typeof value !== type) {
const message = `配置项 \`${name}\` 要求是一个 \`${type}\` 类型的值,但是你设置的 \`${name}\` = \`${value}\` 为 \`${typeof value}\` 类型`
throw new Error(message)
}
}
/**
* 指定的值如果没有在列表中,则报错
* @param {*} value 要检验的数据
* @param {*} list 列表
* @param {*} name 名称
*/
function throwErrorIfNotInclude(name, value, list) {
if (!list.includes(value)) {
const message =
`配置项 \`${name}\` 仅支持以下值,你设置的 \`${name}\` = \`${value}\` 不在此范围内:\n` +
list
.map((value, index) => {
return `${index + 1}. \`${value}\`\n`
})
.join('')
throw new Error(message)
}
}
/**
* 整理参数(对原对象对校验和调整)
* @param {object} config 配置项
*
* 说明:
* 1. 将已知的参数做一个 `数据校验` 和规范化,未知数据原封不动保留
*/
module.exports = function normalizeConfig(config) {
throwErrorIfWrongType('config', config, 'object')
/**
* 配置项 `method`
*
* 规则:
* 1. 大写字符串
* 2. 在指定范围内
*/
if (config.method !== undefined) {
throwErrorIfWrongType('method', config.method, 'string')
config.method = config.method.toUpperCase()
throwErrorIfNotInclude('method', config.method, methods)
}
/**
* 配置项 `baseURL`
*
* 规则:
* 1. 字符串
* 2. 以 `http://` 或 `https://` 开头
*/
if (config.baseURL !== undefined) {
throwErrorIfWrongType('baseURL', config.baseURL, 'string')
if (!config.baseURL.startsWith('http://') && !config.baseURL.startsWith('https://')) {
throw new Error('配置项 `baseURL` 应该以 `http://` 或 `https://` 开头,例如 `https://www.jshttp.cn/`')
}
}
/**
* 配置项 `url`
*
* 规则:
* 1. 字符串
*/
if (config.url !== undefined) {
if (typeof config.url !== 'string') {
throw new Error('配置项 `url` 应该是一个字符串类型,可以是绝对路径或相对路径,例如 `https://www.jshttp.cn/` 或 `/api`')
}
}
/**
* 配置项 `requestType`
*
* 规则:
* 1. 字符串
*
* 合法值:
* 1. `json` - 默认
* 2. `text`
* 3. `form`
* 4. `arraybuffer`
*/
if (config.requestType !== undefined) {
throwErrorIfWrongType('requestType', config.requestType, 'string')
const validList = ['json', 'text', 'form', 'arraybuffer']
throwErrorIfNotInclude('requestType', config.requestType, validList)
}
/**
* 配置项 `responseType`
*
* 规则:
* 1. 字符串
*
* 合法值:
* 1. `json` - 全部适用
* 2. `arraybuffer` - 全部适用
* 3. `text` - 全部适用
* 4. `blob` - 仅用于 `XMLHttpRequest`
* 5. `document` - 仅用于 `XMLHttpRequest`
* 6. `stream` - 仅用于 `Node.js`
*/
if (config.responseType !== undefined) {
throwErrorIfWrongType('responseType', config.responseType, 'string')
const validList = ['arraybuffer', 'blob', 'document', 'json', 'text', 'stream']
throwErrorIfNotInclude('responseType', config.responseType, validList)
}
/**
* 配置项 `responseEncoding`
*
* 规则:
* 1. 字符串
*
* 合法值:
* 1. `utf8` (或 `utf-8`)
* 2. `base64`
* 3. `hex`
* 4. `ascii`
* 5. `binary`
* 6. `ucs2`
* 7. `latin1`
* 8. `utf16le`
*/
if (config.responseEncoding !== undefined) {
throwErrorIfWrongType('responseEncoding', config.responseEncoding, 'string')
const validList = ['utf8', 'utf-8', 'utf16le', 'latin1', 'base64', 'hex', 'ascii', 'binary', 'ucs2']
throwErrorIfNotInclude('responseEncoding', config.responseEncoding, validList)
}
/**
* 配置项 `timeout`
*
* 规则:
* 1. 数字
*/
if (config.timeout !== undefined) {
throwErrorIfWrongType('timeout', config.timeout, 'number')
const timeout = parseInt(config.timeout, 10)
config.timeout = timeout > 0 ? timeout : 0
}
/**
* 配置项 `retry`
*
* 规则:
* 1. 非负整数
*/
if (config.retry !== undefined) {
if (!(Number.isInteger(config.retry) && config.retry >= 0)) {
throw new Error('配置项 `retry` 要求是一个非负整数(0,1,2,...)')
}
}
/**
* 配置项 `headers`
*
* 规则:
* 1. 对象
*/
if (config.headers !== undefined) {
throwErrorIfWrongType('headers', config.headers, 'object')
}
/**
* 配置项 `params`
*
* 规则:
* 1. 对象
*/
if (config.params !== undefined) {
throwErrorIfWrongType('params', config.params, 'object')
}
/**
* 配置项 `mock`
*
* 规则:
* 1. 对象
*/
if (config.mock !== undefined) {
throwErrorIfWrongType('mock', config.mock, 'object')
}
/**
* 配置项 `adapter`
*
* 规则:
* 1. 函数
*/
if (config.adapter !== undefined) {
throwErrorIfWrongType('adapter', config.adapter, 'function')
}
/**
* 配置项 `validateStatus`
*
* 规则:
* 1. 函数
*/
if (config.validateStatus !== undefined) {
throwErrorIfWrongType('validateStatus', config.validateStatus, 'function')
}
/**
* 配置项 `middleware`
*
* 规则:
* 1. 数组
* 2. 子项为函数或对象
*/
if (config.middleware !== undefined) {
if (typeof config.middleware !== 'object' || typeof config.middleware.length !== 'number') {
throw new Error('配置项 `middleware` 要求是一个数组!')
}
config.middleware.forEach(function checkMiddlewareItemType(item) {
if (typeof item !== 'function' && typeof item !== 'object') {
throw new Error('配置项 `middleware` 的列表元素要求是一个函数或对象,请检查你的设置!')
}
})
}
/**
* 配置项 `responseItems`
*
* 规则:
* 1. 数组
*/
if (config.responseItems !== undefined) {
if (typeof config.responseItems !== 'object' || typeof config.responseItems.length !== 'number') {
throw new Error('配置项 `responseItems` 要求是一个数组!')
}
if (config.responseItems.length === 0) {
throw new Error('配置项 `responseItems` 应至少包含一个元素,可选值:`status`, `statusText`, `headers`, `data`, `config`, `request`')
}
const valid = ['status', 'statusText', 'headers', 'data', 'config', 'request']
config.responseItems.forEach(function checkResponseItemInclude(item) {
if (!valid.includes(item)) {
throw new Error(
'配置项 `responseItems` 的可选值:`status`, `statusText`, `headers`, `data`, `config`, `request`,你可以选择一项或多项,你选择的以下值不在可选值内:' +
` \`${item}\` `
)
}
})
}
/**
* 配置项 `debug`
*
* 合法值:
* 1. `true`
* 2. `false`
*/
if (config.debug !== undefined) {
if (config.debug !== true && config.debug !== false) {
throw new Error('配置项 `debug` 的可选值:`true` 或 `false`')
}
}
/**
* 配置项 `logging`
*
* 规则:
* 1. 是一个函数
*/
if (config.logging !== undefined) {
throwErrorIfWrongType('logging', config.logging, 'function')
}
/**
* 配置项 `data`
*
* 规则:
* 1. 对 `data` 无校验
*/
if (config.data !== undefined) {
// 空
}
return config
}
'use strict'
const buildConfig = require('../config/buildConfig.js')
const initialize = require('../lifetime/initialize.js')
const dispatch = require('../lifetime/dispatch.js')
const mergeConfig = require('../config/mergeConfig.js')
const getDefaults = require('../config/defaults.js')
const normalizeConfig = require('../config/normalizeConfig.js')
const Context = require('./context.js')
const getAliyunApigwSignatureMiddleware = require('../middleware/aliyunApigwSignature.js')
const MIDDLEWARE = Symbol('application#middleware')
const baseConfig = getDefaults()
module.exports = class Application {
constructor(defaultConfig) {
this.defaults = normalizeConfig(defaultConfig)
/**
* 用户自定义中间件列表
*
* @param {function} [].fn 函数
* @param {number} [].order 函数排序,用于在生成最终函数时,将列表重排(按数字升序排列)
*/
this[MIDDLEWARE] = this.defaults.middleware || []
}
/**
* 添加一个默认自定义中间件
* @param {function|object} obj 中间件
*/
use(obj) {
this[MIDDLEWARE]['push'](obj)
}
/**
* 根据配置,计算需要加入的签名中间件
*/
getSignMiddleware(config) {
if (config.sign && typeof config.sign === 'object' && !config.sign.disable) {
if (!(config.sign.key && config.sign.secret)) {
throw new Error('签名中间件开启时,需要同时配置 `sign.key` 和 `sign.secret` 参数!')
}
if (!config.sign.type || config.sign.type === 'aliyun') {
return getAliyunApigwSignatureMiddleware(config.sign)
}
}
}
createPipeline(configMiddleware) {
// 整理格式统一为 `{fn:function;order:number;}`
const unifiedList = configMiddleware.map((value) => {
if (typeof value === 'object') {
const { fn, order } = value
if (typeof fn === 'function' && typeof order === 'number') {
return { fn, order }
}
} else if (typeof value === 'function') {
return { fn: value, order: 100 }
}
throw new Error('中间件格式错误')
})
// 对中间件重新排序(按照 `order` 升序排列)
unifiedList.sort((a, b) => {
return a.order - b.order
})
// 获取中间件函数列表
const middleware = unifiedList.map((value) => {
return value.fn
})
middleware.push(dispatch)
middleware.unshift(initialize)
return function (context, next) {
let index = -1
function dispatch(i) {
if (i <= index) return Promise.reject(new Error('next() 被执行了多次!'))
index = i
let fn = middleware[i]
if (i === middleware.length) {
fn = next
}
if (!fn) {
return Promise.resolve()
}
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)))
} catch (err) {
return Promise.reject(err)
}
}
return dispatch(0)
}
}
/**
* 发起请求(包含重试逻辑)
*/
async request(...args) {
// 整理参数,生成标准格式的 `config`
const customConfig = buildConfig(...args)
const config = mergeConfig(baseConfig, this.defaults, normalizeConfig(customConfig))
// 加入 `签名中间件`
const signFn = this.getSignMiddleware(config)
if (signFn) {
config.middleware.push({ fn: signFn, order: 9999 })
}
/** 最大重试次数 */
let retry = config.retry
/** 已重试次数 */
let retries = -1
/** 检验成功请求函数 */
const validateStatus = config.validateStatus
/** 响应结果列表 */
const responses = []
while (retry >= 0) {
retry--
retries++
const result = await this.execSingleRequest(config, retries)
responses.push(result)
if (validateStatus(result.status)) {
// 返回响应结果
const { responseItems } = config
const output = {}
responseItems.forEach((key) => {
if (typeof key === 'string') {
output[key] = result[key]
} else if (typeof key === 'object') {
const { item, alias } = key
output[alias] = result[item]
} else {
throw new Error('配置项 `responseItems` 格式错误')
}
})
if (responseItems.includes('responses')) {
output.responses = responses
}
return output
}
}
throw new Error(responses[responses.length - 1])
}
/**
* 执行单次请求
*/
async execSingleRequest(config, retries) {
const context = new Context(config)
context.retries = retries
const fn = this.createPipeline(config.middleware)
return await fn(context)
}
}
'use strict'
const getUrl = require('./getUrl.js')
const mockAdapter = require('../adapters/mock.js')
const STATE = Symbol('context#state')
module.exports = class Context {
constructor(config) {
// 检查请求头
this.checkHeadersUnique(config.headers)
this.config = config
this.adapter = config.mock && typeof config.mock === 'object' ? mockAdapter : config.adapter
/** 公共存储空间 */
this[STATE] = {}
}
/**
* 以指定名称存储当前时间
* @param {string} name 名称
*/
setTime(name) {
/**
* 辅助函数:对数字补零到指定位数
* @param {number} number 被格式化的数字
* @param {number} digit 格式化的位数
* @returns {string}
*/
function zerofill(number, digit = 2) {
const zero = '0'
for (let i = 0; i < digit; i++) {
if (number < Math.pow(10, i + 1)) {
const str = zero.repeat(digit - i - 1) + number.toString()
return str
}
}
return number
}
const time = new Date()
const year = time.getFullYear()
const month = zerofill(time.getMonth())
const day = zerofill(time.getDate())
const hour = zerofill(time.getHours())
const minute = zerofill(time.getMinutes())
const second = zerofill(time.getSeconds())
const millisecond = zerofill(time.getMilliseconds(), 3)
const str = `${year}-${month}-${day} ${hour}:${minute}:${second}.${millisecond}`
this[STATE][name] = time.getTime()
this[STATE][name + 'Text'] = str
}
get state() {
return this[STATE]
}
/**
* 用于在中间件中快速获取 `url`
*/
get url() {
return getUrl(this.config.baseURL, this.config.url, this.config.params)
}
/**
* 检查请求头是否存在同名字段
* @param {object} headers 请求头
*
* 例如:`content-type` 和 `Content-Type` 为同名字段
*/
checkHeadersUnique(headers) {
const keys = Object.keys(headers)
for (let i = 0; i < keys.length - 1; i++) {
for (let j = i + 1; j < keys.length; j++) {
if (keys[i].toUpperCase() === keys[j].toUpperCase()) {
throw new Error(`请求头中的 \`${keys[i]}\` 和 \`${keys[j]}\` 同名冲突,请检查对应的请求头来源,最多只保留一个!`)
}
}
}
}
getHeader(field) {
if (typeof field !== 'string') {
return ''
}
Object.keys(this.config.headers).forEach((key) => {
if (key.toUpperCase() === field.toUpperCase()) {
return this.config.headers[key]
}
})
}
removeHeader(field) {
if (typeof field !== 'string') {
return ''
}
Object.keys(this.config.headers).forEach((key) => {
if (key.toUpperCase() === field.toUpperCase()) {
delete this.config.headers[key]
}
})
}
setHeader(field, value) {
this.removeHeader(field)
this.config.headers[field] = value
}
getParam(field) {
return this.config.params[field]
}
setParam(field, value) {
this.config.params[field] = value
}
/**
* 合成打印日志所需的内容
* @returns {object} content 日志内容对象
* @returns {number} content.status 响应状态码
* @returns {string} content.url 请求地址
* @returns {object} content.config 配置项
* @returns {number} content.startTime 发起请求任务时间(时间戳)
* @returns {number} content.endTime 结束请求任务时间(时间戳)
* @returns {number} content.requestTime 本次发起请求时间(时间戳)
* @returns {number} content.responseTime 本次结束响应时间(时间戳)
* @returns {string} content.startTimeText 发起请求任务时间(文本格式)
* @returns {string} content.endTimeText 结束请求任务时间(文本格式)
* @returns {string} content.requestTimeText 本次发起请求时间(文本格式)
* @returns {string} content.responseTimeText 本次结束响应时间(文本格式)
*/
getLoggingContent() {
const ctx = this
return {
status: ctx.response.status,
url: ctx.url,
config: ctx.config,
startTime: ctx.state.startTime,
endTime: ctx.state.endTime,
requestTime: ctx.state.requestTime,
responseTime: ctx.state.responseTime,
startTimeText: ctx.state.startTimeText,
endTimeText: ctx.state.endTimeText,
requestTimeText: ctx.state.requestTimeText,
responseTimeText: ctx.state.responseTimeText,
}
}
}
'use strict'
/**
* 根据环境变量,判断所处的环境类型,选择适配器
*
* 备注:
* 1. `require` 语句不能在顶上提前使用,非特定环境引入模块将会无法运行而报错,只能在确定所处环境后引入
*/
module.exports = function getAdapter() {
// 浏览器环境(各小程序环境把)
/**
* 普通浏览器环境、React Native 环境
*
* 说明:
* 1. 各 `小程序` 环境把 `XMLHttpRequest` 直接禁用了,即
* ```js
* typeof XMLHttpRequest === 'undefined' // true
* ```
*/
if (typeof XMLHttpRequest === 'function') {
return require('../adapters/xhr.js')
}
/**
* Node.js 环境
*/
if (typeof process === 'object' && typeof Buffer === 'function') {
return require('../adapters/node.js')
}
/**
* 微信小程序
*/
if (typeof wx === 'object' && typeof wx.request === 'function') {
return require('../adapters/mini-wx.js')
}
/**
* 支付宝小程序
*/
if (typeof my === 'object' && typeof my.request === 'function') {
return require('../adapters/mini-my.js')
}
/**
* QQ 小程序
*/
if (typeof qq === 'object' && typeof qq.request === 'function') {
return require('../adapters/mini-qq.js')
}
/**
* 字节跳动小程序
*/
if (typeof tt === 'object' && typeof tt.request === 'function') {
return require('../adapters/mini-tt.js')
}
throw new Error('暂时无法识别当前的 Javascript 环境,请使用自定义适配器 `config.adapter` 或联系作者添加当前环境适配器!')
}
'use strict'
const statuses = require('../static/statuses.js')
const STATUS = Symbol('response#status')
const STATUS_TEXT = Symbol('response#statusText')
const HEADERS = Symbol('response#headers')
const DATA = Symbol('response#data')
module.exports = class Response {
constructor(adapterRes) {
this.config = adapterRes.config
this.status = adapterRes.status
this.statusText = adapterRes.statusText
this.headers = adapterRes.headers
this.data = adapterRes.data
this.request = adapterRes.request
}
get status() {
return this[STATUS]
}
set status(value) {
const code = parseInt(value, 10)
if (isNaN(code) || code < 100 || code > 599) {
throw new Error('响应状态码的有效范围是 100 ~ 599,当前为 ' + value)
}
this[STATUS] = code
}
get statusText() {
return this[STATUS_TEXT] || statuses[this.status]
}
set statusText(value) {
if (!value || typeof value !== 'string') {
return
}
this[STATUS_TEXT] = value
}
get headers() {
return this[HEADERS] || {}
}
set headers(value) {
if (typeof value === 'object') {
this[HEADERS] = value
}
}
get data() {
return this[DATA] || null
}
set data(value) {
if (typeof value === 'string' && this.config.responseType === 'json') {
try {
const json = JSON.parse(value)
this[DATA] = json
} catch (e) {
this[DATA] = value
}
} else {
this[DATA] = value
}
}
}
'use strict'
const Response = require('../core/response.js')
/**
* 将请求适配器封装为中间件格式
*/
module.exports = async function dispatch(ctx) {
// 记录发起请求时间
ctx.setTime('requestTime')
const result = await ctx.adapter(ctx.config)
// 记录完成请求时间
ctx.setTime('responseTime')
ctx.response = new Response(result)
ctx.request = result.request
}
'use strict'
/**
* 初始化函数,用于放在第一个中间件
*/
module.exports = async function initialize(ctx, next) {
// 记录本次请求任务开始时间
ctx.setTime('startTime')
await next()
// 记录本次请求任务结束时间
ctx.setTime('endTime')
// 打印日志
if (ctx.config.debug && typeof ctx.config.logging === 'function') {
const content = ctx.getLoggingContent()
ctx.config.logging(content)
}
return {
status: ctx.response.status,
statusText: ctx.response.statusText,
headers: ctx.response.headers,
data: ctx.response.data,
request: ctx.response.request,
url: ctx.url,
config: ctx.config,
}
}
'use strict'
const CryptoJS = require('../min/crypto-js.min.js')
/**
* 获取参与签名的请求头字段
* @param {object} headers 请求头
* @returns {string[]}
*/
function getSignHeaderKeys(headers) {
/** 不参与 Header 签名的请求头 */
const EXCLUDE_SIGN_HEADERS = ['x-ca-signature', 'x-xa-signature-headers', 'accept', 'content-md5', 'content-type', 'date']
const signHeaderKeys = []
Object.keys(headers).forEach((field) => {
if (!EXCLUDE_SIGN_HEADERS.includes(field)) {
signHeaderKeys.push(field)
}
})
return signHeaderKeys.sort()
}
function getSignedHeadersString(signHeaderKeys, headers) {
const list = []
for (let i = 0; i < signHeaderKeys.length; i++) {
const key = signHeaderKeys[i]
const value = headers[key]
list.push(key + ':' + (value ? value : ''))
}
return list.join('\n')
}
function getPathAndParams(url) {
const urlRaw = url.replace('https://', '').replace('http://', '')
return urlRaw.substr(urlRaw.indexOf('/'))
}
function md5(content) {
return CryptoJS.MD5(content).toString(CryptoJS.enc.Base64)
}
function buildStringToSign(method, headers, signedHeadersString, pathAndParams) {
const lf = '\n'
const list = [method.toUpperCase(), lf]
const arr = ['accept', 'content-md5', 'content-type', 'date']
for (let i = 0; i < arr.length; i++) {
const key = arr[i]
if (headers[key]) {
list.push(headers[key])
}
list.push(lf)
}
if (signedHeadersString) {
list.push(signedHeadersString)
list.push(lf)
}
if (pathAndParams) {
list.push(pathAndParams)
}
return list.join('')
}
/**
* 阿里云 API 网关签名加密
* @see https://help.aliyun.com/document_detail/29475.html
*/
module.exports = function getAliyunApigwSignatureMiddleware(options) {
const { key, secret, debug } = options
const appKey = key
const appSecret = secret
return async function aliyunApigwSignature(ctx, next) {
const originHeaders = ctx.config.headers
const url = ctx.url
// 处理请求头
const headers = {}
// 将请求头字段全部处理成 `小写`
Object.keys(originHeaders).forEach((field) => {
if (originHeaders[field]) {
headers[field.toLowerCase()] = originHeaders[field]
}
})
// 给请求头添加一些要求添加的字段
headers['x-ca-key'] = appKey
headers['x-ca-timestamp'] = Date.now()
headers['accept'] = headers['accept'] || '*/*'
headers['content-type'] = headers['content-type'] || 'application/json'
// 该请求头要求为一个随机字符串,理论上使用 `UUID` 更好,为了少引入依赖,使用这种方法
headers['x-ca-nonce'] = CryptoJS.MD5(Date.now().toString() + Math.random() * 10000).toString(CryptoJS.enc.Hex)
if (ctx.config.method !== 'GET' && ctx.config.data) {
headers['content-md5'] = md5(JSON.stringify(ctx.config.data))
}
const signHeaderKeys = getSignHeaderKeys(headers)
headers['x-ca-signature-headers'] = signHeaderKeys.join(',')
const pathAndParams = getPathAndParams(url)
const signedHeadersString = getSignedHeadersString(signHeaderKeys, headers)
const stringToSign = buildStringToSign(ctx.config.method, headers, signedHeadersString, pathAndParams)
headers['x-ca-signature'] = CryptoJS.HmacSHA256(stringToSign, appSecret).toString(CryptoJS.enc.Base64)
if (debug) {
console.log(`当前签名字符串:\`${stringToSign.replace(/\n/g, '#')}\``)
}
ctx.config.headers = headers
await next()
}
}
!function(t,e){"object"==typeof exports?module.exports=exports=e():"function"==typeof define&&define.amd?define([],e):t.CryptoJS=e()}(this,function(){var h,t,e,r,i,n,f,o,s,c,a,l,d,m,x,b,H,z,A,u,p,_,v,y,g,B,w,k,S,C,D,E,R,M,F,P,W,O,I,U,K,X,L,j,N,T,q,Z,V,G,J,$,Q,Y,tt,et,rt,it,nt,ot,st,ct,at,ht,lt,ft,dt,ut,pt,_t,vt,yt,gt,Bt,wt,kt,St,bt=bt||function(l){var t;if("undefined"!=typeof window&&window.crypto&&(t=window.crypto),!t&&"undefined"!=typeof window&&window.msCrypto&&(t=window.msCrypto),!t&&"undefined"!=typeof global&&global.crypto&&(t=global.crypto),!t&&"function"==typeof require)try{t=require("crypto")}catch(t){}function i(){if(t){if("function"==typeof t.getRandomValues)try{return t.getRandomValues(new Uint32Array(1))[0]}catch(t){}if("function"==typeof t.randomBytes)try{return t.randomBytes(4).readInt32LE()}catch(t){}}throw new Error("Native crypto module could not be used to get secure random number.")}var r=Object.create||function(t){var e;return n.prototype=t,e=new n,n.prototype=null,e};function n(){}var e={},o=e.lib={},s=o.Base={extend:function(t){var e=r(this);return t&&e.mixIn(t),e.hasOwnProperty("init")&&this.init!==e.init||(e.init=function(){e.$super.init.apply(this,arguments)}),(e.init.prototype=e).$super=this,e},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}},f=o.WordArray=s.extend({init:function(t,e){t=this.words=t||[],this.sigBytes=null!=e?e:4*t.length},toString:function(t){return(t||a).stringify(this)},concat:function(t){var e=this.words,r=t.words,i=this.sigBytes,n=t.sigBytes;if(this.clamp(),i%4)for(var o=0;o<n;o++){var s=r[o>>>2]>>>24-o%4*8&255;e[i+o>>>2]|=s<<24-(i+o)%4*8}else for(o=0;o<n;o+=4)e[i+o>>>2]=r[o>>>2];return this.sigBytes+=n,this},clamp:function(){var t=this.words,e=this.sigBytes;t[e>>>2]&=4294967295<<32-e%4*8,t.length=l.ceil(e/4)},clone:function(){var t=s.clone.call(this);return t.words=this.words.slice(0),t},random:function(t){for(var e=[],r=0;r<t;r+=4)e.push(i());return new f.init(e,t)}}),c=e.enc={},a=c.Hex={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],n=0;n<r;n++){var o=e[n>>>2]>>>24-n%4*8&255;i.push((o>>>4).toString(16)),i.push((15&o).toString(16))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i+=2)r[i>>>3]|=parseInt(t.substr(i,2),16)<<24-i%8*4;return new f.init(r,e/2)}},h=c.Latin1={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],n=0;n<r;n++){var o=e[n>>>2]>>>24-n%4*8&255;i.push(String.fromCharCode(o))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i++)r[i>>>2]|=(255&t.charCodeAt(i))<<24-i%4*8;return new f.init(r,e)}},d=c.Utf8={stringify:function(t){try{return decodeURIComponent(escape(h.stringify(t)))}catch(t){throw new Error("Malformed UTF-8 data")}},parse:function(t){return h.parse(unescape(encodeURIComponent(t)))}},u=o.BufferedBlockAlgorithm=s.extend({reset:function(){this._data=new f.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=d.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(t){var e,r=this._data,i=r.words,n=r.sigBytes,o=this.blockSize,s=n/(4*o),c=(s=t?l.ceil(s):l.max((0|s)-this._minBufferSize,0))*o,a=l.min(4*c,n);if(c){for(var h=0;h<c;h+=o)this._doProcessBlock(i,h);e=i.splice(0,c),r.sigBytes-=a}return new f.init(e,a)},clone:function(){var t=s.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),p=(o.Hasher=u.extend({cfg:s.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){u.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){return t&&this._append(t),this._doFinalize()},blockSize:16,_createHelper:function(r){return function(t,e){return new r.init(e).finalize(t)}},_createHmacHelper:function(r){return function(t,e){return new p.HMAC.init(r,e).finalize(t)}}}),e.algo={});return e}(Math);function mt(t,e,r){return t^e^r}function xt(t,e,r){return t&e|~t&r}function Ht(t,e,r){return(t|~e)^r}function zt(t,e,r){return t&r|e&~r}function At(t,e,r){return t^(e|~r)}function Ct(t,e){return t<<e|t>>>32-e}function Dt(t,e,r,i){var n,o=this._iv;o?(n=o.slice(0),this._iv=void 0):n=this._prevBlock,i.encryptBlock(n,0);for(var s=0;s<r;s++)t[e+s]^=n[s]}function Et(t){if(255==(t>>24&255)){var e=t>>16&255,r=t>>8&255,i=255&t;255===e?(e=0,255===r?(r=0,255===i?i=0:++i):++r):++e,t=0,t+=e<<16,t+=r<<8,t+=i}else t+=1<<24;return t}function Rt(){for(var t=this._X,e=this._C,r=0;r<8;r++)ft[r]=e[r];e[0]=e[0]+1295307597+this._b|0,e[1]=e[1]+3545052371+(e[0]>>>0<ft[0]>>>0?1:0)|0,e[2]=e[2]+886263092+(e[1]>>>0<ft[1]>>>0?1:0)|0,e[3]=e[3]+1295307597+(e[2]>>>0<ft[2]>>>0?1:0)|0,e[4]=e[4]+3545052371+(e[3]>>>0<ft[3]>>>0?1:0)|0,e[5]=e[5]+886263092+(e[4]>>>0<ft[4]>>>0?1:0)|0,e[6]=e[6]+1295307597+(e[5]>>>0<ft[5]>>>0?1:0)|0,e[7]=e[7]+3545052371+(e[6]>>>0<ft[6]>>>0?1:0)|0,this._b=e[7]>>>0<ft[7]>>>0?1:0;for(r=0;r<8;r++){var i=t[r]+e[r],n=65535&i,o=i>>>16,s=((n*n>>>17)+n*o>>>15)+o*o,c=((4294901760&i)*i|0)+((65535&i)*i|0);dt[r]=s^c}t[0]=dt[0]+(dt[7]<<16|dt[7]>>>16)+(dt[6]<<16|dt[6]>>>16)|0,t[1]=dt[1]+(dt[0]<<8|dt[0]>>>24)+dt[7]|0,t[2]=dt[2]+(dt[1]<<16|dt[1]>>>16)+(dt[0]<<16|dt[0]>>>16)|0,t[3]=dt[3]+(dt[2]<<8|dt[2]>>>24)+dt[1]|0,t[4]=dt[4]+(dt[3]<<16|dt[3]>>>16)+(dt[2]<<16|dt[2]>>>16)|0,t[5]=dt[5]+(dt[4]<<8|dt[4]>>>24)+dt[3]|0,t[6]=dt[6]+(dt[5]<<16|dt[5]>>>16)+(dt[4]<<16|dt[4]>>>16)|0,t[7]=dt[7]+(dt[6]<<8|dt[6]>>>24)+dt[5]|0}function Mt(){for(var t=this._X,e=this._C,r=0;r<8;r++)wt[r]=e[r];e[0]=e[0]+1295307597+this._b|0,e[1]=e[1]+3545052371+(e[0]>>>0<wt[0]>>>0?1:0)|0,e[2]=e[2]+886263092+(e[1]>>>0<wt[1]>>>0?1:0)|0,e[3]=e[3]+1295307597+(e[2]>>>0<wt[2]>>>0?1:0)|0,e[4]=e[4]+3545052371+(e[3]>>>0<wt[3]>>>0?1:0)|0,e[5]=e[5]+886263092+(e[4]>>>0<wt[4]>>>0?1:0)|0,e[6]=e[6]+1295307597+(e[5]>>>0<wt[5]>>>0?1:0)|0,e[7]=e[7]+3545052371+(e[6]>>>0<wt[6]>>>0?1:0)|0,this._b=e[7]>>>0<wt[7]>>>0?1:0;for(r=0;r<8;r++){var i=t[r]+e[r],n=65535&i,o=i>>>16,s=((n*n>>>17)+n*o>>>15)+o*o,c=((4294901760&i)*i|0)+((65535&i)*i|0);kt[r]=s^c}t[0]=kt[0]+(kt[7]<<16|kt[7]>>>16)+(kt[6]<<16|kt[6]>>>16)|0,t[1]=kt[1]+(kt[0]<<8|kt[0]>>>24)+kt[7]|0,t[2]=kt[2]+(kt[1]<<16|kt[1]>>>16)+(kt[0]<<16|kt[0]>>>16)|0,t[3]=kt[3]+(kt[2]<<8|kt[2]>>>24)+kt[1]|0,t[4]=kt[4]+(kt[3]<<16|kt[3]>>>16)+(kt[2]<<16|kt[2]>>>16)|0,t[5]=kt[5]+(kt[4]<<8|kt[4]>>>24)+kt[3]|0,t[6]=kt[6]+(kt[5]<<16|kt[5]>>>16)+(kt[4]<<16|kt[4]>>>16)|0,t[7]=kt[7]+(kt[6]<<8|kt[6]>>>24)+kt[5]|0}return h=bt.lib.WordArray,bt.enc.Base64={stringify:function(t){var e=t.words,r=t.sigBytes,i=this._map;t.clamp();for(var n=[],o=0;o<r;o+=3)for(var s=(e[o>>>2]>>>24-o%4*8&255)<<16|(e[o+1>>>2]>>>24-(o+1)%4*8&255)<<8|e[o+2>>>2]>>>24-(o+2)%4*8&255,c=0;c<4&&o+.75*c<r;c++)n.push(i.charAt(s>>>6*(3-c)&63));var a=i.charAt(64);if(a)for(;n.length%4;)n.push(a);return n.join("")},parse:function(t){var e=t.length,r=this._map,i=this._reverseMap;if(!i){i=this._reverseMap=[];for(var n=0;n<r.length;n++)i[r.charCodeAt(n)]=n}var o=r.charAt(64);if(o){var s=t.indexOf(o);-1!==s&&(e=s)}return function(t,e,r){for(var i=[],n=0,o=0;o<e;o++)if(o%4){var s=r[t.charCodeAt(o-1)]<<o%4*2,c=r[t.charCodeAt(o)]>>>6-o%4*2,a=s|c;i[n>>>2]|=a<<24-n%4*8,n++}return h.create(i,n)}(t,e,i)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="},function(l){var t=bt,e=t.lib,r=e.WordArray,i=e.Hasher,n=t.algo,H=[];!function(){for(var t=0;t<64;t++)H[t]=4294967296*l.abs(l.sin(t+1))|0}();var o=n.MD5=i.extend({_doReset:function(){this._hash=new r.init([1732584193,4023233417,2562383102,271733878])},_doProcessBlock:function(t,e){for(var r=0;r<16;r++){var i=e+r,n=t[i];t[i]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8)}var o=this._hash.words,s=t[e+0],c=t[e+1],a=t[e+2],h=t[e+3],l=t[e+4],f=t[e+5],d=t[e+6],u=t[e+7],p=t[e+8],_=t[e+9],v=t[e+10],y=t[e+11],g=t[e+12],B=t[e+13],w=t[e+14],k=t[e+15],S=o[0],m=o[1],x=o[2],b=o[3];S=z(S,m,x,b,s,7,H[0]),b=z(b,S,m,x,c,12,H[1]),x=z(x,b,S,m,a,17,H[2]),m=z(m,x,b,S,h,22,H[3]),S=z(S,m,x,b,l,7,H[4]),b=z(b,S,m,x,f,12,H[5]),x=z(x,b,S,m,d,17,H[6]),m=z(m,x,b,S,u,22,H[7]),S=z(S,m,x,b,p,7,H[8]),b=z(b,S,m,x,_,12,H[9]),x=z(x,b,S,m,v,17,H[10]),m=z(m,x,b,S,y,22,H[11]),S=z(S,m,x,b,g,7,H[12]),b=z(b,S,m,x,B,12,H[13]),x=z(x,b,S,m,w,17,H[14]),S=A(S,m=z(m,x,b,S,k,22,H[15]),x,b,c,5,H[16]),b=A(b,S,m,x,d,9,H[17]),x=A(x,b,S,m,y,14,H[18]),m=A(m,x,b,S,s,20,H[19]),S=A(S,m,x,b,f,5,H[20]),b=A(b,S,m,x,v,9,H[21]),x=A(x,b,S,m,k,14,H[22]),m=A(m,x,b,S,l,20,H[23]),S=A(S,m,x,b,_,5,H[24]),b=A(b,S,m,x,w,9,H[25]),x=A(x,b,S,m,h,14,H[26]),m=A(m,x,b,S,p,20,H[27]),S=A(S,m,x,b,B,5,H[28]),b=A(b,S,m,x,a,9,H[29]),x=A(x,b,S,m,u,14,H[30]),S=C(S,m=A(m,x,b,S,g,20,H[31]),x,b,f,4,H[32]),b=C(b,S,m,x,p,11,H[33]),x=C(x,b,S,m,y,16,H[34]),m=C(m,x,b,S,w,23,H[35]),S=C(S,m,x,b,c,4,H[36]),b=C(b,S,m,x,l,11,H[37]),x=C(x,b,S,m,u,16,H[38]),m=C(m,x,b,S,v,23,H[39]),S=C(S,m,x,b,B,4,H[40]),b=C(b,S,m,x,s,11,H[41]),x=C(x,b,S,m,h,16,H[42]),m=C(m,x,b,S,d,23,H[43]),S=C(S,m,x,b,_,4,H[44]),b=C(b,S,m,x,g,11,H[45]),x=C(x,b,S,m,k,16,H[46]),S=D(S,m=C(m,x,b,S,a,23,H[47]),x,b,s,6,H[48]),b=D(b,S,m,x,u,10,H[49]),x=D(x,b,S,m,w,15,H[50]),m=D(m,x,b,S,f,21,H[51]),S=D(S,m,x,b,g,6,H[52]),b=D(b,S,m,x,h,10,H[53]),x=D(x,b,S,m,v,15,H[54]),m=D(m,x,b,S,c,21,H[55]),S=D(S,m,x,b,p,6,H[56]),b=D(b,S,m,x,k,10,H[57]),x=D(x,b,S,m,d,15,H[58]),m=D(m,x,b,S,B,21,H[59]),S=D(S,m,x,b,l,6,H[60]),b=D(b,S,m,x,y,10,H[61]),x=D(x,b,S,m,a,15,H[62]),m=D(m,x,b,S,_,21,H[63]),o[0]=o[0]+S|0,o[1]=o[1]+m|0,o[2]=o[2]+x|0,o[3]=o[3]+b|0},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;e[i>>>5]|=128<<24-i%32;var n=l.floor(r/4294967296),o=r;e[15+(64+i>>>9<<4)]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8),e[14+(64+i>>>9<<4)]=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),t.sigBytes=4*(e.length+1),this._process();for(var s=this._hash,c=s.words,a=0;a<4;a++){var h=c[a];c[a]=16711935&(h<<8|h>>>24)|4278255360&(h<<24|h>>>8)}return s},clone:function(){var t=i.clone.call(this);return t._hash=this._hash.clone(),t}});function z(t,e,r,i,n,o,s){var c=t+(e&r|~e&i)+n+s;return(c<<o|c>>>32-o)+e}function A(t,e,r,i,n,o,s){var c=t+(e&i|r&~i)+n+s;return(c<<o|c>>>32-o)+e}function C(t,e,r,i,n,o,s){var c=t+(e^r^i)+n+s;return(c<<o|c>>>32-o)+e}function D(t,e,r,i,n,o,s){var c=t+(r^(e|~i))+n+s;return(c<<o|c>>>32-o)+e}t.MD5=i._createHelper(o),t.HmacMD5=i._createHmacHelper(o)}(Math),e=(t=bt).lib,r=e.WordArray,i=e.Hasher,n=t.algo,f=[],o=n.SHA1=i.extend({_doReset:function(){this._hash=new r.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(t,e){for(var r=this._hash.words,i=r[0],n=r[1],o=r[2],s=r[3],c=r[4],a=0;a<80;a++){if(a<16)f[a]=0|t[e+a];else{var h=f[a-3]^f[a-8]^f[a-14]^f[a-16];f[a]=h<<1|h>>>31}var l=(i<<5|i>>>27)+c+f[a];l+=a<20?1518500249+(n&o|~n&s):a<40?1859775393+(n^o^s):a<60?(n&o|n&s|o&s)-1894007588:(n^o^s)-899497514,c=s,s=o,o=n<<30|n>>>2,n=i,i=l}r[0]=r[0]+i|0,r[1]=r[1]+n|0,r[2]=r[2]+o|0,r[3]=r[3]+s|0,r[4]=r[4]+c|0},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[14+(64+i>>>9<<4)]=Math.floor(r/4294967296),e[15+(64+i>>>9<<4)]=r,t.sigBytes=4*e.length,this._process(),this._hash},clone:function(){var t=i.clone.call(this);return t._hash=this._hash.clone(),t}}),t.SHA1=i._createHelper(o),t.HmacSHA1=i._createHmacHelper(o),function(n){var t=bt,e=t.lib,r=e.WordArray,i=e.Hasher,o=t.algo,s=[],B=[];!function(){function t(t){for(var e=n.sqrt(t),r=2;r<=e;r++)if(!(t%r))return;return 1}function e(t){return 4294967296*(t-(0|t))|0}for(var r=2,i=0;i<64;)t(r)&&(i<8&&(s[i]=e(n.pow(r,.5))),B[i]=e(n.pow(r,1/3)),i++),r++}();var w=[],c=o.SHA256=i.extend({_doReset:function(){this._hash=new r.init(s.slice(0))},_doProcessBlock:function(t,e){for(var r=this._hash.words,i=r[0],n=r[1],o=r[2],s=r[3],c=r[4],a=r[5],h=r[6],l=r[7],f=0;f<64;f++){if(f<16)w[f]=0|t[e+f];else{var d=w[f-15],u=(d<<25|d>>>7)^(d<<14|d>>>18)^d>>>3,p=w[f-2],_=(p<<15|p>>>17)^(p<<13|p>>>19)^p>>>10;w[f]=u+w[f-7]+_+w[f-16]}var v=i&n^i&o^n&o,y=(i<<30|i>>>2)^(i<<19|i>>>13)^(i<<10|i>>>22),g=l+((c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25))+(c&a^~c&h)+B[f]+w[f];l=h,h=a,a=c,c=s+g|0,s=o,o=n,n=i,i=g+(y+v)|0}r[0]=r[0]+i|0,r[1]=r[1]+n|0,r[2]=r[2]+o|0,r[3]=r[3]+s|0,r[4]=r[4]+c|0,r[5]=r[5]+a|0,r[6]=r[6]+h|0,r[7]=r[7]+l|0},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[14+(64+i>>>9<<4)]=n.floor(r/4294967296),e[15+(64+i>>>9<<4)]=r,t.sigBytes=4*e.length,this._process(),this._hash},clone:function(){var t=i.clone.call(this);return t._hash=this._hash.clone(),t}});t.SHA256=i._createHelper(c),t.HmacSHA256=i._createHmacHelper(c)}(Math),function(){var n=bt.lib.WordArray,t=bt.enc;t.Utf16=t.Utf16BE={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],n=0;n<r;n+=2){var o=e[n>>>2]>>>16-n%4*8&65535;i.push(String.fromCharCode(o))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i++)r[i>>>1]|=t.charCodeAt(i)<<16-i%2*16;return n.create(r,2*e)}};function s(t){return t<<8&4278255360|t>>>8&16711935}t.Utf16LE={stringify:function(t){for(var e=t.words,r=t.sigBytes,i=[],n=0;n<r;n+=2){var o=s(e[n>>>2]>>>16-n%4*8&65535);i.push(String.fromCharCode(o))}return i.join("")},parse:function(t){for(var e=t.length,r=[],i=0;i<e;i++)r[i>>>1]|=s(t.charCodeAt(i)<<16-i%2*16);return n.create(r,2*e)}}}(),function(){if("function"==typeof ArrayBuffer){var t=bt.lib.WordArray,n=t.init;(t.init=function(t){if(t instanceof ArrayBuffer&&(t=new Uint8Array(t)),(t instanceof Int8Array||"undefined"!=typeof Uint8ClampedArray&&t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array)&&(t=new Uint8Array(t.buffer,t.byteOffset,t.byteLength)),t instanceof Uint8Array){for(var e=t.byteLength,r=[],i=0;i<e;i++)r[i>>>2]|=t[i]<<24-i%4*8;n.call(this,r,e)}else n.apply(this,arguments)}).prototype=t}}(),Math,c=(s=bt).lib,a=c.WordArray,l=c.Hasher,d=s.algo,m=a.create([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,7,4,13,1,10,6,15,3,12,0,9,5,2,14,11,8,3,10,14,4,9,15,8,1,2,7,0,6,13,11,5,12,1,9,11,10,0,8,12,4,13,3,7,15,14,5,6,2,4,0,5,9,7,12,2,10,14,1,3,8,11,6,15,13]),x=a.create([5,14,7,0,9,2,11,4,13,6,15,8,1,10,3,12,6,11,3,7,0,13,5,10,14,15,8,12,4,9,1,2,15,5,1,3,7,14,6,9,11,8,12,2,10,0,4,13,8,6,4,1,3,11,15,0,5,12,2,13,9,7,10,14,12,15,10,4,1,5,8,7,6,2,13,14,0,3,9,11]),b=a.create([11,14,15,12,5,8,7,9,11,13,14,15,6,7,9,8,7,6,8,13,11,9,7,15,7,12,15,9,11,7,13,12,11,13,6,7,14,9,13,15,14,8,13,6,5,12,7,5,11,12,14,15,14,15,9,8,9,14,5,6,8,6,5,12,9,15,5,11,6,8,13,12,5,12,13,14,11,8,5,6]),H=a.create([8,9,9,11,13,15,15,5,7,7,8,11,14,14,12,6,9,13,15,7,12,8,9,11,7,7,12,7,6,15,13,11,9,7,15,11,8,6,6,14,12,13,5,14,13,13,7,5,15,5,8,11,14,14,6,14,6,9,12,9,12,5,15,8,8,5,12,9,12,5,14,6,8,13,6,5,15,13,11,11]),z=a.create([0,1518500249,1859775393,2400959708,2840853838]),A=a.create([1352829926,1548603684,1836072691,2053994217,0]),u=d.RIPEMD160=l.extend({_doReset:function(){this._hash=a.create([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(t,e){for(var r=0;r<16;r++){var i=e+r,n=t[i];t[i]=16711935&(n<<8|n>>>24)|4278255360&(n<<24|n>>>8)}var o,s,c,a,h,l,f,d,u,p,_,v=this._hash.words,y=z.words,g=A.words,B=m.words,w=x.words,k=b.words,S=H.words;l=o=v[0],f=s=v[1],d=c=v[2],u=a=v[3],p=h=v[4];for(r=0;r<80;r+=1)_=o+t[e+B[r]]|0,_+=r<16?mt(s,c,a)+y[0]:r<32?xt(s,c,a)+y[1]:r<48?Ht(s,c,a)+y[2]:r<64?zt(s,c,a)+y[3]:At(s,c,a)+y[4],_=(_=Ct(_|=0,k[r]))+h|0,o=h,h=a,a=Ct(c,10),c=s,s=_,_=l+t[e+w[r]]|0,_+=r<16?At(f,d,u)+g[0]:r<32?zt(f,d,u)+g[1]:r<48?Ht(f,d,u)+g[2]:r<64?xt(f,d,u)+g[3]:mt(f,d,u)+g[4],_=(_=Ct(_|=0,S[r]))+p|0,l=p,p=u,u=Ct(d,10),d=f,f=_;_=v[1]+c+u|0,v[1]=v[2]+a+p|0,v[2]=v[3]+h+l|0,v[3]=v[4]+o+f|0,v[4]=v[0]+s+d|0,v[0]=_},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;e[i>>>5]|=128<<24-i%32,e[14+(64+i>>>9<<4)]=16711935&(r<<8|r>>>24)|4278255360&(r<<24|r>>>8),t.sigBytes=4*(e.length+1),this._process();for(var n=this._hash,o=n.words,s=0;s<5;s++){var c=o[s];o[s]=16711935&(c<<8|c>>>24)|4278255360&(c<<24|c>>>8)}return n},clone:function(){var t=l.clone.call(this);return t._hash=this._hash.clone(),t}}),s.RIPEMD160=l._createHelper(u),s.HmacRIPEMD160=l._createHmacHelper(u),p=bt.lib.Base,_=bt.enc.Utf8,bt.algo.HMAC=p.extend({init:function(t,e){t=this._hasher=new t.init,"string"==typeof e&&(e=_.parse(e));var r=t.blockSize,i=4*r;e.sigBytes>i&&(e=t.finalize(e)),e.clamp();for(var n=this._oKey=e.clone(),o=this._iKey=e.clone(),s=n.words,c=o.words,a=0;a<r;a++)s[a]^=1549556828,c[a]^=909522486;n.sigBytes=o.sigBytes=i,this.reset()},reset:function(){var t=this._hasher;t.reset(),t.update(this._iKey)},update:function(t){return this._hasher.update(t),this},finalize:function(t){var e=this._hasher,r=e.finalize(t);return e.reset(),e.finalize(this._oKey.clone().concat(r))}}),y=(v=bt).lib,g=y.Base,B=y.WordArray,w=v.algo,k=w.SHA1,S=w.HMAC,C=w.PBKDF2=g.extend({cfg:g.extend({keySize:4,hasher:k,iterations:1}),init:function(t){this.cfg=this.cfg.extend(t)},compute:function(t,e){for(var r=this.cfg,i=S.create(r.hasher,t),n=B.create(),o=B.create([1]),s=n.words,c=o.words,a=r.keySize,h=r.iterations;s.length<a;){var l=i.update(e).finalize(o);i.reset();for(var f=l.words,d=f.length,u=l,p=1;p<h;p++){u=i.finalize(u),i.reset();for(var _=u.words,v=0;v<d;v++)f[v]^=_[v]}n.concat(l),c[0]++}return n.sigBytes=4*a,n}}),v.PBKDF2=function(t,e,r){return C.create(r).compute(t,e)},E=(D=bt).lib,R=E.Base,M=E.WordArray,F=D.algo,P=F.MD5,W=F.EvpKDF=R.extend({cfg:R.extend({keySize:4,hasher:P,iterations:1}),init:function(t){this.cfg=this.cfg.extend(t)},compute:function(t,e){for(var r,i=this.cfg,n=i.hasher.create(),o=M.create(),s=o.words,c=i.keySize,a=i.iterations;s.length<c;){r&&n.update(r),r=n.update(t).finalize(e),n.reset();for(var h=1;h<a;h++)r=n.finalize(r),n.reset();o.concat(r)}return o.sigBytes=4*c,o}}),D.EvpKDF=function(t,e,r){return W.create(r).compute(t,e)},I=(O=bt).lib.WordArray,U=O.algo,K=U.SHA256,X=U.SHA224=K.extend({_doReset:function(){this._hash=new I.init([3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428])},_doFinalize:function(){var t=K._doFinalize.call(this);return t.sigBytes-=4,t}}),O.SHA224=K._createHelper(X),O.HmacSHA224=K._createHmacHelper(X),L=bt.lib,j=L.Base,N=L.WordArray,(T=bt.x64={}).Word=j.extend({init:function(t,e){this.high=t,this.low=e}}),T.WordArray=j.extend({init:function(t,e){t=this.words=t||[],this.sigBytes=null!=e?e:8*t.length},toX32:function(){for(var t=this.words,e=t.length,r=[],i=0;i<e;i++){var n=t[i];r.push(n.high),r.push(n.low)}return N.create(r,this.sigBytes)},clone:function(){for(var t=j.clone.call(this),e=t.words=this.words.slice(0),r=e.length,i=0;i<r;i++)e[i]=e[i].clone();return t}}),function(d){var t=bt,e=t.lib,u=e.WordArray,i=e.Hasher,l=t.x64.Word,r=t.algo,C=[],D=[],E=[];!function(){for(var t=1,e=0,r=0;r<24;r++){C[t+5*e]=(r+1)*(r+2)/2%64;var i=(2*t+3*e)%5;t=e%5,e=i}for(t=0;t<5;t++)for(e=0;e<5;e++)D[t+5*e]=e+(2*t+3*e)%5*5;for(var n=1,o=0;o<24;o++){for(var s=0,c=0,a=0;a<7;a++){if(1&n){var h=(1<<a)-1;h<32?c^=1<<h:s^=1<<h-32}128&n?n=n<<1^113:n<<=1}E[o]=l.create(s,c)}}();var R=[];!function(){for(var t=0;t<25;t++)R[t]=l.create()}();var n=r.SHA3=i.extend({cfg:i.cfg.extend({outputLength:512}),_doReset:function(){for(var t=this._state=[],e=0;e<25;e++)t[e]=new l.init;this.blockSize=(1600-2*this.cfg.outputLength)/32},_doProcessBlock:function(t,e){for(var r=this._state,i=this.blockSize/2,n=0;n<i;n++){var o=t[e+2*n],s=t[e+2*n+1];o=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),s=16711935&(s<<8|s>>>24)|4278255360&(s<<24|s>>>8),(x=r[n]).high^=s,x.low^=o}for(var c=0;c<24;c++){for(var a=0;a<5;a++){for(var h=0,l=0,f=0;f<5;f++){h^=(x=r[a+5*f]).high,l^=x.low}var d=R[a];d.high=h,d.low=l}for(a=0;a<5;a++){var u=R[(a+4)%5],p=R[(a+1)%5],_=p.high,v=p.low;for(h=u.high^(_<<1|v>>>31),l=u.low^(v<<1|_>>>31),f=0;f<5;f++){(x=r[a+5*f]).high^=h,x.low^=l}}for(var y=1;y<25;y++){var g=(x=r[y]).high,B=x.low,w=C[y];l=w<32?(h=g<<w|B>>>32-w,B<<w|g>>>32-w):(h=B<<w-32|g>>>64-w,g<<w-32|B>>>64-w);var k=R[D[y]];k.high=h,k.low=l}var S=R[0],m=r[0];S.high=m.high,S.low=m.low;for(a=0;a<5;a++)for(f=0;f<5;f++){var x=r[y=a+5*f],b=R[y],H=R[(a+1)%5+5*f],z=R[(a+2)%5+5*f];x.high=b.high^~H.high&z.high,x.low=b.low^~H.low&z.low}x=r[0];var A=E[c];x.high^=A.high,x.low^=A.low}},_doFinalize:function(){var t=this._data,e=t.words,r=(this._nDataBytes,8*t.sigBytes),i=32*this.blockSize;e[r>>>5]|=1<<24-r%32,e[(d.ceil((1+r)/i)*i>>>5)-1]|=128,t.sigBytes=4*e.length,this._process();for(var n=this._state,o=this.cfg.outputLength/8,s=o/8,c=[],a=0;a<s;a++){var h=n[a],l=h.high,f=h.low;l=16711935&(l<<8|l>>>24)|4278255360&(l<<24|l>>>8),f=16711935&(f<<8|f>>>24)|4278255360&(f<<24|f>>>8),c.push(f),c.push(l)}return new u.init(c,o)},clone:function(){for(var t=i.clone.call(this),e=t._state=this._state.slice(0),r=0;r<25;r++)e[r]=e[r].clone();return t}});t.SHA3=i._createHelper(n),t.HmacSHA3=i._createHmacHelper(n)}(Math),function(){var t=bt,e=t.lib.Hasher,r=t.x64,i=r.Word,n=r.WordArray,o=t.algo;function s(){return i.create.apply(i,arguments)}var mt=[s(1116352408,3609767458),s(1899447441,602891725),s(3049323471,3964484399),s(3921009573,2173295548),s(961987163,4081628472),s(1508970993,3053834265),s(2453635748,2937671579),s(2870763221,3664609560),s(3624381080,2734883394),s(310598401,1164996542),s(607225278,1323610764),s(1426881987,3590304994),s(1925078388,4068182383),s(2162078206,991336113),s(2614888103,633803317),s(3248222580,3479774868),s(3835390401,2666613458),s(4022224774,944711139),s(264347078,2341262773),s(604807628,2007800933),s(770255983,1495990901),s(1249150122,1856431235),s(1555081692,3175218132),s(1996064986,2198950837),s(2554220882,3999719339),s(2821834349,766784016),s(2952996808,2566594879),s(3210313671,3203337956),s(3336571891,1034457026),s(3584528711,2466948901),s(113926993,3758326383),s(338241895,168717936),s(666307205,1188179964),s(773529912,1546045734),s(1294757372,1522805485),s(1396182291,2643833823),s(1695183700,2343527390),s(1986661051,1014477480),s(2177026350,1206759142),s(2456956037,344077627),s(2730485921,1290863460),s(2820302411,3158454273),s(3259730800,3505952657),s(3345764771,106217008),s(3516065817,3606008344),s(3600352804,1432725776),s(4094571909,1467031594),s(275423344,851169720),s(430227734,3100823752),s(506948616,1363258195),s(659060556,3750685593),s(883997877,3785050280),s(958139571,3318307427),s(1322822218,3812723403),s(1537002063,2003034995),s(1747873779,3602036899),s(1955562222,1575990012),s(2024104815,1125592928),s(2227730452,2716904306),s(2361852424,442776044),s(2428436474,593698344),s(2756734187,3733110249),s(3204031479,2999351573),s(3329325298,3815920427),s(3391569614,3928383900),s(3515267271,566280711),s(3940187606,3454069534),s(4118630271,4000239992),s(116418474,1914138554),s(174292421,2731055270),s(289380356,3203993006),s(460393269,320620315),s(685471733,587496836),s(852142971,1086792851),s(1017036298,365543100),s(1126000580,2618297676),s(1288033470,3409855158),s(1501505948,4234509866),s(1607167915,987167468),s(1816402316,1246189591)],xt=[];!function(){for(var t=0;t<80;t++)xt[t]=s()}();var c=o.SHA512=e.extend({_doReset:function(){this._hash=new n.init([new i.init(1779033703,4089235720),new i.init(3144134277,2227873595),new i.init(1013904242,4271175723),new i.init(2773480762,1595750129),new i.init(1359893119,2917565137),new i.init(2600822924,725511199),new i.init(528734635,4215389547),new i.init(1541459225,327033209)])},_doProcessBlock:function(t,e){for(var r=this._hash.words,i=r[0],n=r[1],o=r[2],s=r[3],c=r[4],a=r[5],h=r[6],l=r[7],f=i.high,d=i.low,u=n.high,p=n.low,_=o.high,v=o.low,y=s.high,g=s.low,B=c.high,w=c.low,k=a.high,S=a.low,m=h.high,x=h.low,b=l.high,H=l.low,z=f,A=d,C=u,D=p,E=_,R=v,M=y,F=g,P=B,W=w,O=k,I=S,U=m,K=x,X=b,L=H,j=0;j<80;j++){var N,T,q=xt[j];if(j<16)T=q.high=0|t[e+2*j],N=q.low=0|t[e+2*j+1];else{var Z=xt[j-15],V=Z.high,G=Z.low,J=(V>>>1|G<<31)^(V>>>8|G<<24)^V>>>7,$=(G>>>1|V<<31)^(G>>>8|V<<24)^(G>>>7|V<<25),Q=xt[j-2],Y=Q.high,tt=Q.low,et=(Y>>>19|tt<<13)^(Y<<3|tt>>>29)^Y>>>6,rt=(tt>>>19|Y<<13)^(tt<<3|Y>>>29)^(tt>>>6|Y<<26),it=xt[j-7],nt=it.high,ot=it.low,st=xt[j-16],ct=st.high,at=st.low;T=(T=(T=J+nt+((N=$+ot)>>>0<$>>>0?1:0))+et+((N+=rt)>>>0<rt>>>0?1:0))+ct+((N+=at)>>>0<at>>>0?1:0),q.high=T,q.low=N}var ht,lt=P&O^~P&U,ft=W&I^~W&K,dt=z&C^z&E^C&E,ut=A&D^A&R^D&R,pt=(z>>>28|A<<4)^(z<<30|A>>>2)^(z<<25|A>>>7),_t=(A>>>28|z<<4)^(A<<30|z>>>2)^(A<<25|z>>>7),vt=(P>>>14|W<<18)^(P>>>18|W<<14)^(P<<23|W>>>9),yt=(W>>>14|P<<18)^(W>>>18|P<<14)^(W<<23|P>>>9),gt=mt[j],Bt=gt.high,wt=gt.low,kt=X+vt+((ht=L+yt)>>>0<L>>>0?1:0),St=_t+ut;X=U,L=K,U=O,K=I,O=P,I=W,P=M+(kt=(kt=(kt=kt+lt+((ht=ht+ft)>>>0<ft>>>0?1:0))+Bt+((ht=ht+wt)>>>0<wt>>>0?1:0))+T+((ht=ht+N)>>>0<N>>>0?1:0))+((W=F+ht|0)>>>0<F>>>0?1:0)|0,M=E,F=R,E=C,R=D,C=z,D=A,z=kt+(pt+dt+(St>>>0<_t>>>0?1:0))+((A=ht+St|0)>>>0<ht>>>0?1:0)|0}d=i.low=d+A,i.high=f+z+(d>>>0<A>>>0?1:0),p=n.low=p+D,n.high=u+C+(p>>>0<D>>>0?1:0),v=o.low=v+R,o.high=_+E+(v>>>0<R>>>0?1:0),g=s.low=g+F,s.high=y+M+(g>>>0<F>>>0?1:0),w=c.low=w+W,c.high=B+P+(w>>>0<W>>>0?1:0),S=a.low=S+I,a.high=k+O+(S>>>0<I>>>0?1:0),x=h.low=x+K,h.high=m+U+(x>>>0<K>>>0?1:0),H=l.low=H+L,l.high=b+X+(H>>>0<L>>>0?1:0)},_doFinalize:function(){var t=this._data,e=t.words,r=8*this._nDataBytes,i=8*t.sigBytes;return e[i>>>5]|=128<<24-i%32,e[30+(128+i>>>10<<5)]=Math.floor(r/4294967296),e[31+(128+i>>>10<<5)]=r,t.sigBytes=4*e.length,this._process(),this._hash.toX32()},clone:function(){var t=e.clone.call(this);return t._hash=this._hash.clone(),t},blockSize:32});t.SHA512=e._createHelper(c),t.HmacSHA512=e._createHmacHelper(c)}(),Z=(q=bt).x64,V=Z.Word,G=Z.WordArray,J=q.algo,$=J.SHA512,Q=J.SHA384=$.extend({_doReset:function(){this._hash=new G.init([new V.init(3418070365,3238371032),new V.init(1654270250,914150663),new V.init(2438529370,812702999),new V.init(355462360,4144912697),new V.init(1731405415,4290775857),new V.init(2394180231,1750603025),new V.init(3675008525,1694076839),new V.init(1203062813,3204075428)])},_doFinalize:function(){var t=$._doFinalize.call(this);return t.sigBytes-=16,t}}),q.SHA384=$._createHelper(Q),q.HmacSHA384=$._createHmacHelper(Q),bt.lib.Cipher||function(){var t=bt,e=t.lib,r=e.Base,a=e.WordArray,i=e.BufferedBlockAlgorithm,n=t.enc,o=(n.Utf8,n.Base64),s=t.algo.EvpKDF,c=e.Cipher=i.extend({cfg:r.extend(),createEncryptor:function(t,e){return this.create(this._ENC_XFORM_MODE,t,e)},createDecryptor:function(t,e){return this.create(this._DEC_XFORM_MODE,t,e)},init:function(t,e,r){this.cfg=this.cfg.extend(r),this._xformMode=t,this._key=e,this.reset()},reset:function(){i.reset.call(this),this._doReset()},process:function(t){return this._append(t),this._process()},finalize:function(t){return t&&this._append(t),this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(i){return{encrypt:function(t,e,r){return h(e).encrypt(i,t,e,r)},decrypt:function(t,e,r){return h(e).decrypt(i,t,e,r)}}}});function h(t){return"string"==typeof t?w:g}e.StreamCipher=c.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var l,f=t.mode={},d=e.BlockCipherMode=r.extend({createEncryptor:function(t,e){return this.Encryptor.create(t,e)},createDecryptor:function(t,e){return this.Decryptor.create(t,e)},init:function(t,e){this._cipher=t,this._iv=e}}),u=f.CBC=((l=d.extend()).Encryptor=l.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize;p.call(this,t,e,i),r.encryptBlock(t,e),this._prevBlock=t.slice(e,e+i)}}),l.Decryptor=l.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,n=t.slice(e,e+i);r.decryptBlock(t,e),p.call(this,t,e,i),this._prevBlock=n}}),l);function p(t,e,r){var i,n=this._iv;n?(i=n,this._iv=void 0):i=this._prevBlock;for(var o=0;o<r;o++)t[e+o]^=i[o]}var _=(t.pad={}).Pkcs7={pad:function(t,e){for(var r=4*e,i=r-t.sigBytes%r,n=i<<24|i<<16|i<<8|i,o=[],s=0;s<i;s+=4)o.push(n);var c=a.create(o,i);t.concat(c)},unpad:function(t){var e=255&t.words[t.sigBytes-1>>>2];t.sigBytes-=e}},v=(e.BlockCipher=c.extend({cfg:c.cfg.extend({mode:u,padding:_}),reset:function(){var t;c.reset.call(this);var e=this.cfg,r=e.iv,i=e.mode;this._xformMode==this._ENC_XFORM_MODE?t=i.createEncryptor:(t=i.createDecryptor,this._minBufferSize=1),this._mode&&this._mode.__creator==t?this._mode.init(this,r&&r.words):(this._mode=t.call(i,this,r&&r.words),this._mode.__creator=t)},_doProcessBlock:function(t,e){this._mode.processBlock(t,e)},_doFinalize:function(){var t,e=this.cfg.padding;return this._xformMode==this._ENC_XFORM_MODE?(e.pad(this._data,this.blockSize),t=this._process(!0)):(t=this._process(!0),e.unpad(t)),t},blockSize:4}),e.CipherParams=r.extend({init:function(t){this.mixIn(t)},toString:function(t){return(t||this.formatter).stringify(this)}})),y=(t.format={}).OpenSSL={stringify:function(t){var e=t.ciphertext,r=t.salt;return(r?a.create([1398893684,1701076831]).concat(r).concat(e):e).toString(o)},parse:function(t){var e,r=o.parse(t),i=r.words;return 1398893684==i[0]&&1701076831==i[1]&&(e=a.create(i.slice(2,4)),i.splice(0,4),r.sigBytes-=16),v.create({ciphertext:r,salt:e})}},g=e.SerializableCipher=r.extend({cfg:r.extend({format:y}),encrypt:function(t,e,r,i){i=this.cfg.extend(i);var n=t.createEncryptor(r,i),o=n.finalize(e),s=n.cfg;return v.create({ciphertext:o,key:r,iv:s.iv,algorithm:t,mode:s.mode,padding:s.padding,blockSize:t.blockSize,formatter:i.format})},decrypt:function(t,e,r,i){return i=this.cfg.extend(i),e=this._parse(e,i.format),t.createDecryptor(r,i).finalize(e.ciphertext)},_parse:function(t,e){return"string"==typeof t?e.parse(t,this):t}}),B=(t.kdf={}).OpenSSL={execute:function(t,e,r,i){i=i||a.random(8);var n=s.create({keySize:e+r}).compute(t,i),o=a.create(n.words.slice(e),4*r);return n.sigBytes=4*e,v.create({key:n,iv:o,salt:i})}},w=e.PasswordBasedCipher=g.extend({cfg:g.cfg.extend({kdf:B}),encrypt:function(t,e,r,i){var n=(i=this.cfg.extend(i)).kdf.execute(r,t.keySize,t.ivSize);i.iv=n.iv;var o=g.encrypt.call(this,t,e,n.key,i);return o.mixIn(n),o},decrypt:function(t,e,r,i){i=this.cfg.extend(i),e=this._parse(e,i.format);var n=i.kdf.execute(r,t.keySize,t.ivSize,e.salt);return i.iv=n.iv,g.decrypt.call(this,t,e,n.key,i)}})}(),bt.mode.CFB=((Y=bt.lib.BlockCipherMode.extend()).Encryptor=Y.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize;Dt.call(this,t,e,i,r),this._prevBlock=t.slice(e,e+i)}}),Y.Decryptor=Y.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,n=t.slice(e,e+i);Dt.call(this,t,e,i,r),this._prevBlock=n}}),Y),bt.mode.ECB=((tt=bt.lib.BlockCipherMode.extend()).Encryptor=tt.extend({processBlock:function(t,e){this._cipher.encryptBlock(t,e)}}),tt.Decryptor=tt.extend({processBlock:function(t,e){this._cipher.decryptBlock(t,e)}}),tt),bt.pad.AnsiX923={pad:function(t,e){var r=t.sigBytes,i=4*e,n=i-r%i,o=r+n-1;t.clamp(),t.words[o>>>2]|=n<<24-o%4*8,t.sigBytes+=n},unpad:function(t){var e=255&t.words[t.sigBytes-1>>>2];t.sigBytes-=e}},bt.pad.Iso10126={pad:function(t,e){var r=4*e,i=r-t.sigBytes%r;t.concat(bt.lib.WordArray.random(i-1)).concat(bt.lib.WordArray.create([i<<24],1))},unpad:function(t){var e=255&t.words[t.sigBytes-1>>>2];t.sigBytes-=e}},bt.pad.Iso97971={pad:function(t,e){t.concat(bt.lib.WordArray.create([2147483648],1)),bt.pad.ZeroPadding.pad(t,e)},unpad:function(t){bt.pad.ZeroPadding.unpad(t),t.sigBytes--}},bt.mode.OFB=(et=bt.lib.BlockCipherMode.extend(),rt=et.Encryptor=et.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,n=this._iv,o=this._keystream;n&&(o=this._keystream=n.slice(0),this._iv=void 0),r.encryptBlock(o,0);for(var s=0;s<i;s++)t[e+s]^=o[s]}}),et.Decryptor=rt,et),bt.pad.NoPadding={pad:function(){},unpad:function(){}},it=bt.lib.CipherParams,nt=bt.enc.Hex,bt.format.Hex={stringify:function(t){return t.ciphertext.toString(nt)},parse:function(t){var e=nt.parse(t);return it.create({ciphertext:e})}},function(){var t=bt,e=t.lib.BlockCipher,r=t.algo,h=[],l=[],f=[],d=[],u=[],p=[],_=[],v=[],y=[],g=[];!function(){for(var t=[],e=0;e<256;e++)t[e]=e<128?e<<1:e<<1^283;var r=0,i=0;for(e=0;e<256;e++){var n=i^i<<1^i<<2^i<<3^i<<4;n=n>>>8^255&n^99,h[r]=n;var o=t[l[n]=r],s=t[o],c=t[s],a=257*t[n]^16843008*n;f[r]=a<<24|a>>>8,d[r]=a<<16|a>>>16,u[r]=a<<8|a>>>24,p[r]=a;a=16843009*c^65537*s^257*o^16843008*r;_[n]=a<<24|a>>>8,v[n]=a<<16|a>>>16,y[n]=a<<8|a>>>24,g[n]=a,r?(r=o^t[t[t[c^o]]],i^=t[t[i]]):r=i=1}}();var B=[0,1,2,4,8,16,32,64,128,27,54],i=r.AES=e.extend({_doReset:function(){if(!this._nRounds||this._keyPriorReset!==this._key){for(var t=this._keyPriorReset=this._key,e=t.words,r=t.sigBytes/4,i=4*(1+(this._nRounds=6+r)),n=this._keySchedule=[],o=0;o<i;o++)o<r?n[o]=e[o]:(a=n[o-1],o%r?6<r&&o%r==4&&(a=h[a>>>24]<<24|h[a>>>16&255]<<16|h[a>>>8&255]<<8|h[255&a]):(a=h[(a=a<<8|a>>>24)>>>24]<<24|h[a>>>16&255]<<16|h[a>>>8&255]<<8|h[255&a],a^=B[o/r|0]<<24),n[o]=n[o-r]^a);for(var s=this._invKeySchedule=[],c=0;c<i;c++){o=i-c;if(c%4)var a=n[o];else a=n[o-4];s[c]=c<4||o<=4?a:_[h[a>>>24]]^v[h[a>>>16&255]]^y[h[a>>>8&255]]^g[h[255&a]]}}},encryptBlock:function(t,e){this._doCryptBlock(t,e,this._keySchedule,f,d,u,p,h)},decryptBlock:function(t,e){var r=t[e+1];t[e+1]=t[e+3],t[e+3]=r,this._doCryptBlock(t,e,this._invKeySchedule,_,v,y,g,l);r=t[e+1];t[e+1]=t[e+3],t[e+3]=r},_doCryptBlock:function(t,e,r,i,n,o,s,c){for(var a=this._nRounds,h=t[e]^r[0],l=t[e+1]^r[1],f=t[e+2]^r[2],d=t[e+3]^r[3],u=4,p=1;p<a;p++){var _=i[h>>>24]^n[l>>>16&255]^o[f>>>8&255]^s[255&d]^r[u++],v=i[l>>>24]^n[f>>>16&255]^o[d>>>8&255]^s[255&h]^r[u++],y=i[f>>>24]^n[d>>>16&255]^o[h>>>8&255]^s[255&l]^r[u++],g=i[d>>>24]^n[h>>>16&255]^o[l>>>8&255]^s[255&f]^r[u++];h=_,l=v,f=y,d=g}_=(c[h>>>24]<<24|c[l>>>16&255]<<16|c[f>>>8&255]<<8|c[255&d])^r[u++],v=(c[l>>>24]<<24|c[f>>>16&255]<<16|c[d>>>8&255]<<8|c[255&h])^r[u++],y=(c[f>>>24]<<24|c[d>>>16&255]<<16|c[h>>>8&255]<<8|c[255&l])^r[u++],g=(c[d>>>24]<<24|c[h>>>16&255]<<16|c[l>>>8&255]<<8|c[255&f])^r[u++];t[e]=_,t[e+1]=v,t[e+2]=y,t[e+3]=g},keySize:8});t.AES=e._createHelper(i)}(),function(){var t=bt,e=t.lib,n=e.WordArray,r=e.BlockCipher,i=t.algo,h=[57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4],l=[14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32],f=[1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28],d=[{0:8421888,268435456:32768,536870912:8421378,805306368:2,1073741824:512,1342177280:8421890,1610612736:8389122,1879048192:8388608,2147483648:514,2415919104:8389120,2684354560:33280,2952790016:8421376,3221225472:32770,3489660928:8388610,3758096384:0,4026531840:33282,134217728:0,402653184:8421890,671088640:33282,939524096:32768,1207959552:8421888,1476395008:512,1744830464:8421378,2013265920:2,2281701376:8389120,2550136832:33280,2818572288:8421376,3087007744:8389122,3355443200:8388610,3623878656:32770,3892314112:514,4160749568:8388608,1:32768,268435457:2,536870913:8421888,805306369:8388608,1073741825:8421378,1342177281:33280,1610612737:512,1879048193:8389122,2147483649:8421890,2415919105:8421376,2684354561:8388610,2952790017:33282,3221225473:514,3489660929:8389120,3758096385:32770,4026531841:0,134217729:8421890,402653185:8421376,671088641:8388608,939524097:512,1207959553:32768,1476395009:8388610,1744830465:2,2013265921:33282,2281701377:32770,2550136833:8389122,2818572289:514,3087007745:8421888,3355443201:8389120,3623878657:0,3892314113:33280,4160749569:8421378},{0:1074282512,16777216:16384,33554432:524288,50331648:1074266128,67108864:1073741840,83886080:1074282496,100663296:1073758208,117440512:16,134217728:540672,150994944:1073758224,167772160:1073741824,184549376:540688,201326592:524304,218103808:0,234881024:16400,251658240:1074266112,8388608:1073758208,25165824:540688,41943040:16,58720256:1073758224,75497472:1074282512,92274688:1073741824,109051904:524288,125829120:1074266128,142606336:524304,159383552:0,176160768:16384,192937984:1074266112,209715200:1073741840,226492416:540672,243269632:1074282496,260046848:16400,268435456:0,285212672:1074266128,301989888:1073758224,318767104:1074282496,335544320:1074266112,352321536:16,369098752:540688,385875968:16384,402653184:16400,419430400:524288,436207616:524304,452984832:1073741840,469762048:540672,486539264:1073758208,503316480:1073741824,520093696:1074282512,276824064:540688,293601280:524288,310378496:1074266112,327155712:16384,343932928:1073758208,360710144:1074282512,377487360:16,394264576:1073741824,411041792:1074282496,427819008:1073741840,444596224:1073758224,461373440:524304,478150656:0,494927872:16400,511705088:1074266128,528482304:540672},{0:260,1048576:0,2097152:67109120,3145728:65796,4194304:65540,5242880:67108868,6291456:67174660,7340032:67174400,8388608:67108864,9437184:67174656,10485760:65792,11534336:67174404,12582912:67109124,13631488:65536,14680064:4,15728640:256,524288:67174656,1572864:67174404,2621440:0,3670016:67109120,4718592:67108868,5767168:65536,6815744:65540,7864320:260,8912896:4,9961472:256,11010048:67174400,12058624:65796,13107200:65792,14155776:67109124,15204352:67174660,16252928:67108864,16777216:67174656,17825792:65540,18874368:65536,19922944:67109120,20971520:256,22020096:67174660,23068672:67108868,24117248:0,25165824:67109124,26214400:67108864,27262976:4,28311552:65792,29360128:67174400,30408704:260,31457280:65796,32505856:67174404,17301504:67108864,18350080:260,19398656:67174656,20447232:0,21495808:65540,22544384:67109120,23592960:256,24641536:67174404,25690112:65536,26738688:67174660,27787264:65796,28835840:67108868,29884416:67109124,30932992:67174400,31981568:4,33030144:65792},{0:2151682048,65536:2147487808,131072:4198464,196608:2151677952,262144:0,327680:4198400,393216:2147483712,458752:4194368,524288:2147483648,589824:4194304,655360:64,720896:2147487744,786432:2151678016,851968:4160,917504:4096,983040:2151682112,32768:2147487808,98304:64,163840:2151678016,229376:2147487744,294912:4198400,360448:2151682112,425984:0,491520:2151677952,557056:4096,622592:2151682048,688128:4194304,753664:4160,819200:2147483648,884736:4194368,950272:4198464,1015808:2147483712,1048576:4194368,1114112:4198400,1179648:2147483712,1245184:0,1310720:4160,1376256:2151678016,1441792:2151682048,1507328:2147487808,1572864:2151682112,1638400:2147483648,1703936:2151677952,1769472:4198464,1835008:2147487744,1900544:4194304,1966080:64,2031616:4096,1081344:2151677952,1146880:2151682112,1212416:0,1277952:4198400,1343488:4194368,1409024:2147483648,1474560:2147487808,1540096:64,1605632:2147483712,1671168:4096,1736704:2147487744,1802240:2151678016,1867776:4160,1933312:2151682048,1998848:4194304,2064384:4198464},{0:128,4096:17039360,8192:262144,12288:536870912,16384:537133184,20480:16777344,24576:553648256,28672:262272,32768:16777216,36864:537133056,40960:536871040,45056:553910400,49152:553910272,53248:0,57344:17039488,61440:553648128,2048:17039488,6144:553648256,10240:128,14336:17039360,18432:262144,22528:537133184,26624:553910272,30720:536870912,34816:537133056,38912:0,43008:553910400,47104:16777344,51200:536871040,55296:553648128,59392:16777216,63488:262272,65536:262144,69632:128,73728:536870912,77824:553648256,81920:16777344,86016:553910272,90112:537133184,94208:16777216,98304:553910400,102400:553648128,106496:17039360,110592:537133056,114688:262272,118784:536871040,122880:0,126976:17039488,67584:553648256,71680:16777216,75776:17039360,79872:537133184,83968:536870912,88064:17039488,92160:128,96256:553910272,100352:262272,104448:553910400,108544:0,112640:553648128,116736:16777344,120832:262144,124928:537133056,129024:536871040},{0:268435464,256:8192,512:270532608,768:270540808,1024:268443648,1280:2097152,1536:2097160,1792:268435456,2048:0,2304:268443656,2560:2105344,2816:8,3072:270532616,3328:2105352,3584:8200,3840:270540800,128:270532608,384:270540808,640:8,896:2097152,1152:2105352,1408:268435464,1664:268443648,1920:8200,2176:2097160,2432:8192,2688:268443656,2944:270532616,3200:0,3456:270540800,3712:2105344,3968:268435456,4096:268443648,4352:270532616,4608:270540808,4864:8200,5120:2097152,5376:268435456,5632:268435464,5888:2105344,6144:2105352,6400:0,6656:8,6912:270532608,7168:8192,7424:268443656,7680:270540800,7936:2097160,4224:8,4480:2105344,4736:2097152,4992:268435464,5248:268443648,5504:8200,5760:270540808,6016:270532608,6272:270540800,6528:270532616,6784:8192,7040:2105352,7296:2097160,7552:0,7808:268435456,8064:268443656},{0:1048576,16:33555457,32:1024,48:1049601,64:34604033,80:0,96:1,112:34603009,128:33555456,144:1048577,160:33554433,176:34604032,192:34603008,208:1025,224:1049600,240:33554432,8:34603009,24:0,40:33555457,56:34604032,72:1048576,88:33554433,104:33554432,120:1025,136:1049601,152:33555456,168:34603008,184:1048577,200:1024,216:34604033,232:1,248:1049600,256:33554432,272:1048576,288:33555457,304:34603009,320:1048577,336:33555456,352:34604032,368:1049601,384:1025,400:34604033,416:1049600,432:1,448:0,464:34603008,480:33554433,496:1024,264:1049600,280:33555457,296:34603009,312:1,328:33554432,344:1048576,360:1025,376:34604032,392:33554433,408:34603008,424:0,440:34604033,456:1049601,472:1024,488:33555456,504:1048577},{0:134219808,1:131072,2:134217728,3:32,4:131104,5:134350880,6:134350848,7:2048,8:134348800,9:134219776,10:133120,11:134348832,12:2080,13:0,14:134217760,15:133152,2147483648:2048,2147483649:134350880,2147483650:134219808,2147483651:134217728,2147483652:134348800,2147483653:133120,2147483654:133152,2147483655:32,2147483656:134217760,2147483657:2080,2147483658:131104,2147483659:134350848,2147483660:0,2147483661:134348832,2147483662:134219776,2147483663:131072,16:133152,17:134350848,18:32,19:2048,20:134219776,21:134217760,22:134348832,23:131072,24:0,25:131104,26:134348800,27:134219808,28:134350880,29:133120,30:2080,31:134217728,2147483664:131072,2147483665:2048,2147483666:134348832,2147483667:133152,2147483668:32,2147483669:134348800,2147483670:134217728,2147483671:134219808,2147483672:134350880,2147483673:134217760,2147483674:134219776,2147483675:0,2147483676:133120,2147483677:2080,2147483678:131104,2147483679:134350848}],u=[4160749569,528482304,33030144,2064384,129024,8064,504,2147483679],o=i.DES=r.extend({_doReset:function(){for(var t=this._key.words,e=[],r=0;r<56;r++){var i=h[r]-1;e[r]=t[i>>>5]>>>31-i%32&1}for(var n=this._subKeys=[],o=0;o<16;o++){var s=n[o]=[],c=f[o];for(r=0;r<24;r++)s[r/6|0]|=e[(l[r]-1+c)%28]<<31-r%6,s[4+(r/6|0)]|=e[28+(l[r+24]-1+c)%28]<<31-r%6;s[0]=s[0]<<1|s[0]>>>31;for(r=1;r<7;r++)s[r]=s[r]>>>4*(r-1)+3;s[7]=s[7]<<5|s[7]>>>27}var a=this._invSubKeys=[];for(r=0;r<16;r++)a[r]=n[15-r]},encryptBlock:function(t,e){this._doCryptBlock(t,e,this._subKeys)},decryptBlock:function(t,e){this._doCryptBlock(t,e,this._invSubKeys)},_doCryptBlock:function(t,e,r){this._lBlock=t[e],this._rBlock=t[e+1],p.call(this,4,252645135),p.call(this,16,65535),_.call(this,2,858993459),_.call(this,8,16711935),p.call(this,1,1431655765);for(var i=0;i<16;i++){for(var n=r[i],o=this._lBlock,s=this._rBlock,c=0,a=0;a<8;a++)c|=d[a][((s^n[a])&u[a])>>>0];this._lBlock=s,this._rBlock=o^c}var h=this._lBlock;this._lBlock=this._rBlock,this._rBlock=h,p.call(this,1,1431655765),_.call(this,8,16711935),_.call(this,2,858993459),p.call(this,16,65535),p.call(this,4,252645135),t[e]=this._lBlock,t[e+1]=this._rBlock},keySize:2,ivSize:2,blockSize:2});function p(t,e){var r=(this._lBlock>>>t^this._rBlock)&e;this._rBlock^=r,this._lBlock^=r<<t}function _(t,e){var r=(this._rBlock>>>t^this._lBlock)&e;this._lBlock^=r,this._rBlock^=r<<t}t.DES=r._createHelper(o);var s=i.TripleDES=r.extend({_doReset:function(){var t=this._key.words;if(2!==t.length&&4!==t.length&&t.length<6)throw new Error("Invalid key length - 3DES requires the key length to be 64, 128, 192 or >192.");var e=t.slice(0,2),r=t.length<4?t.slice(0,2):t.slice(2,4),i=t.length<6?t.slice(0,2):t.slice(4,6);this._des1=o.createEncryptor(n.create(e)),this._des2=o.createEncryptor(n.create(r)),this._des3=o.createEncryptor(n.create(i))},encryptBlock:function(t,e){this._des1.encryptBlock(t,e),this._des2.decryptBlock(t,e),this._des3.encryptBlock(t,e)},decryptBlock:function(t,e){this._des3.decryptBlock(t,e),this._des2.encryptBlock(t,e),this._des1.decryptBlock(t,e)},keySize:6,ivSize:2,blockSize:2});t.TripleDES=r._createHelper(s)}(),function(){var t=bt,e=t.lib.StreamCipher,r=t.algo,i=r.RC4=e.extend({_doReset:function(){for(var t=this._key,e=t.words,r=t.sigBytes,i=this._S=[],n=0;n<256;n++)i[n]=n;n=0;for(var o=0;n<256;n++){var s=n%r,c=e[s>>>2]>>>24-s%4*8&255;o=(o+i[n]+c)%256;var a=i[n];i[n]=i[o],i[o]=a}this._i=this._j=0},_doProcessBlock:function(t,e){t[e]^=n.call(this)},keySize:8,ivSize:0});function n(){for(var t=this._S,e=this._i,r=this._j,i=0,n=0;n<4;n++){r=(r+t[e=(e+1)%256])%256;var o=t[e];t[e]=t[r],t[r]=o,i|=t[(t[e]+t[r])%256]<<24-8*n}return this._i=e,this._j=r,i}t.RC4=e._createHelper(i);var o=r.RC4Drop=i.extend({cfg:i.cfg.extend({drop:192}),_doReset:function(){i._doReset.call(this);for(var t=this.cfg.drop;0<t;t--)n.call(this)}});t.RC4Drop=e._createHelper(o)}(),bt.mode.CTRGladman=(ot=bt.lib.BlockCipherMode.extend(),st=ot.Encryptor=ot.extend({processBlock:function(t,e){var r,i=this._cipher,n=i.blockSize,o=this._iv,s=this._counter;o&&(s=this._counter=o.slice(0),this._iv=void 0),0===((r=s)[0]=Et(r[0]))&&(r[1]=Et(r[1]));var c=s.slice(0);i.encryptBlock(c,0);for(var a=0;a<n;a++)t[e+a]^=c[a]}}),ot.Decryptor=st,ot),at=(ct=bt).lib.StreamCipher,ht=ct.algo,lt=[],ft=[],dt=[],ut=ht.Rabbit=at.extend({_doReset:function(){for(var t=this._key.words,e=this.cfg.iv,r=0;r<4;r++)t[r]=16711935&(t[r]<<8|t[r]>>>24)|4278255360&(t[r]<<24|t[r]>>>8);var i=this._X=[t[0],t[3]<<16|t[2]>>>16,t[1],t[0]<<16|t[3]>>>16,t[2],t[1]<<16|t[0]>>>16,t[3],t[2]<<16|t[1]>>>16],n=this._C=[t[2]<<16|t[2]>>>16,4294901760&t[0]|65535&t[1],t[3]<<16|t[3]>>>16,4294901760&t[1]|65535&t[2],t[0]<<16|t[0]>>>16,4294901760&t[2]|65535&t[3],t[1]<<16|t[1]>>>16,4294901760&t[3]|65535&t[0]];for(r=this._b=0;r<4;r++)Rt.call(this);for(r=0;r<8;r++)n[r]^=i[r+4&7];if(e){var o=e.words,s=o[0],c=o[1],a=16711935&(s<<8|s>>>24)|4278255360&(s<<24|s>>>8),h=16711935&(c<<8|c>>>24)|4278255360&(c<<24|c>>>8),l=a>>>16|4294901760&h,f=h<<16|65535&a;n[0]^=a,n[1]^=l,n[2]^=h,n[3]^=f,n[4]^=a,n[5]^=l,n[6]^=h,n[7]^=f;for(r=0;r<4;r++)Rt.call(this)}},_doProcessBlock:function(t,e){var r=this._X;Rt.call(this),lt[0]=r[0]^r[5]>>>16^r[3]<<16,lt[1]=r[2]^r[7]>>>16^r[5]<<16,lt[2]=r[4]^r[1]>>>16^r[7]<<16,lt[3]=r[6]^r[3]>>>16^r[1]<<16;for(var i=0;i<4;i++)lt[i]=16711935&(lt[i]<<8|lt[i]>>>24)|4278255360&(lt[i]<<24|lt[i]>>>8),t[e+i]^=lt[i]},blockSize:4,ivSize:2}),ct.Rabbit=at._createHelper(ut),bt.mode.CTR=(pt=bt.lib.BlockCipherMode.extend(),_t=pt.Encryptor=pt.extend({processBlock:function(t,e){var r=this._cipher,i=r.blockSize,n=this._iv,o=this._counter;n&&(o=this._counter=n.slice(0),this._iv=void 0);var s=o.slice(0);r.encryptBlock(s,0),o[i-1]=o[i-1]+1|0;for(var c=0;c<i;c++)t[e+c]^=s[c]}}),pt.Decryptor=_t,pt),yt=(vt=bt).lib.StreamCipher,gt=vt.algo,Bt=[],wt=[],kt=[],St=gt.RabbitLegacy=yt.extend({_doReset:function(){for(var t=this._key.words,e=this.cfg.iv,r=this._X=[t[0],t[3]<<16|t[2]>>>16,t[1],t[0]<<16|t[3]>>>16,t[2],t[1]<<16|t[0]>>>16,t[3],t[2]<<16|t[1]>>>16],i=this._C=[t[2]<<16|t[2]>>>16,4294901760&t[0]|65535&t[1],t[3]<<16|t[3]>>>16,4294901760&t[1]|65535&t[2],t[0]<<16|t[0]>>>16,4294901760&t[2]|65535&t[3],t[1]<<16|t[1]>>>16,4294901760&t[3]|65535&t[0]],n=this._b=0;n<4;n++)Mt.call(this);for(n=0;n<8;n++)i[n]^=r[n+4&7];if(e){var o=e.words,s=o[0],c=o[1],a=16711935&(s<<8|s>>>24)|4278255360&(s<<24|s>>>8),h=16711935&(c<<8|c>>>24)|4278255360&(c<<24|c>>>8),l=a>>>16|4294901760&h,f=h<<16|65535&a;i[0]^=a,i[1]^=l,i[2]^=h,i[3]^=f,i[4]^=a,i[5]^=l,i[6]^=h,i[7]^=f;for(n=0;n<4;n++)Mt.call(this)}},_doProcessBlock:function(t,e){var r=this._X;Mt.call(this),Bt[0]=r[0]^r[5]>>>16^r[3]<<16,Bt[1]=r[2]^r[7]>>>16^r[5]<<16,Bt[2]=r[4]^r[1]>>>16^r[7]<<16,Bt[3]=r[6]^r[3]>>>16^r[1]<<16;for(var i=0;i<4;i++)Bt[i]=16711935&(Bt[i]<<8|Bt[i]>>>24)|4278255360&(Bt[i]<<24|Bt[i]>>>8),t[e+i]^=Bt[i]},blockSize:4,ivSize:2}),vt.RabbitLegacy=yt._createHelper(St),bt.pad.ZeroPadding={pad:function(t,e){var r=4*e;t.clamp(),t.sigBytes+=r-(t.sigBytes%r||r)},unpad:function(t){var e=t.words,r=t.sigBytes-1;for(r=t.sigBytes-1;0<=r;r--)if(e[r>>>2]>>>24-r%4*8&255){t.sigBytes=r+1;break}}},bt});
'use strict'
/**
* 所有 HTTP 请求方法合法值
* From http.METHODS
* @see https://nodejs.org/api/http.html#http_http_methods
*/
const ALL_METHODS = [
'ACL',
'BIND',
'CHECKOUT',
'CONNECT',
'COPY',
'DELETE',
'GET',
'HEAD',
'LINK',
'LOCK',
'M-SEARCH',
'MERGE',
'MKACTIVITY',
'MKCALENDAR',
'MKCOL',
'MOVE',
'NOTIFY',
'OPTIONS',
'PATCH',
'POST',
'PROPFIND',
'PROPPATCH',
'PURGE',
'PUT',
'REBIND',
'REPORT',
'SEARCH',
'SOURCE',
'SUBSCRIBE',
'TRACE',
'UNBIND',
'UNLINK',
'UNLOCK',
'UNSUBSCRIBE',
]
/**
* 常用方法
*/
const COMMON_METHODS = ['GET', 'POST', 'PATCH', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']
module.exports = ALL_METHODS