initital commit
@@ -0,0 +1,19 @@
|
||||
// app.js
|
||||
App({
|
||||
onLaunch() {
|
||||
// 展示本地存储能力
|
||||
const logs = wx.getStorageSync('logs') || []
|
||||
logs.unshift(Date.now())
|
||||
wx.setStorageSync('logs', logs)
|
||||
|
||||
// 登录
|
||||
wx.login({
|
||||
success: res => {
|
||||
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||
}
|
||||
})
|
||||
},
|
||||
globalData: {
|
||||
userInfo: null
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"pages":[
|
||||
"pages/notice/notice",
|
||||
"pages/project/project",
|
||||
"pages/meeting/meeting",
|
||||
"pages/mine/mine",
|
||||
"pages/index/index",
|
||||
"pages/logs/logs"
|
||||
],
|
||||
"window":{
|
||||
"backgroundTextStyle":"light",
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "Weixin",
|
||||
"navigationBarTextStyle":"black"
|
||||
},
|
||||
"tabBar": {
|
||||
"selectedColor": "#08A09A",
|
||||
"color": "#999",
|
||||
"backgroundColor": "#fff",
|
||||
"list": [
|
||||
{
|
||||
"text": "消息",
|
||||
"pagePath": "pages/notice/notice",
|
||||
"iconPath": "./assets/images/notice.png",
|
||||
"selectedIconPath": "./assets/images/notice-active.png"
|
||||
},
|
||||
{
|
||||
"text": "项目",
|
||||
"pagePath": "pages/project/project",
|
||||
"iconPath": "./assets/images/project.png",
|
||||
"selectedIconPath": "./assets/images/project-active.png"
|
||||
},
|
||||
{
|
||||
"text": "会议",
|
||||
"pagePath": "pages/meeting/meeting",
|
||||
"iconPath": "./assets/images/meeting.png",
|
||||
"selectedIconPath": "./assets/images/meeting-active.png"
|
||||
},
|
||||
{
|
||||
"text": "我的",
|
||||
"pagePath": "pages/mine/mine",
|
||||
"iconPath": "./assets/images/mine.png",
|
||||
"selectedIconPath": "./assets/images/mine-active.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"style": "v2",
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**app.wxss**/
|
||||
.container {
|
||||
background-color: #f5f5f5;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
@import './assets/css/common.wxss';
|
||||
@import '/assets/font/iconfont.wxss';
|
||||
@@ -0,0 +1,770 @@
|
||||
page {
|
||||
overflow-x: hidden;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
page::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 2rpx;
|
||||
background-color: #E5E6EA;
|
||||
z-index: 9999;
|
||||
}
|
||||
.container{
|
||||
overflow-x: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.bg_fff{
|
||||
background-color: #fff;
|
||||
}
|
||||
.bg_d{
|
||||
background-color: #00b3c7;
|
||||
}
|
||||
.cd {
|
||||
color: #65A6FF;
|
||||
}
|
||||
.cb{
|
||||
color: #4DA8FF;
|
||||
}
|
||||
.cg {
|
||||
color: #AB9985;
|
||||
}
|
||||
.cw {
|
||||
color: #fff;
|
||||
}
|
||||
.c6{
|
||||
color: #666666;
|
||||
}
|
||||
.cc{
|
||||
color: #CCCCCC;
|
||||
}
|
||||
.c9{
|
||||
color:#999999;
|
||||
}
|
||||
.a2{
|
||||
color: #2A2A2A;
|
||||
}
|
||||
.hover-default {
|
||||
opacity: 0.8;
|
||||
}
|
||||
.button {
|
||||
position: relative;
|
||||
}
|
||||
.button button {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
}
|
||||
.button.primary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #00b3c7;
|
||||
border-radius: 8rpx;
|
||||
color: #fff;
|
||||
}
|
||||
.button.disable {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #EBEBED;
|
||||
border-radius: 8rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.dn {
|
||||
display: none;
|
||||
}
|
||||
.di {
|
||||
display: inline;
|
||||
}
|
||||
.db {
|
||||
display: block;
|
||||
}
|
||||
.w100 {
|
||||
width: 100%;
|
||||
}
|
||||
.h100 {
|
||||
height: 100%;
|
||||
}
|
||||
.dib {
|
||||
display: inline-block;
|
||||
}
|
||||
.box_bb {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.lh14 {
|
||||
line-height: 14rpx;
|
||||
}
|
||||
.lh16 {
|
||||
line-height: 16rpx;
|
||||
}
|
||||
.lh18 {
|
||||
line-height: 18rpx;
|
||||
}
|
||||
.lh20 {
|
||||
line-height: 20rpx;
|
||||
}
|
||||
.lh22 {
|
||||
line-height: 22rpx;
|
||||
}
|
||||
.lh24 {
|
||||
line-height: 24rpx;
|
||||
}
|
||||
.lh28 {
|
||||
line-height: 28rpx;
|
||||
}
|
||||
.lh40 {
|
||||
line-height: 40rpx;
|
||||
}
|
||||
.m0 {
|
||||
margin: 0;
|
||||
}
|
||||
.m5 {
|
||||
margin: 5rpx;
|
||||
}
|
||||
.m10 {
|
||||
margin: 10rpx;
|
||||
}
|
||||
.m15 {
|
||||
margin: 15rpx;
|
||||
}
|
||||
.m20 {
|
||||
margin: 20rpx;
|
||||
}
|
||||
.m25 {
|
||||
margin: 25rpx;
|
||||
}
|
||||
.m30 {
|
||||
margin: 30rpx;
|
||||
}
|
||||
.mla {
|
||||
margin-left: auto;
|
||||
}
|
||||
.ml1 {
|
||||
margin-left: 1rpx;
|
||||
}
|
||||
.ml2 {
|
||||
margin-left: 2rpx;
|
||||
}
|
||||
.ml5 {
|
||||
margin-left: 5rpx;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
.ml15 {
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
.ml20 {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
.ml25 {
|
||||
margin-left: 25rpx;
|
||||
}
|
||||
.ml30 {
|
||||
margin-left: 30rpx;
|
||||
}
|
||||
.mra {
|
||||
margin-right: auto;
|
||||
}
|
||||
.mr1 {
|
||||
margin-right: 1rpx;
|
||||
}
|
||||
.mr2 {
|
||||
margin-right: 2rpx;
|
||||
}
|
||||
.mr5 {
|
||||
margin-right: 5rpx;
|
||||
}
|
||||
.mr10 {
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
.mr15 {
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
.mr20 {
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.mr25 {
|
||||
margin-right: 25rpx;
|
||||
}
|
||||
.mr30 {
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
.mr-10 {
|
||||
margin-right: -10rpx;
|
||||
}
|
||||
.mr-15 {
|
||||
margin-right: -15rpx;
|
||||
}
|
||||
.mta {
|
||||
margin-top: auto;
|
||||
}
|
||||
.mt1 {
|
||||
margin-top: 1rpx;
|
||||
}
|
||||
.mt2 {
|
||||
margin-top: 2rpx;
|
||||
}
|
||||
.mt5 {
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
.mt10 {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
.mt15 {
|
||||
margin-top: 15rpx;
|
||||
}
|
||||
.mt20 {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
.mt25 {
|
||||
margin-top: 25rpx;
|
||||
}
|
||||
.mt30 {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
.mt50 {
|
||||
margin-top: 50rpx;
|
||||
}
|
||||
.mt-5 {
|
||||
margin-top: -5rpx;
|
||||
}
|
||||
.mt-10 {
|
||||
margin-top: -10rpx;
|
||||
}
|
||||
.mt-15 {
|
||||
margin-top: -15rpx;
|
||||
}
|
||||
.mb1 {
|
||||
margin-bottom: 1rpx;
|
||||
}
|
||||
.mb2 {
|
||||
margin-bottom: 2rpx;
|
||||
}
|
||||
.mb5 {
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.mb10 {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
.mb15 {
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
.mb20 {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.mb25 {
|
||||
margin-bottom: 25rpx;
|
||||
}
|
||||
.mb30 {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
.mb-5 {
|
||||
margin-bottom: -5rpx;
|
||||
}
|
||||
.mb-10 {
|
||||
margin-bottom: -10rpx;
|
||||
}
|
||||
.mb-15 {
|
||||
margin-bottom: -15rpx;
|
||||
}
|
||||
.p0 {
|
||||
padding: 0;
|
||||
}
|
||||
.p1 {
|
||||
padding: 1rpx;
|
||||
}
|
||||
.pl1 {
|
||||
padding-left: 1rpx;
|
||||
}
|
||||
.pt1 {
|
||||
padding-top: 1rpx;
|
||||
}
|
||||
.pr1 {
|
||||
padding-right: 1rpx;
|
||||
}
|
||||
.pb1 {
|
||||
padding-bottom: 1rpx;
|
||||
}
|
||||
.p2 {
|
||||
padding: 2rpx;
|
||||
}
|
||||
.pl2 {
|
||||
padding-left: 2rpx;
|
||||
}
|
||||
.pt2 {
|
||||
padding-top: 2rpx;
|
||||
}
|
||||
.pr2 {
|
||||
padding-right: 2rpx;
|
||||
}
|
||||
.pb2 {
|
||||
padding-bottom: 2rpx;
|
||||
}
|
||||
.pl5 {
|
||||
padding-left: 5rpx;
|
||||
}
|
||||
.p5 {
|
||||
padding: 5rpx;
|
||||
}
|
||||
.pt5 {
|
||||
padding-top: 5rpx;
|
||||
}
|
||||
.pr5 {
|
||||
padding-right: 5rpx;
|
||||
}
|
||||
.pb5 {
|
||||
padding-bottom: 5rpx;
|
||||
}
|
||||
.p10 {
|
||||
padding: 10rpx;
|
||||
}
|
||||
.pl10 {
|
||||
padding-left: 10rpx;
|
||||
}
|
||||
.pt10 {
|
||||
padding-top: 10rpx;
|
||||
}
|
||||
.pr10 {
|
||||
padding-right: 10rpx;
|
||||
}
|
||||
.pb10 {
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
.p15 {
|
||||
padding: 15rpx;
|
||||
}
|
||||
.pl15 {
|
||||
padding-left: 15rpx;
|
||||
}
|
||||
.pt15 {
|
||||
padding-top: 15rpx;
|
||||
}
|
||||
.pr15 {
|
||||
padding-right: 15rpx;
|
||||
}
|
||||
.pb15 {
|
||||
padding-bottom: 15rpx;
|
||||
}
|
||||
.p20 {
|
||||
padding: 20rpx;
|
||||
}
|
||||
.pl20 {
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
.pt20 {
|
||||
padding-top: 20rpx;
|
||||
}
|
||||
.pr20 {
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
.pb20 {
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
.p25 {
|
||||
padding: 25rpx;
|
||||
}
|
||||
.pl25 {
|
||||
padding-left: 25rpx;
|
||||
}
|
||||
.pt25 {
|
||||
padding-top: 25rpx;
|
||||
}
|
||||
.pr25 {
|
||||
padding-right: 25rpx;
|
||||
}
|
||||
.pb25 {
|
||||
padding-bottom: 25rpx;
|
||||
}
|
||||
.p30 {
|
||||
padding: 30rpx;
|
||||
}
|
||||
.pl30 {
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
.pt30 {
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
.pr30 {
|
||||
padding-right: 30rpx;
|
||||
}
|
||||
.pb30 {
|
||||
padding-bottom: 30rpx;
|
||||
}
|
||||
.bt1 {
|
||||
border-top: 1rpx solid #f6f8fc;
|
||||
}
|
||||
.bb1 {
|
||||
border-bottom: 1rpx solid #f6f8fc;
|
||||
}
|
||||
.bl1 {
|
||||
border-left: 1rpx solid #f6f8fc;
|
||||
}
|
||||
.br1 {
|
||||
border-right: 1rpx solid #f6f8fc;
|
||||
}
|
||||
.bt10 {
|
||||
border-top: 10rpx solid #f6f8fc;
|
||||
}
|
||||
.bb10 {
|
||||
border-bottom: 10rpx solid #f6f8fc;
|
||||
}
|
||||
.f0 {
|
||||
font-size: 0;
|
||||
}
|
||||
.f20 {
|
||||
font-size: 20rpx;
|
||||
}
|
||||
.f24 {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
.f26 {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.f28 {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.f32 {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.f34 {
|
||||
font-size: 34rpx;
|
||||
}
|
||||
.f36 {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
.f40 {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
.f44 {
|
||||
font-size: 44rpx;
|
||||
}
|
||||
.f48 {
|
||||
font-size: 48rpx;
|
||||
}
|
||||
.f56 {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
.n {
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
.b {
|
||||
font-weight: bold;
|
||||
}
|
||||
.i {
|
||||
font-style: italic;
|
||||
}
|
||||
.tc {
|
||||
text-align: center;
|
||||
}
|
||||
.tr {
|
||||
text-align: right;
|
||||
}
|
||||
.tl {
|
||||
text-align: left;
|
||||
}
|
||||
.tj,.th_tj {
|
||||
text-align: justify;
|
||||
}
|
||||
.th_tj:after{
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 1rpx;
|
||||
}
|
||||
.tdl {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.lt-1 {
|
||||
letter-spacing: -1rpx;
|
||||
}
|
||||
.lt0 {
|
||||
letter-spacing: 0;
|
||||
}
|
||||
.lt1 {
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.bk {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.vm {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.vb {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.vt {
|
||||
vertical-align: top;
|
||||
}
|
||||
.vn {
|
||||
vertical-align: -5rpx;
|
||||
}
|
||||
.l {
|
||||
float: left;
|
||||
}
|
||||
.r {
|
||||
float: right;
|
||||
}
|
||||
.cl {
|
||||
clear: both;
|
||||
}
|
||||
.rel {
|
||||
position: relative;
|
||||
}
|
||||
.abs,.cm {
|
||||
position: absolute;
|
||||
}
|
||||
.fixed {
|
||||
position: fixed;
|
||||
}
|
||||
.zx1 {
|
||||
z-index: 1;
|
||||
}
|
||||
.zx2 {
|
||||
z-index: 2;
|
||||
}
|
||||
.zx8 {
|
||||
z-index: 8;
|
||||
}
|
||||
.zx9 {
|
||||
z-index: 9;
|
||||
}
|
||||
.zx99 {
|
||||
z-index: 99;
|
||||
}
|
||||
.zx999 {
|
||||
z-index: 999;
|
||||
}
|
||||
.cm{
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
.t0{
|
||||
top: 0;
|
||||
}
|
||||
.t50{
|
||||
top: 50%;
|
||||
}
|
||||
.b0{
|
||||
bottom: 0;
|
||||
}
|
||||
.l0{
|
||||
left: 0;
|
||||
}
|
||||
.l50{
|
||||
left: 50%;
|
||||
}
|
||||
.r0{
|
||||
right: 0;
|
||||
}
|
||||
.ovh {
|
||||
overflow: hidden;
|
||||
}
|
||||
.ova {
|
||||
overflow: auto;
|
||||
}
|
||||
.vh {
|
||||
visibility: hidden;
|
||||
}
|
||||
.vv {
|
||||
visibility: visible;
|
||||
}
|
||||
.o0{
|
||||
opacity: 0;
|
||||
}
|
||||
.clearfix,
|
||||
.fix {
|
||||
zoom: 1;
|
||||
}
|
||||
.clearfix:after,
|
||||
.fix:after {
|
||||
display: table;
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
.ell {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ell_more{
|
||||
overflow : hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
.ell_2{
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
.ell_3{
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
.middle {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.trans {
|
||||
transition: all 250ms;
|
||||
}
|
||||
.disabled {
|
||||
opacity: 0.4;
|
||||
filter: alpha(opacity=40);
|
||||
cursor: default;
|
||||
-ms-pointer-events: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.flex {
|
||||
/* 转为弹性盒模型 */
|
||||
display: flex;
|
||||
}
|
||||
.flex_wrap {
|
||||
/* 转为弹性盒模型并自动换行 */
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.flex_b {
|
||||
/* 垂直底部对齐 */
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.flex_tb {
|
||||
/* 垂直两端对齐 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex_tb_c {
|
||||
/* 多行垂直两端对齐,水平居中 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.flex_line_c {
|
||||
/* 多行垂直水平居中 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.flex_line_c_m {
|
||||
/* 多行垂直居中,水平居中 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.flex_line_end {
|
||||
/* 多行垂直起点在下沿 */
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.flex_lr {
|
||||
/* 水平两端对齐,剩余空间平均分布 */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex_lr_m {
|
||||
/* 水平两端对齐,剩余空间平均分布,垂直居中 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex_c_m {
|
||||
/* 垂直水平居中 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex_c {
|
||||
/* 水平居中 */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex_m {
|
||||
/* 垂直居中 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.flex_nosize {
|
||||
/* 子元素不自动 */
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.flex_autosize {
|
||||
/* 子元素自动宽度 */
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.flex_inline {
|
||||
/* 转为行内弹性盒模型 */
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.flex0{
|
||||
flex: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
.flex1{
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.Mask{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
.Mask .maskClick{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container{
|
||||
min-height: 100%;
|
||||
}
|
||||
.errorMessageBox{
|
||||
min-height: 100%;
|
||||
}
|
||||
.errorMessageBox .bottom{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border-top: 10rpx solid #f6f8fc;
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* tabs */
|
||||
.nav-tabs {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-more {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
#tabs li {
|
||||
cursor: pointer;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-bottom: -1px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.tab-container .content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 页面布局 */
|
||||
.main {
|
||||
padding: 30px 100px;
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
color: #333;
|
||||
text-align: left;
|
||||
margin-bottom: 30px;
|
||||
line-height: 1;
|
||||
height: 110px;
|
||||
margin-top: -50px;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.main .logo a {
|
||||
font-size: 160px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.helps {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.helps pre {
|
||||
padding: 20px;
|
||||
margin: 10px 0;
|
||||
border: solid 1px #e7e1cd;
|
||||
background-color: #fffdef;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.icon_lists {
|
||||
width: 100% !important;
|
||||
overflow: hidden;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.icon_lists li {
|
||||
width: 100px;
|
||||
margin-bottom: 10px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
list-style: none !important;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.icon_lists li .code-name {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.icon_lists .icon {
|
||||
display: block;
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
font-size: 42px;
|
||||
margin: 10px auto;
|
||||
color: #333;
|
||||
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
-moz-transition: font-size 0.25s linear, width 0.25s linear;
|
||||
transition: font-size 0.25s linear, width 0.25s linear;
|
||||
}
|
||||
|
||||
.icon_lists .icon:hover {
|
||||
font-size: 100px;
|
||||
}
|
||||
|
||||
.icon_lists .svg-icon {
|
||||
/* 通过设置 font-size 来改变图标大小 */
|
||||
width: 1em;
|
||||
/* 图标和文字相邻时,垂直对齐 */
|
||||
vertical-align: -0.15em;
|
||||
/* 通过设置 color 来改变 SVG 的颜色/fill */
|
||||
fill: currentColor;
|
||||
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
|
||||
normalize.css 中也包含这行 */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.icon_lists li .name,
|
||||
.icon_lists li .code-name {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* markdown 样式 */
|
||||
.markdown {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
vertical-align: middle;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
color: #404040;
|
||||
font-weight: 500;
|
||||
line-height: 40px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #404040;
|
||||
margin: 1.6em 0 0.6em 0;
|
||||
font-weight: 500;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #e9e9e9;
|
||||
margin: 16px 0;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown>p,
|
||||
.markdown>blockquote,
|
||||
.markdown>.highlight,
|
||||
.markdown>ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul>li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown>ul li,
|
||||
.markdown blockquote ul>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown>ul li p,
|
||||
.markdown>ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol>li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown>ol li,
|
||||
.markdown blockquote ol>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 3px;
|
||||
padding: 0 5px;
|
||||
background: #eee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
border: 1px solid #e9e9e9;
|
||||
width: 95%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown>table th,
|
||||
.markdown>table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown>table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
font-size: 90%;
|
||||
color: #999;
|
||||
border-left: 4px solid #e9e9e9;
|
||||
padding-left: 0.8em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
opacity: 1;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown>br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
padding: 0.5em;
|
||||
color: #333333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-meta {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-strong,
|
||||
.hljs-emphasis,
|
||||
.hljs-quote {
|
||||
color: #df5000;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-type {
|
||||
color: #a71d5d;
|
||||
}
|
||||
|
||||
.hljs-literal,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-attribute {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name {
|
||||
color: #63a35c;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-attr,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #795da3;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #55a532;
|
||||
background-color: #eaffea;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #bd2c00;
|
||||
background-color: #ffecec;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 代码高亮 */
|
||||
/* PrismJS 1.15.0
|
||||
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
line-height: 1.5;
|
||||
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #905;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #690;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #07a;
|
||||
}
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>IconFont Demo</title>
|
||||
<link rel="shortcut icon" href="https://gtms04.alicdn.com/tps/i4/TB1_oz6GVXXXXaFXpXXJDFnIXXX-64-64.ico" type="image/x-icon"/>
|
||||
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
|
||||
<link rel="stylesheet" href="demo.css">
|
||||
<link rel="stylesheet" href="iconfont.css">
|
||||
<script src="iconfont.js"></script>
|
||||
<!-- jQuery -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
|
||||
<!-- 代码高亮 -->
|
||||
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="main">
|
||||
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank"></a></h1>
|
||||
<div class="nav-tabs">
|
||||
<ul id="tabs" class="dib-box">
|
||||
<li class="dib active"><span>Unicode</span></li>
|
||||
<li class="dib"><span>Font class</span></li>
|
||||
<li class="dib"><span>Symbol</span></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="tab-container">
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">减</div>
|
||||
<div class="code-name">&#xe619;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">加</div>
|
||||
<div class="code-name">&#xe61a;</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="unicode-">Unicode 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
|
||||
<ul>
|
||||
<li>兼容性最好,支持 IE6+,及所有现代浏览器。</li>
|
||||
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
|
||||
<li>但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式</p>
|
||||
</blockquote>
|
||||
<p>Unicode 使用步骤如下:</p>
|
||||
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.eot');
|
||||
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('iconfont.woff2') format('woff2'),
|
||||
url('iconfont.woff') format('woff'),
|
||||
url('iconfont.ttf') format('truetype'),
|
||||
url('iconfont.svg#iconfont') format('svg');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
<pre><code class="language-css"
|
||||
>.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
|
||||
<pre>
|
||||
<code class="language-html"
|
||||
><span class="iconfont">&#x33;</span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-jian"></span>
|
||||
<div class="name">
|
||||
减
|
||||
</div>
|
||||
<div class="code-name">.icon-jian
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-jia"></span>
|
||||
<div class="name">
|
||||
加
|
||||
</div>
|
||||
<div class="code-name">.icon-jia
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="font-class-">font-class 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
|
||||
<p>与 Unicode 使用方式相比,具有如下特点:</p>
|
||||
<ul>
|
||||
<li>兼容性良好,支持 IE8+,及所有现代浏览器。</li>
|
||||
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
|
||||
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
|
||||
<li>不过因为本质上还是使用的字体,所以多色图标还是不支持的。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
|
||||
<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css">
|
||||
</code></pre>
|
||||
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><span class="iconfont icon-xxx"></span>
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<p>"
|
||||
iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-jian"></use>
|
||||
</svg>
|
||||
<div class="name">减</div>
|
||||
<div class="code-name">#icon-jian</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-jia"></use>
|
||||
</svg>
|
||||
<div class="name">加</div>
|
||||
<div class="code-name">#icon-jia</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="article markdown">
|
||||
<h2 id="symbol-">Symbol 引用</h2>
|
||||
<hr>
|
||||
|
||||
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
|
||||
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
|
||||
<ul>
|
||||
<li>支持多色图标了,不再受单色限制。</li>
|
||||
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
|
||||
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
|
||||
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
|
||||
</ul>
|
||||
<p>使用步骤如下:</p>
|
||||
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
|
||||
<pre><code class="language-html"><script src="./iconfont.js"></script>
|
||||
</code></pre>
|
||||
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
|
||||
<pre><code class="language-html"><style>
|
||||
.icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</code></pre>
|
||||
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
|
||||
<pre><code class="language-html"><svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-xxx"></use>
|
||||
</svg>
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.tab-container .content:first').show()
|
||||
|
||||
$('#tabs li').click(function (e) {
|
||||
var tabContent = $('.tab-container .content')
|
||||
var index = $(this).index()
|
||||
|
||||
if ($(this).hasClass('active')) {
|
||||
return
|
||||
} else {
|
||||
$('#tabs li').removeClass('active')
|
||||
$(this).addClass('active')
|
||||
|
||||
tabContent.hide().eq(index).fadeIn()
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
!function(a){var e,n='<svg><symbol id="icon-jian" viewBox="0 0 1024 1024"><path d="M512 1024C229.2224 1024 0 794.7776 0 512 0 229.2224 229.2224 0 512 0 794.7776 0 1024 229.2224 1024 512 1024 794.7776 794.7776 1024 512 1024ZM512 51.2C257.5104 51.2 51.2 257.5104 51.2 512 51.2 766.4896 257.5104 972.8 512 972.8 766.4896 972.8 972.8 766.4896 972.8 512 972.8 257.5104 766.4896 51.2 512 51.2ZM307.2 486.4 716.8 486.4 716.8 537.6 307.2 537.6 307.2 486.4Z" ></path></symbol><symbol id="icon-jia" viewBox="0 0 1024 1024"><path d="M512 1024C229.2224 1024 0 794.7776 0 512 0 229.2224 229.2224 0 512 0 794.7776 0 1024 229.2224 1024 512 1024 794.7776 794.7776 1024 512 1024ZM716.8 486.4 537.6 486.4 537.6 307.2 486.4 307.2 486.4 486.4 307.2 486.4 307.2 537.6 486.4 537.6 486.4 716.8 537.6 716.8 537.6 537.6 716.8 537.6 716.8 486.4Z" ></path></symbol></svg>',t=(e=document.getElementsByTagName("script"))[e.length-1].getAttribute("data-injectcss");if(t&&!a.__iconfont__svg__cssinject__){a.__iconfont__svg__cssinject__=!0;try{document.write("<style>.svgfont {display: inline-block;width: 1em;height: 1em;fill: currentColor;vertical-align: -0.1em;font-size:16px;}</style>")}catch(e){console&&console.log(e)}}!function(e){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(e,0);else{var t=function(){document.removeEventListener("DOMContentLoaded",t,!1),e()};document.addEventListener("DOMContentLoaded",t,!1)}else document.attachEvent&&(o=e,i=a.document,c=!1,(d=function(){try{i.documentElement.doScroll("left")}catch(e){return void setTimeout(d,50)}n()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,n())});function n(){c||(c=!0,o())}var o,i,c,d}(function(){var e,t;(e=document.createElement("div")).innerHTML=n,n=null,(t=e.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",function(e,t){t.firstChild?function(e,t){t.parentNode.insertBefore(e,t)}(e,t.firstChild):t.appendChild(e)}(t,document.body))})}(window);
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": "",
|
||||
"name": "",
|
||||
"font_family": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "654162",
|
||||
"name": "减",
|
||||
"font_class": "jian",
|
||||
"unicode": "e619",
|
||||
"unicode_decimal": 58905
|
||||
},
|
||||
{
|
||||
"icon_id": "654163",
|
||||
"name": "加",
|
||||
"font_class": "jia",
|
||||
"unicode": "e61a",
|
||||
"unicode_decimal": 58906
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<!--
|
||||
2013-9-30: Created.
|
||||
-->
|
||||
<svg>
|
||||
<metadata>
|
||||
Created by iconfont
|
||||
</metadata>
|
||||
<defs>
|
||||
|
||||
<font id="iconfont" horiz-adv-x="1024" >
|
||||
<font-face
|
||||
font-family="iconfont"
|
||||
font-weight="500"
|
||||
font-stretch="normal"
|
||||
units-per-em="1024"
|
||||
ascent="896"
|
||||
descent="-128"
|
||||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="jian" unicode="" d="M512-128C229.2224-128 0 101.2224 0 384 0 666.7776 229.2224 896 512 896 794.7776 896 1024 666.7776 1024 384 1024 101.2224 794.7776-128 512-128ZM512 844.8C257.5104 844.8 51.2 638.4896 51.2 384 51.2 129.5104 257.5104-76.8 512-76.8 766.4896-76.8 972.8 129.5104 972.8 384 972.8 638.4896 766.4896 844.8 512 844.8ZM307.2 409.6 716.8 409.6 716.8 358.4 307.2 358.4 307.2 409.6Z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
<glyph glyph-name="jia" unicode="" d="M512-128C229.2224-128 0 101.2224 0 384 0 666.7776 229.2224 896 512 896 794.7776 896 1024 666.7776 1024 384 1024 101.2224 794.7776-128 512-128ZM716.8 409.6 537.6 409.6 537.6 588.8 486.4 588.8 486.4 409.6 307.2 409.6 307.2 358.4 486.4 358.4 486.4 179.2 537.6 179.2 537.6 358.4 716.8 358.4 716.8 409.6Z" horiz-adv-x="1024" />
|
||||
|
||||
|
||||
|
||||
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,25 @@
|
||||
@font-face {font-family: "iconfont";
|
||||
src: url('iconfont.eot?t=1574240438561'); /* IE9 */
|
||||
src: url('iconfont.eot?t=1574240438561#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALMAAsAAAAABuAAAAJ/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCfgqBVIFEATYCJAMMCwgABCAFhG0HNBsABsg+QDZkA29GJAJpmfH2sw9ROWtmL/4jQrmpIh6+9ns9d/d+2hdgBQpQRgKOj4qCEhoRW9UIX12hazuehWFh6f7X2pxZ6PP6ebxkAum0rc9f8dlBOy2TClQahEYDDIAMS5DZ+gag0eTmBgcvUvTC/i0wlK622QkAONtff77D/rh3+kedd1k0n0XlNMfGT12A8dau870xiqxAQm8Yu8AlPCbQLOsrnW0fL9CUrFWBeOm7JjRzQSlZZij0aw6muNUzLK/KF+B1+P34zTSGFL3K2nj+eOPA/BvEuPmfSx8RIsDjPVTsAElc1CbPVQSjVjTuqhUgZcM32nwDNou90grx1znlY2ADpgrf4HIIvvGQAiroe4X0LnCFyJlTlbGxdCbf+9Ht890/7vXDvAP5JeJnhz/JGVd/kdaiaTpddP89U/1q6ytPmtb03ry/ak1IWaVwTLdvM0My3bnWiYDf+ht/MpN7N7sEX78Ll/wvod5geGJX8BNFPZtS18CqVIWu0HRXizeVKGi6x3+Wd8bfePV87zhhmBMxKAaWoBpaQZO8Az2dXegbOoRm2+54ZxariBxhyweAMOUTignvoJryjSb5F3oW/EPfVFRoLmL2ws5aPGufMplCDlpv6NtpohyLtKPKE7lPkclZSUi/ERd+BCfDcTGzo4R4ji3FszsVUag4jXELnqMoSjHjNCBbhp5INhuNVN2bhnYaQ9spRkyCOJDlDfLZUgnltxft0udPiOtJxMQthBrvDWEFf3Q0MTTuge6USS/CvbxSeOaaEkJBCkvF0BbYSWQnUyirnxcgNjHkjYhnZkaoleqrHK6vjr9vBzTWlholaqR87ptJxTMAAAA=') format('woff2'),
|
||||
url('iconfont.woff?t=1574240438561') format('woff'),
|
||||
url('iconfont.ttf?t=1574240438561') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
|
||||
url('iconfont.svg?t=1574240438561#iconfont') format('svg'); /* iOS 4.1- */
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-jian:before {
|
||||
content: "\e619";
|
||||
}
|
||||
|
||||
.icon-jia:before {
|
||||
content: "\e61a";
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,81 @@
|
||||
function withData(param){
|
||||
return param < 10 ? '0' + param : '' + param;
|
||||
}
|
||||
function getLoopArray(start,end){
|
||||
var start = start || 0;
|
||||
var end = end || 1;
|
||||
var array = [];
|
||||
for (var i = start; i <= end; i++) {
|
||||
array.push(withData(i));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
function getMonthDay(year,month){
|
||||
var flag = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0), array = null;
|
||||
|
||||
switch (month) {
|
||||
case '01':
|
||||
case '03':
|
||||
case '05':
|
||||
case '07':
|
||||
case '08':
|
||||
case '10':
|
||||
case '12':
|
||||
array = getLoopArray(1, 31)
|
||||
break;
|
||||
case '04':
|
||||
case '06':
|
||||
case '09':
|
||||
case '11':
|
||||
array = getLoopArray(1, 30)
|
||||
break;
|
||||
case '02':
|
||||
array = flag ? getLoopArray(1, 29) : getLoopArray(1, 28)
|
||||
break;
|
||||
default:
|
||||
array = '月份格式不正确,请重新输入!'
|
||||
}
|
||||
return array;
|
||||
}
|
||||
function getNewDateArry(){
|
||||
// 当前时间的处理
|
||||
var newDate = new Date();
|
||||
var year = withData(newDate.getFullYear()),
|
||||
mont = withData(newDate.getMonth() + 1),
|
||||
date = withData(newDate.getDate()),
|
||||
hour = withData(newDate.getHours()),
|
||||
minu = withData(newDate.getMinutes()),
|
||||
seco = withData(newDate.getSeconds());
|
||||
|
||||
return [year, mont, date, hour, minu, seco];
|
||||
}
|
||||
function dateTimePicker(startYear,endYear,date) {
|
||||
// 返回默认显示的数组和联动数组的声明
|
||||
var dateTime = [], dateTimeArray = [[],[],[],[],[],[]];
|
||||
var start = startYear || 1978;
|
||||
var end = endYear || 2100;
|
||||
// 默认开始显示数据
|
||||
var defaultDate = date ? [...date.split(' ')[0].split('-'), ...date.split(' ')[1].split(':')] : getNewDateArry();
|
||||
// 处理联动列表数据
|
||||
/*年月日 时分秒*/
|
||||
dateTimeArray[0] = getLoopArray(start,end);
|
||||
dateTimeArray[1] = getLoopArray(1, 12);
|
||||
dateTimeArray[2] = getMonthDay(defaultDate[0], defaultDate[1]);
|
||||
dateTimeArray[3] = getLoopArray(0, 23);
|
||||
dateTimeArray[4] = getLoopArray(0, 59);
|
||||
dateTimeArray[5] = getLoopArray(0, 59);
|
||||
|
||||
dateTimeArray.forEach((current,index) => {
|
||||
dateTime.push(current.indexOf(defaultDate[index]));
|
||||
});
|
||||
|
||||
return {
|
||||
dateTimeArray: dateTimeArray,
|
||||
dateTime: dateTime
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
dateTimePicker: dateTimePicker,
|
||||
getMonthDay: getMonthDay
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import http from './http.js'
|
||||
|
||||
// let baseUrl = 'https://share.hzwlsoft.com'
|
||||
// let baseUrl = 'http://localhost:8080'
|
||||
let baseUrl = 'http://10.0.1.63:8080'
|
||||
// let baseUrl = 'http://192.168.1.110:8080'
|
||||
/* 配置路径 */
|
||||
|
||||
|
||||
let apiUrl = {
|
||||
// 登录
|
||||
wxLoginByUserName: '/api/sys/login', //微信账号密码登陆--1
|
||||
}
|
||||
|
||||
export default {
|
||||
baseUrl,
|
||||
//微信账号密码登陆--1
|
||||
wxLoginByUserName(option, success, error) {
|
||||
http.post1(baseUrl + apiUrl.wxLoginByUserName, option).then(res => {
|
||||
return success && success(res)
|
||||
}).catch(err => {
|
||||
return error && error(err)
|
||||
})
|
||||
},
|
||||
|
||||
//微信小程序授权--2
|
||||
wxAuthorization(option, success, error) {
|
||||
http.post1(baseUrl + apiUrl.wxAuthorization, option).then(res => {
|
||||
return success && success(res)
|
||||
}).catch(err => {
|
||||
return error && error(err)
|
||||
})
|
||||
},
|
||||
|
||||
//微信小程序登录
|
||||
wxLoginByOpenId(option, success, error) {
|
||||
http.post(baseUrl + apiUrl.wxLoginByOpenId, option).then(res => {
|
||||
return success && success(res)
|
||||
}).catch(err => {
|
||||
return error && error(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
let headerDefault = {
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
let headerDefault1 = {
|
||||
'content-type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
let TokenKey = 'X-Access-Token'
|
||||
let baseUrl = 'http://10.0.1.63:8080'
|
||||
// let baseUrl = 'http://localhost:8080'
|
||||
const http = (method, url, data, header= headerDefault) => {
|
||||
let Authorization = wx.getStorageSync(TokenKey) ? wx.getStorageSync(TokenKey) : '';
|
||||
header[TokenKey] = Authorization == '' ? '' : JSON.parse(Authorization)
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
})
|
||||
wx.request({
|
||||
method: method,
|
||||
url: baseUrl + url,
|
||||
header: header,
|
||||
data: data,
|
||||
success: res => {
|
||||
console.log(res)
|
||||
if (res.statusCode === 200) {
|
||||
// 接口请求错误的时候提示
|
||||
if((res.data.code !== 200 && res.data.code !== 0) && (res.data.message)) {
|
||||
wx.showToast({
|
||||
title: res.data.message,
|
||||
icon: "none",
|
||||
duration: 800,
|
||||
mask: true
|
||||
});
|
||||
}
|
||||
// 200: 服务端业务处理正常结束
|
||||
resolve(res.data)
|
||||
wx.hideLoading();
|
||||
} else {
|
||||
console.error(res.data);
|
||||
reject(res.data);
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title: "登录失效,请重新登录",
|
||||
icon: "none",
|
||||
duration: 1500,
|
||||
mask: true
|
||||
});
|
||||
wx.navigateTo({
|
||||
url: '/pages/login/login',
|
||||
})
|
||||
console.error("登录失效3");
|
||||
}
|
||||
},
|
||||
fail: err => {
|
||||
console.error(err);
|
||||
reject(err);
|
||||
wx.hideLoading();
|
||||
},
|
||||
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
get: (url, data, header) => http('GET', url, data, header),
|
||||
post: (url, data, header) => http('POST', url, data, header),
|
||||
post1: (url, data, header) => http('POST', url, data, headerDefault1),
|
||||
put: (url, data, header) => http('PUT', url, data, header),
|
||||
delete: (url, data, header) => http('DELETE', url, data, header)
|
||||
}
|
||||
@@ -0,0 +1,806 @@
|
||||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Qs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var replace = String.prototype.replace;
|
||||
var percentTwenties = /%20/g;
|
||||
|
||||
var util = require('./utils');
|
||||
|
||||
var Format = {
|
||||
RFC1738: 'RFC1738',
|
||||
RFC3986: 'RFC3986'
|
||||
};
|
||||
|
||||
module.exports = util.assign(
|
||||
{
|
||||
'default': Format.RFC3986,
|
||||
formatters: {
|
||||
RFC1738: function (value) {
|
||||
return replace.call(value, percentTwenties, '+');
|
||||
},
|
||||
RFC3986: function (value) {
|
||||
return String(value);
|
||||
}
|
||||
}
|
||||
},
|
||||
Format
|
||||
);
|
||||
|
||||
},{"./utils":5}],2:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var stringify = require('./stringify');
|
||||
var parse = require('./parse');
|
||||
var formats = require('./formats');
|
||||
|
||||
module.exports = {
|
||||
formats: formats,
|
||||
parse: parse,
|
||||
stringify: stringify
|
||||
};
|
||||
|
||||
},{"./formats":1,"./parse":3,"./stringify":4}],3:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
|
||||
var defaults = {
|
||||
allowDots: false,
|
||||
allowPrototypes: false,
|
||||
arrayLimit: 20,
|
||||
charset: 'utf-8',
|
||||
charsetSentinel: false,
|
||||
comma: false,
|
||||
decoder: utils.decode,
|
||||
delimiter: '&',
|
||||
depth: 5,
|
||||
ignoreQueryPrefix: false,
|
||||
interpretNumericEntities: false,
|
||||
parameterLimit: 1000,
|
||||
parseArrays: true,
|
||||
plainObjects: false,
|
||||
strictNullHandling: false
|
||||
};
|
||||
|
||||
var interpretNumericEntities = function (str) {
|
||||
return str.replace(/&#(\d+);/g, function ($0, numberStr) {
|
||||
return String.fromCharCode(parseInt(numberStr, 10));
|
||||
});
|
||||
};
|
||||
|
||||
// This is what browsers will submit when the ✓ character occurs in an
|
||||
// application/x-www-form-urlencoded body and the encoding of the page containing
|
||||
// the form is iso-8859-1, or when the submitted form has an accept-charset
|
||||
// attribute of iso-8859-1. Presumably also with other charsets that do not contain
|
||||
// the ✓ character, such as us-ascii.
|
||||
var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓')
|
||||
|
||||
// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded.
|
||||
var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')
|
||||
|
||||
var parseValues = function parseQueryStringValues(str, options) {
|
||||
var obj = {};
|
||||
var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
|
||||
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
|
||||
var parts = cleanStr.split(options.delimiter, limit);
|
||||
var skipIndex = -1; // Keep track of where the utf8 sentinel was found
|
||||
var i;
|
||||
|
||||
var charset = options.charset;
|
||||
if (options.charsetSentinel) {
|
||||
for (i = 0; i < parts.length; ++i) {
|
||||
if (parts[i].indexOf('utf8=') === 0) {
|
||||
if (parts[i] === charsetSentinel) {
|
||||
charset = 'utf-8';
|
||||
} else if (parts[i] === isoSentinel) {
|
||||
charset = 'iso-8859-1';
|
||||
}
|
||||
skipIndex = i;
|
||||
i = parts.length; // The eslint settings do not allow break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < parts.length; ++i) {
|
||||
if (i === skipIndex) {
|
||||
continue;
|
||||
}
|
||||
var part = parts[i];
|
||||
|
||||
var bracketEqualsPos = part.indexOf(']=');
|
||||
var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1;
|
||||
|
||||
var key, val;
|
||||
if (pos === -1) {
|
||||
key = options.decoder(part, defaults.decoder, charset, 'key');
|
||||
val = options.strictNullHandling ? null : '';
|
||||
} else {
|
||||
key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key');
|
||||
val = options.decoder(part.slice(pos + 1), defaults.decoder, charset, 'value');
|
||||
}
|
||||
|
||||
if (val && options.interpretNumericEntities && charset === 'iso-8859-1') {
|
||||
val = interpretNumericEntities(val);
|
||||
}
|
||||
|
||||
if (val && options.comma && val.indexOf(',') > -1) {
|
||||
val = val.split(',');
|
||||
}
|
||||
|
||||
if (has.call(obj, key)) {
|
||||
obj[key] = utils.combine(obj[key], val);
|
||||
} else {
|
||||
obj[key] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
var parseObject = function (chain, val, options) {
|
||||
var leaf = val;
|
||||
|
||||
for (var i = chain.length - 1; i >= 0; --i) {
|
||||
var obj;
|
||||
var root = chain[i];
|
||||
|
||||
if (root === '[]' && options.parseArrays) {
|
||||
obj = [].concat(leaf);
|
||||
} else {
|
||||
obj = options.plainObjects ? Object.create(null) : {};
|
||||
var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root;
|
||||
var index = parseInt(cleanRoot, 10);
|
||||
if (!options.parseArrays && cleanRoot === '') {
|
||||
obj = { 0: leaf };
|
||||
} else if (
|
||||
!isNaN(index)
|
||||
&& root !== cleanRoot
|
||||
&& String(index) === cleanRoot
|
||||
&& index >= 0
|
||||
&& (options.parseArrays && index <= options.arrayLimit)
|
||||
) {
|
||||
obj = [];
|
||||
obj[index] = leaf;
|
||||
} else {
|
||||
obj[cleanRoot] = leaf;
|
||||
}
|
||||
}
|
||||
|
||||
leaf = obj;
|
||||
}
|
||||
|
||||
return leaf;
|
||||
};
|
||||
|
||||
var parseKeys = function parseQueryStringKeys(givenKey, val, options) {
|
||||
if (!givenKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Transform dot notation to bracket notation
|
||||
var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey;
|
||||
|
||||
// The regex chunks
|
||||
|
||||
var brackets = /(\[[^[\]]*])/;
|
||||
var child = /(\[[^[\]]*])/g;
|
||||
|
||||
// Get the parent
|
||||
|
||||
var segment = options.depth > 0 && brackets.exec(key);
|
||||
var parent = segment ? key.slice(0, segment.index) : key;
|
||||
|
||||
// Stash the parent if it exists
|
||||
|
||||
var keys = [];
|
||||
if (parent) {
|
||||
// If we aren't using plain objects, optionally prefix keys that would overwrite object prototype properties
|
||||
if (!options.plainObjects && has.call(Object.prototype, parent)) {
|
||||
if (!options.allowPrototypes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
keys.push(parent);
|
||||
}
|
||||
|
||||
// Loop through children appending to the array until we hit depth
|
||||
|
||||
var i = 0;
|
||||
while (options.depth > 0 && (segment = child.exec(key)) !== null && i < options.depth) {
|
||||
i += 1;
|
||||
if (!options.plainObjects && has.call(Object.prototype, segment[1].slice(1, -1))) {
|
||||
if (!options.allowPrototypes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
keys.push(segment[1]);
|
||||
}
|
||||
|
||||
// If there's a remainder, just add whatever is left
|
||||
|
||||
if (segment) {
|
||||
keys.push('[' + key.slice(segment.index) + ']');
|
||||
}
|
||||
|
||||
return parseObject(keys, val, options);
|
||||
};
|
||||
|
||||
var normalizeParseOptions = function normalizeParseOptions(opts) {
|
||||
if (!opts) {
|
||||
return defaults;
|
||||
}
|
||||
|
||||
if (opts.decoder !== null && opts.decoder !== undefined && typeof opts.decoder !== 'function') {
|
||||
throw new TypeError('Decoder has to be a function.');
|
||||
}
|
||||
|
||||
if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
|
||||
throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined');
|
||||
}
|
||||
var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset;
|
||||
|
||||
return {
|
||||
allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
|
||||
allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes,
|
||||
arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit,
|
||||
charset: charset,
|
||||
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
||||
comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma,
|
||||
decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder,
|
||||
delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter,
|
||||
// eslint-disable-next-line no-implicit-coercion, no-extra-parens
|
||||
depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth,
|
||||
ignoreQueryPrefix: opts.ignoreQueryPrefix === true,
|
||||
interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities,
|
||||
parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit,
|
||||
parseArrays: opts.parseArrays !== false,
|
||||
plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects,
|
||||
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = function (str, opts) {
|
||||
var options = normalizeParseOptions(opts);
|
||||
|
||||
if (str === '' || str === null || typeof str === 'undefined') {
|
||||
return options.plainObjects ? Object.create(null) : {};
|
||||
}
|
||||
|
||||
var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
|
||||
var obj = options.plainObjects ? Object.create(null) : {};
|
||||
|
||||
// Iterate over the keys and setup the new object
|
||||
|
||||
var keys = Object.keys(tempObj);
|
||||
for (var i = 0; i < keys.length; ++i) {
|
||||
var key = keys[i];
|
||||
var newObj = parseKeys(key, tempObj[key], options);
|
||||
obj = utils.merge(obj, newObj, options);
|
||||
}
|
||||
|
||||
return utils.compact(obj);
|
||||
};
|
||||
|
||||
},{"./utils":5}],4:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var formats = require('./formats');
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
|
||||
var arrayPrefixGenerators = {
|
||||
brackets: function brackets(prefix) {
|
||||
return prefix + '[]';
|
||||
},
|
||||
comma: 'comma',
|
||||
indices: function indices(prefix, key) {
|
||||
return prefix + '[' + key + ']';
|
||||
},
|
||||
repeat: function repeat(prefix) {
|
||||
return prefix;
|
||||
}
|
||||
};
|
||||
|
||||
var isArray = Array.isArray;
|
||||
var push = Array.prototype.push;
|
||||
var pushToArray = function (arr, valueOrArray) {
|
||||
push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]);
|
||||
};
|
||||
|
||||
var toISO = Date.prototype.toISOString;
|
||||
|
||||
var defaultFormat = formats['default'];
|
||||
var defaults = {
|
||||
addQueryPrefix: false,
|
||||
allowDots: false,
|
||||
charset: 'utf-8',
|
||||
charsetSentinel: false,
|
||||
delimiter: '&',
|
||||
encode: true,
|
||||
encoder: utils.encode,
|
||||
encodeValuesOnly: false,
|
||||
format: defaultFormat,
|
||||
formatter: formats.formatters[defaultFormat],
|
||||
// deprecated
|
||||
indices: false,
|
||||
serializeDate: function serializeDate(date) {
|
||||
return toISO.call(date);
|
||||
},
|
||||
skipNulls: false,
|
||||
strictNullHandling: false
|
||||
};
|
||||
|
||||
var isNonNullishPrimitive = function isNonNullishPrimitive(v) {
|
||||
return typeof v === 'string'
|
||||
|| typeof v === 'number'
|
||||
|| typeof v === 'boolean'
|
||||
|| typeof v === 'symbol'
|
||||
|| typeof v === 'bigint';
|
||||
};
|
||||
|
||||
var stringify = function stringify(
|
||||
object,
|
||||
prefix,
|
||||
generateArrayPrefix,
|
||||
strictNullHandling,
|
||||
skipNulls,
|
||||
encoder,
|
||||
filter,
|
||||
sort,
|
||||
allowDots,
|
||||
serializeDate,
|
||||
formatter,
|
||||
encodeValuesOnly,
|
||||
charset
|
||||
) {
|
||||
var obj = object;
|
||||
if (typeof filter === 'function') {
|
||||
obj = filter(prefix, obj);
|
||||
} else if (obj instanceof Date) {
|
||||
obj = serializeDate(obj);
|
||||
} else if (generateArrayPrefix === 'comma' && isArray(obj)) {
|
||||
obj = obj.join(',');
|
||||
}
|
||||
|
||||
if (obj === null) {
|
||||
if (strictNullHandling) {
|
||||
return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key') : prefix;
|
||||
}
|
||||
|
||||
obj = '';
|
||||
}
|
||||
|
||||
if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) {
|
||||
if (encoder) {
|
||||
var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key');
|
||||
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value'))];
|
||||
}
|
||||
return [formatter(prefix) + '=' + formatter(String(obj))];
|
||||
}
|
||||
|
||||
var values = [];
|
||||
|
||||
if (typeof obj === 'undefined') {
|
||||
return values;
|
||||
}
|
||||
|
||||
var objKeys;
|
||||
if (isArray(filter)) {
|
||||
objKeys = filter;
|
||||
} else {
|
||||
var keys = Object.keys(obj);
|
||||
objKeys = sort ? keys.sort(sort) : keys;
|
||||
}
|
||||
|
||||
for (var i = 0; i < objKeys.length; ++i) {
|
||||
var key = objKeys[i];
|
||||
|
||||
if (skipNulls && obj[key] === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isArray(obj)) {
|
||||
pushToArray(values, stringify(
|
||||
obj[key],
|
||||
typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix,
|
||||
generateArrayPrefix,
|
||||
strictNullHandling,
|
||||
skipNulls,
|
||||
encoder,
|
||||
filter,
|
||||
sort,
|
||||
allowDots,
|
||||
serializeDate,
|
||||
formatter,
|
||||
encodeValuesOnly,
|
||||
charset
|
||||
));
|
||||
} else {
|
||||
pushToArray(values, stringify(
|
||||
obj[key],
|
||||
prefix + (allowDots ? '.' + key : '[' + key + ']'),
|
||||
generateArrayPrefix,
|
||||
strictNullHandling,
|
||||
skipNulls,
|
||||
encoder,
|
||||
filter,
|
||||
sort,
|
||||
allowDots,
|
||||
serializeDate,
|
||||
formatter,
|
||||
encodeValuesOnly,
|
||||
charset
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
var normalizeStringifyOptions = function normalizeStringifyOptions(opts) {
|
||||
if (!opts) {
|
||||
return defaults;
|
||||
}
|
||||
|
||||
if (opts.encoder !== null && opts.encoder !== undefined && typeof opts.encoder !== 'function') {
|
||||
throw new TypeError('Encoder has to be a function.');
|
||||
}
|
||||
|
||||
var charset = opts.charset || defaults.charset;
|
||||
if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') {
|
||||
throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined');
|
||||
}
|
||||
|
||||
var format = formats['default'];
|
||||
if (typeof opts.format !== 'undefined') {
|
||||
if (!has.call(formats.formatters, opts.format)) {
|
||||
throw new TypeError('Unknown format option provided.');
|
||||
}
|
||||
format = opts.format;
|
||||
}
|
||||
var formatter = formats.formatters[format];
|
||||
|
||||
var filter = defaults.filter;
|
||||
if (typeof opts.filter === 'function' || isArray(opts.filter)) {
|
||||
filter = opts.filter;
|
||||
}
|
||||
|
||||
return {
|
||||
addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix,
|
||||
allowDots: typeof opts.allowDots === 'undefined' ? defaults.allowDots : !!opts.allowDots,
|
||||
charset: charset,
|
||||
charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel,
|
||||
delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter,
|
||||
encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode,
|
||||
encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder,
|
||||
encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly,
|
||||
filter: filter,
|
||||
formatter: formatter,
|
||||
serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate,
|
||||
skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls,
|
||||
sort: typeof opts.sort === 'function' ? opts.sort : null,
|
||||
strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = function (object, opts) {
|
||||
var obj = object;
|
||||
var options = normalizeStringifyOptions(opts);
|
||||
|
||||
var objKeys;
|
||||
var filter;
|
||||
|
||||
if (typeof options.filter === 'function') {
|
||||
filter = options.filter;
|
||||
obj = filter('', obj);
|
||||
} else if (isArray(options.filter)) {
|
||||
filter = options.filter;
|
||||
objKeys = filter;
|
||||
}
|
||||
|
||||
var keys = [];
|
||||
|
||||
if (typeof obj !== 'object' || obj === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var arrayFormat;
|
||||
if (opts && opts.arrayFormat in arrayPrefixGenerators) {
|
||||
arrayFormat = opts.arrayFormat;
|
||||
} else if (opts && 'indices' in opts) {
|
||||
arrayFormat = opts.indices ? 'indices' : 'repeat';
|
||||
} else {
|
||||
arrayFormat = 'indices';
|
||||
}
|
||||
|
||||
var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
|
||||
|
||||
if (!objKeys) {
|
||||
objKeys = Object.keys(obj);
|
||||
}
|
||||
|
||||
if (options.sort) {
|
||||
objKeys.sort(options.sort);
|
||||
}
|
||||
|
||||
for (var i = 0; i < objKeys.length; ++i) {
|
||||
var key = objKeys[i];
|
||||
|
||||
if (options.skipNulls && obj[key] === null) {
|
||||
continue;
|
||||
}
|
||||
pushToArray(keys, stringify(
|
||||
obj[key],
|
||||
key,
|
||||
generateArrayPrefix,
|
||||
options.strictNullHandling,
|
||||
options.skipNulls,
|
||||
options.encode ? options.encoder : null,
|
||||
options.filter,
|
||||
options.sort,
|
||||
options.allowDots,
|
||||
options.serializeDate,
|
||||
options.formatter,
|
||||
options.encodeValuesOnly,
|
||||
options.charset
|
||||
));
|
||||
}
|
||||
|
||||
var joined = keys.join(options.delimiter);
|
||||
var prefix = options.addQueryPrefix === true ? '?' : '';
|
||||
|
||||
if (options.charsetSentinel) {
|
||||
if (options.charset === 'iso-8859-1') {
|
||||
// encodeURIComponent('✓'), the "numeric entity" representation of a checkmark
|
||||
prefix += 'utf8=%26%2310003%3B&';
|
||||
} else {
|
||||
// encodeURIComponent('✓')
|
||||
prefix += 'utf8=%E2%9C%93&';
|
||||
}
|
||||
}
|
||||
|
||||
return joined.length > 0 ? prefix + joined : '';
|
||||
};
|
||||
|
||||
},{"./formats":1,"./utils":5}],5:[function(require,module,exports){
|
||||
'use strict';
|
||||
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
var isArray = Array.isArray;
|
||||
|
||||
var hexTable = (function () {
|
||||
var array = [];
|
||||
for (var i = 0; i < 256; ++i) {
|
||||
array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
|
||||
}
|
||||
|
||||
return array;
|
||||
}());
|
||||
|
||||
var compactQueue = function compactQueue(queue) {
|
||||
while (queue.length > 1) {
|
||||
var item = queue.pop();
|
||||
var obj = item.obj[item.prop];
|
||||
|
||||
if (isArray(obj)) {
|
||||
var compacted = [];
|
||||
|
||||
for (var j = 0; j < obj.length; ++j) {
|
||||
if (typeof obj[j] !== 'undefined') {
|
||||
compacted.push(obj[j]);
|
||||
}
|
||||
}
|
||||
|
||||
item.obj[item.prop] = compacted;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var arrayToObject = function arrayToObject(source, options) {
|
||||
var obj = options && options.plainObjects ? Object.create(null) : {};
|
||||
for (var i = 0; i < source.length; ++i) {
|
||||
if (typeof source[i] !== 'undefined') {
|
||||
obj[i] = source[i];
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
var merge = function merge(target, source, options) {
|
||||
if (!source) {
|
||||
return target;
|
||||
}
|
||||
|
||||
if (typeof source !== 'object') {
|
||||
if (isArray(target)) {
|
||||
target.push(source);
|
||||
} else if (target && typeof target === 'object') {
|
||||
if ((options && (options.plainObjects || options.allowPrototypes)) || !has.call(Object.prototype, source)) {
|
||||
target[source] = true;
|
||||
}
|
||||
} else {
|
||||
return [target, source];
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
if (!target || typeof target !== 'object') {
|
||||
return [target].concat(source);
|
||||
}
|
||||
|
||||
var mergeTarget = target;
|
||||
if (isArray(target) && !isArray(source)) {
|
||||
mergeTarget = arrayToObject(target, options);
|
||||
}
|
||||
|
||||
if (isArray(target) && isArray(source)) {
|
||||
source.forEach(function (item, i) {
|
||||
if (has.call(target, i)) {
|
||||
var targetItem = target[i];
|
||||
if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
|
||||
target[i] = merge(targetItem, item, options);
|
||||
} else {
|
||||
target.push(item);
|
||||
}
|
||||
} else {
|
||||
target[i] = item;
|
||||
}
|
||||
});
|
||||
return target;
|
||||
}
|
||||
|
||||
return Object.keys(source).reduce(function (acc, key) {
|
||||
var value = source[key];
|
||||
|
||||
if (has.call(acc, key)) {
|
||||
acc[key] = merge(acc[key], value, options);
|
||||
} else {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, mergeTarget);
|
||||
};
|
||||
|
||||
var assign = function assignSingleSource(target, source) {
|
||||
return Object.keys(source).reduce(function (acc, key) {
|
||||
acc[key] = source[key];
|
||||
return acc;
|
||||
}, target);
|
||||
};
|
||||
|
||||
var decode = function (str, decoder, charset) {
|
||||
var strWithoutPlus = str.replace(/\+/g, ' ');
|
||||
if (charset === 'iso-8859-1') {
|
||||
// unescape never throws, no try...catch needed:
|
||||
return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
|
||||
}
|
||||
// utf-8
|
||||
try {
|
||||
return decodeURIComponent(strWithoutPlus);
|
||||
} catch (e) {
|
||||
return strWithoutPlus;
|
||||
}
|
||||
};
|
||||
|
||||
var encode = function encode(str, defaultEncoder, charset) {
|
||||
// This code was originally written by Brian White (mscdex) for the io.js core querystring library.
|
||||
// It has been adapted here for stricter adherence to RFC 3986
|
||||
if (str.length === 0) {
|
||||
return str;
|
||||
}
|
||||
|
||||
var string = str;
|
||||
if (typeof str === 'symbol') {
|
||||
string = Symbol.prototype.toString.call(str);
|
||||
} else if (typeof str !== 'string') {
|
||||
string = String(str);
|
||||
}
|
||||
|
||||
if (charset === 'iso-8859-1') {
|
||||
return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
|
||||
return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
|
||||
});
|
||||
}
|
||||
|
||||
var out = '';
|
||||
for (var i = 0; i < string.length; ++i) {
|
||||
var c = string.charCodeAt(i);
|
||||
|
||||
if (
|
||||
c === 0x2D // -
|
||||
|| c === 0x2E // .
|
||||
|| c === 0x5F // _
|
||||
|| c === 0x7E // ~
|
||||
|| (c >= 0x30 && c <= 0x39) // 0-9
|
||||
|| (c >= 0x41 && c <= 0x5A) // a-z
|
||||
|| (c >= 0x61 && c <= 0x7A) // A-Z
|
||||
) {
|
||||
out += string.charAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c < 0x80) {
|
||||
out = out + hexTable[c];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c < 0x800) {
|
||||
out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c < 0xD800 || c >= 0xE000) {
|
||||
out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
|
||||
continue;
|
||||
}
|
||||
|
||||
i += 1;
|
||||
c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
|
||||
out += hexTable[0xF0 | (c >> 18)]
|
||||
+ hexTable[0x80 | ((c >> 12) & 0x3F)]
|
||||
+ hexTable[0x80 | ((c >> 6) & 0x3F)]
|
||||
+ hexTable[0x80 | (c & 0x3F)];
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
var compact = function compact(value) {
|
||||
var queue = [{ obj: { o: value }, prop: 'o' }];
|
||||
var refs = [];
|
||||
|
||||
for (var i = 0; i < queue.length; ++i) {
|
||||
var item = queue[i];
|
||||
var obj = item.obj[item.prop];
|
||||
|
||||
var keys = Object.keys(obj);
|
||||
for (var j = 0; j < keys.length; ++j) {
|
||||
var key = keys[j];
|
||||
var val = obj[key];
|
||||
if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
|
||||
queue.push({ obj: obj, prop: key });
|
||||
refs.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compactQueue(queue);
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
var isRegExp = function isRegExp(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object RegExp]';
|
||||
};
|
||||
|
||||
var isBuffer = function isBuffer(obj) {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
|
||||
};
|
||||
|
||||
var combine = function combine(a, b) {
|
||||
return [].concat(a, b);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
arrayToObject: arrayToObject,
|
||||
assign: assign,
|
||||
combine: combine,
|
||||
compact: compact,
|
||||
decode: decode,
|
||||
encode: encode,
|
||||
isBuffer: isBuffer,
|
||||
isRegExp: isRegExp,
|
||||
merge: merge
|
||||
};
|
||||
|
||||
},{}]},{},[2])(2)
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
import http from './http.js'
|
||||
let URL_CONFIG = '/api/'
|
||||
const UserApi = {
|
||||
// 登录
|
||||
login: (params) => http.post(`${URL_CONFIG}sys/login`, params),
|
||||
// 获得公钥
|
||||
getRSAPublicKey: (params) => http.get(`${URL_CONFIG}sys/getRSAPublicKey`, params),
|
||||
// 图片的验证码
|
||||
getImgCode: (params, urlParam) => http.get(`${URL_CONFIG}sys/randomImage/${urlParam}`, params),
|
||||
// 退出
|
||||
logout: (params) => http.post(`${URL_CONFIG}sys/logout`, params),
|
||||
//修改密码
|
||||
upDatePass:(params) => http.put(`${URL_CONFIG}sys/user/updatePassword`, params),
|
||||
|
||||
}
|
||||
|
||||
export default UserApi
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
// import JSEncrypt from '../jsencrypt/jsencrypt'
|
||||
// import JSEncrypt from '../jsencrypt/jsencryptInit'
|
||||
import JSEncrypt from '../jsencrypt/jsencryptInit'
|
||||
export function encrypt(publicKey, message) {
|
||||
const encrypt = new JSEncrypt()
|
||||
encrypt.setPublicKey(publicKey) // publicKey为公钥
|
||||
return encrypt.encrypt(message)
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// components/Dialog/dialog.js
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true // 在组件定义时的选项中启用多slot支持
|
||||
},
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
// 弹窗标题
|
||||
title: { // 属性名
|
||||
type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
|
||||
value: '标题' // 属性初始值(可选),如果未指定则会根据类型选择一个
|
||||
},
|
||||
// 弹窗内容
|
||||
content: {
|
||||
type: String,
|
||||
value: '弹窗内容'
|
||||
},
|
||||
// 弹窗取消按钮文字
|
||||
cancelText: {
|
||||
type: String,
|
||||
value: '取消'
|
||||
},
|
||||
// 弹窗确认按钮文字
|
||||
confirmText: {
|
||||
type: String,
|
||||
value: '确定'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
// 弹窗显示控制
|
||||
isShow: false
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
/*
|
||||
* 公有方法
|
||||
*/
|
||||
|
||||
//隐藏弹框
|
||||
hideDialog() {
|
||||
this.setData({
|
||||
isShow: !this.data.isShow
|
||||
})
|
||||
},
|
||||
//展示弹框
|
||||
showDialog() {
|
||||
this.setData({
|
||||
isShow: !this.data.isShow
|
||||
})
|
||||
},
|
||||
/*
|
||||
* 内部私有方法建议以下划线开头
|
||||
* triggerEvent 用于触发事件
|
||||
*/
|
||||
_cancelEvent() {
|
||||
//触发取消回调
|
||||
this.triggerEvent("cancelEvent")
|
||||
},
|
||||
_confirmEvent() {
|
||||
//触发成功回调
|
||||
this.triggerEvent("confirmEvent");
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<!--components/Dialog/dialog.wxml-->
|
||||
<!--components/Dialog/dialog.wxml-->
|
||||
<view class='wx_dialog_container' hidden="{{!isShow}}">
|
||||
<view class='wx-mask'></view>
|
||||
<view class='wx-dialog'>
|
||||
<view class='wx-dialog-title'>{{ title }}</view>
|
||||
<view class='wx-dialog-content'>{{ content }}</view>
|
||||
<view class='wx-dialog-footer'>
|
||||
<view class='wx-dialog-btn' catchtap='_cancelEvent'>{{ cancelText }}</view>
|
||||
<view class='wx-dialog-btn' catchtap='_confirmEvent'>{{ confirmText }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,95 @@
|
||||
/* components/Dialog/dialog.wxss */
|
||||
/* components/Dialog/dialog.wxss */
|
||||
.wx-mask {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.wx-dialog {
|
||||
position: fixed;
|
||||
z-index: 5000;
|
||||
width: 80%;
|
||||
max-width: 600rpx;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: #FFFFFF;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wx-dialog-title {
|
||||
font-size: 18px;
|
||||
padding: 15px 15px 5px;
|
||||
}
|
||||
|
||||
.wx-dialog-content {
|
||||
padding: 15px 15px 5px;
|
||||
min-height: 40px;
|
||||
font-size: 16px;
|
||||
line-height: 1.3;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.wx-dialog-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
line-height: 45px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.wx-dialog-footer::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-top: 1px solid #D5D5D6;
|
||||
color: #D5D5D6;
|
||||
-webkit-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-transform: scaleY(0.5);
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.wx-dialog-btn {
|
||||
display: block;
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wx-dialog-footer .wx-dialog-btn:nth-of-type(1) {
|
||||
color: #353535;
|
||||
}
|
||||
|
||||
.wx-dialog-footer .wx-dialog-btn:nth-of-type(2) {
|
||||
color: #3CC51F;
|
||||
}
|
||||
|
||||
.wx-dialog-footer .wx-dialog-btn:nth-of-type(2):after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 1px;
|
||||
bottom: 0;
|
||||
border-left: 1px solid #D5D5D6;
|
||||
color: #D5D5D6;
|
||||
-webkit-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-transform: scaleX(0.5);
|
||||
transform: scaleX(0.5);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// components/getPhoneNumer/getPhoneNumber.js
|
||||
const app = getApp()
|
||||
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
appid:{
|
||||
type: String,
|
||||
value:''
|
||||
},
|
||||
secret: {
|
||||
type: String,
|
||||
value:''
|
||||
}
|
||||
},
|
||||
// 可以定义外部样式类 影响组件的样式
|
||||
externalClasses: ['class'],
|
||||
options: {
|
||||
// 配置样式是否可以被父组件影响 详细见文档
|
||||
styleIsolation: 'apply-shared'
|
||||
},
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
// session_key
|
||||
session_key:'',
|
||||
// 用户openid
|
||||
openid:''
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
getPhoneNumber(e) {
|
||||
console.log(e);
|
||||
const that = this
|
||||
wx.checkSession({
|
||||
success: (res) => {
|
||||
console.log(res);
|
||||
if(e.detail.errMsg == 'getPhoneNumber:fail user deny'){
|
||||
console.log("用户拒绝了授权");
|
||||
return
|
||||
}else{
|
||||
console.log("用户同意了授权");
|
||||
let key = that.data.session_key
|
||||
let phone = e.detail.encryptedData;
|
||||
let iv = e.detail.iv;
|
||||
const RdWXBizDataCrypt = require('./utils/RdWXBizDataCrypt');
|
||||
const pc = new RdWXBizDataCrypt(that.data.appid, key);
|
||||
const data = pc.decryptData(phone, iv);
|
||||
console.log(data.phoneNumber); //当前手机号码
|
||||
that.triggerEvent("myevent",data)
|
||||
}
|
||||
},
|
||||
fail:(err) => {
|
||||
console.log("登录状态失效,请重新登录",err);
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件生命周期
|
||||
*/
|
||||
lifetimes: {
|
||||
attached(){
|
||||
const that = this
|
||||
wx.login({
|
||||
timeout: 2000,
|
||||
success(res){
|
||||
wx.request({
|
||||
url: `https://api.weixin.qq.com/sns/jscode2session?appid=${that.data.appid}&secret=${that.data.secret}&js_code=${res.code}&grant_type=authorization_code`,
|
||||
success(result){
|
||||
that.setData({
|
||||
session_key:result.data.session_key,
|
||||
openid:result.data.openid
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<!--components/getPhoneNumer/getPhoneNumber.wxml-->
|
||||
<view>
|
||||
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" class="button">
|
||||
<slot></slot>
|
||||
</button>
|
||||
</view>
|
||||
@@ -0,0 +1 @@
|
||||
/* components/getPhoneNumer/getPhoneNumber.wxss */
|
||||
@@ -0,0 +1,34 @@
|
||||
var Crypto = require('./cryptojs/cryptojs.js').Crypto;
|
||||
var app = getApp();
|
||||
|
||||
function RdWXBizDataCrypt(appId, sessionKey) {
|
||||
this.appId = appId
|
||||
this.sessionKey = sessionKey
|
||||
}
|
||||
RdWXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
|
||||
// base64 decode :使用 CryptoJS 中 Crypto.util.base64ToBytes()进行 base64解码
|
||||
var encryptedData = Crypto.util.base64ToBytes(encryptedData)
|
||||
// console.log(sessionKey)
|
||||
var key = Crypto.util.base64ToBytes(this.sessionKey);
|
||||
var iv = Crypto.util.base64ToBytes(iv);
|
||||
// console.log(encryptedData,key,iv)
|
||||
// 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充
|
||||
var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
|
||||
try {
|
||||
// 解密
|
||||
var bytes = Crypto.AES.decrypt(encryptedData, key, {
|
||||
asBpytes: true,
|
||||
iv: iv,
|
||||
mode: mode
|
||||
});
|
||||
var decryptResult = JSON.parse(bytes);
|
||||
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
}
|
||||
if (decryptResult.watermark.appid !== this.appId) {
|
||||
console.log(err)
|
||||
}
|
||||
return decryptResult
|
||||
}
|
||||
module.exports = RdWXBizDataCrypt
|
||||
@@ -0,0 +1,32 @@
|
||||
cryptojs
|
||||
--------
|
||||
|
||||
* with little modification, converted from googlecode project [crypto-js](http://code.google.com/p/crypto-js/), and keep the source code structure of the origin project on googlecode
|
||||
* source code worked in both browser engines and node scripts. see also: [https://github.com/gwjjeff/crypto-js-npm-conv](https://github.com/gwjjeff/crypto-js-npm-conv)
|
||||
* inspiration comes from [ezcrypto](https://github.com/ElmerZhang/ezcrypto), but my tests cannot pass with his version ( ECB/pkcs7 mode ), so I made it myself
|
||||
|
||||
### install
|
||||
|
||||
```
|
||||
npm install cryptojs
|
||||
```
|
||||
|
||||
### usage (example with [coffee-script](http://coffeescript.org/))
|
||||
|
||||
```coffee
|
||||
Crypto = (require 'cryptojs').Crypto
|
||||
key = '12345678'
|
||||
us = 'Hello, 世界!'
|
||||
|
||||
mode = new Crypto.mode.ECB Crypto.pad.pkcs7
|
||||
|
||||
ub = Crypto.charenc.UTF8.stringToBytes us
|
||||
eb = Crypto.DES.encrypt ub, key, {asBytes: true, mode: mode}
|
||||
ehs= Crypto.util.bytesToHex eb
|
||||
|
||||
eb2= Crypto.util.hexToBytes ehs
|
||||
ub2= Crypto.DES.decrypt eb2, key, {asBytes: true, mode: mode}
|
||||
us2= Crypto.charenc.UTF8.bytesToString ub2
|
||||
# should be same as the var 'us'
|
||||
console .log us2
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
var Crypto = exports.Crypto = require('./lib/Crypto').Crypto;
|
||||
|
||||
[ 'CryptoMath'
|
||||
, 'BlockModes'
|
||||
, 'DES'
|
||||
, 'AES'
|
||||
, 'HMAC'
|
||||
, 'MARC4'
|
||||
, 'MD5'
|
||||
, 'PBKDF2'
|
||||
, 'PBKDF2Async'
|
||||
, 'Rabbit'
|
||||
, 'SHA1'
|
||||
, 'SHA256'
|
||||
].forEach( function (path) {
|
||||
require('./lib/' + path);
|
||||
});
|
||||
@@ -0,0 +1,402 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8;
|
||||
|
||||
// Precomputed SBOX
|
||||
var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
||||
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
|
||||
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
|
||||
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
|
||||
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
|
||||
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
|
||||
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
||||
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
|
||||
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
|
||||
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
|
||||
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
|
||||
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
|
||||
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
|
||||
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
|
||||
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
|
||||
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
|
||||
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ];
|
||||
|
||||
// Compute inverse SBOX lookup table
|
||||
for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
|
||||
|
||||
// Compute mulitplication in GF(2^8) lookup tables
|
||||
var MULT2 = [],
|
||||
MULT3 = [],
|
||||
MULT9 = [],
|
||||
MULTB = [],
|
||||
MULTD = [],
|
||||
MULTE = [];
|
||||
|
||||
function xtime(a, b) {
|
||||
for (var result = 0, i = 0; i < 8; i++) {
|
||||
if (b & 1) result ^= a;
|
||||
var hiBitSet = a & 0x80;
|
||||
a = (a << 1) & 0xFF;
|
||||
if (hiBitSet) a ^= 0x1b;
|
||||
b >>>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
for (var i = 0; i < 256; i++) {
|
||||
MULT2[i] = xtime(i,2);
|
||||
MULT3[i] = xtime(i,3);
|
||||
MULT9[i] = xtime(i,9);
|
||||
MULTB[i] = xtime(i,0xB);
|
||||
MULTD[i] = xtime(i,0xD);
|
||||
MULTE[i] = xtime(i,0xE);
|
||||
}
|
||||
|
||||
// Precomputed RCon lookup
|
||||
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
|
||||
|
||||
// Inner state
|
||||
var state = [[], [], [], []],
|
||||
keylength,
|
||||
nrounds,
|
||||
keyschedule;
|
||||
|
||||
var AES = C.AES = {
|
||||
|
||||
/**
|
||||
* Public API
|
||||
*/
|
||||
|
||||
encrypt: function (message, password, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
// Determine mode
|
||||
var mode = options.mode || new C.mode.OFB;
|
||||
|
||||
// Allow mode to override options
|
||||
if (mode.fixOptions) mode.fixOptions(options);
|
||||
|
||||
var
|
||||
|
||||
// Convert to bytes if message is a string
|
||||
m = (
|
||||
message.constructor == String ?
|
||||
UTF8.stringToBytes(message) :
|
||||
message
|
||||
),
|
||||
|
||||
// Generate random IV
|
||||
iv = options.iv || util.randomBytes(AES._blocksize * 4),
|
||||
|
||||
// Generate key
|
||||
k = (
|
||||
password.constructor == String ?
|
||||
// Derive key from passphrase
|
||||
C.PBKDF2(password, iv, 32, { asBytes: true }) :
|
||||
// else, assume byte array representing cryptographic key
|
||||
password
|
||||
);
|
||||
|
||||
// Encrypt
|
||||
AES._init(k);
|
||||
mode.encrypt(AES, m, iv);
|
||||
|
||||
// Return ciphertext
|
||||
m = options.iv ? m : iv.concat(m);
|
||||
return (options && options.asBytes) ? m : util.bytesToBase64(m);
|
||||
|
||||
},
|
||||
|
||||
decrypt: function (ciphertext, password, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
// Determine mode
|
||||
var mode = options.mode || new C.mode.OFB;
|
||||
|
||||
// Allow mode to override options
|
||||
if (mode.fixOptions) mode.fixOptions(options);
|
||||
|
||||
var
|
||||
|
||||
// Convert to bytes if ciphertext is a string
|
||||
c = (
|
||||
ciphertext.constructor == String ?
|
||||
util.base64ToBytes(ciphertext):
|
||||
ciphertext
|
||||
),
|
||||
|
||||
// Separate IV and message
|
||||
iv = options.iv || c.splice(0, AES._blocksize * 4),
|
||||
|
||||
// Generate key
|
||||
k = (
|
||||
password.constructor == String ?
|
||||
// Derive key from passphrase
|
||||
C.PBKDF2(password, iv, 32, { asBytes: true }) :
|
||||
// else, assume byte array representing cryptographic key
|
||||
password
|
||||
);
|
||||
|
||||
// Decrypt
|
||||
AES._init(k);
|
||||
mode.decrypt(AES, c, iv);
|
||||
|
||||
// Return plaintext
|
||||
return (options && options.asBytes) ? c : UTF8.bytesToString(c);
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Package private methods and properties
|
||||
*/
|
||||
|
||||
_blocksize: 4,
|
||||
|
||||
_encryptblock: function (m, offset) {
|
||||
|
||||
// Set input
|
||||
for (var row = 0; row < AES._blocksize; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] = m[offset + col * 4 + row];
|
||||
}
|
||||
|
||||
// Add round key
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] ^= keyschedule[col][row];
|
||||
}
|
||||
|
||||
for (var round = 1; round < nrounds; round++) {
|
||||
|
||||
// Sub bytes
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] = SBOX[state[row][col]];
|
||||
}
|
||||
|
||||
// Shift rows
|
||||
state[1].push(state[1].shift());
|
||||
state[2].push(state[2].shift());
|
||||
state[2].push(state[2].shift());
|
||||
state[3].unshift(state[3].pop());
|
||||
|
||||
// Mix columns
|
||||
for (var col = 0; col < 4; col++) {
|
||||
|
||||
var s0 = state[0][col],
|
||||
s1 = state[1][col],
|
||||
s2 = state[2][col],
|
||||
s3 = state[3][col];
|
||||
|
||||
state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
|
||||
state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
|
||||
state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
|
||||
state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
|
||||
|
||||
}
|
||||
|
||||
// Add round key
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] ^= keyschedule[round * 4 + col][row];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Sub bytes
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] = SBOX[state[row][col]];
|
||||
}
|
||||
|
||||
// Shift rows
|
||||
state[1].push(state[1].shift());
|
||||
state[2].push(state[2].shift());
|
||||
state[2].push(state[2].shift());
|
||||
state[3].unshift(state[3].pop());
|
||||
|
||||
// Add round key
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
|
||||
}
|
||||
|
||||
// Set output
|
||||
for (var row = 0; row < AES._blocksize; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
m[offset + col * 4 + row] = state[row][col];
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_decryptblock: function (c, offset) {
|
||||
|
||||
// Set input
|
||||
for (var row = 0; row < AES._blocksize; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] = c[offset + col * 4 + row];
|
||||
}
|
||||
|
||||
// Add round key
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] ^= keyschedule[nrounds * 4 + col][row];
|
||||
}
|
||||
|
||||
for (var round = 1; round < nrounds; round++) {
|
||||
|
||||
// Inv shift rows
|
||||
state[1].unshift(state[1].pop());
|
||||
state[2].push(state[2].shift());
|
||||
state[2].push(state[2].shift());
|
||||
state[3].push(state[3].shift());
|
||||
|
||||
// Inv sub bytes
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] = INVSBOX[state[row][col]];
|
||||
}
|
||||
|
||||
// Add round key
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
|
||||
}
|
||||
|
||||
// Inv mix columns
|
||||
for (var col = 0; col < 4; col++) {
|
||||
|
||||
var s0 = state[0][col],
|
||||
s1 = state[1][col],
|
||||
s2 = state[2][col],
|
||||
s3 = state[3][col];
|
||||
|
||||
state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
|
||||
state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
|
||||
state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
|
||||
state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Inv shift rows
|
||||
state[1].unshift(state[1].pop());
|
||||
state[2].push(state[2].shift());
|
||||
state[2].push(state[2].shift());
|
||||
state[3].push(state[3].shift());
|
||||
|
||||
// Inv sub bytes
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] = INVSBOX[state[row][col]];
|
||||
}
|
||||
|
||||
// Add round key
|
||||
for (var row = 0; row < 4; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
state[row][col] ^= keyschedule[col][row];
|
||||
}
|
||||
|
||||
// Set output
|
||||
for (var row = 0; row < AES._blocksize; row++) {
|
||||
for (var col = 0; col < 4; col++)
|
||||
c[offset + col * 4 + row] = state[row][col];
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Private methods
|
||||
*/
|
||||
|
||||
_init: function (k) {
|
||||
keylength = k.length / 4;
|
||||
nrounds = keylength + 6;
|
||||
AES._keyexpansion(k);
|
||||
},
|
||||
|
||||
// Generate a key schedule
|
||||
_keyexpansion: function (k) {
|
||||
|
||||
keyschedule = [];
|
||||
|
||||
for (var row = 0; row < keylength; row++) {
|
||||
keyschedule[row] = [
|
||||
k[row * 4],
|
||||
k[row * 4 + 1],
|
||||
k[row * 4 + 2],
|
||||
k[row * 4 + 3]
|
||||
];
|
||||
}
|
||||
|
||||
for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
|
||||
|
||||
var temp = [
|
||||
keyschedule[row - 1][0],
|
||||
keyschedule[row - 1][1],
|
||||
keyschedule[row - 1][2],
|
||||
keyschedule[row - 1][3]
|
||||
];
|
||||
|
||||
if (row % keylength == 0) {
|
||||
|
||||
// Rot word
|
||||
temp.push(temp.shift());
|
||||
|
||||
// Sub word
|
||||
temp[0] = SBOX[temp[0]];
|
||||
temp[1] = SBOX[temp[1]];
|
||||
temp[2] = SBOX[temp[2]];
|
||||
temp[3] = SBOX[temp[3]];
|
||||
|
||||
temp[0] ^= RCON[row / keylength];
|
||||
|
||||
} else if (keylength > 6 && row % keylength == 4) {
|
||||
|
||||
// Sub word
|
||||
temp[0] = SBOX[temp[0]];
|
||||
temp[1] = SBOX[temp[1]];
|
||||
temp[2] = SBOX[temp[2]];
|
||||
temp[3] = SBOX[temp[3]];
|
||||
|
||||
}
|
||||
|
||||
keyschedule[row] = [
|
||||
keyschedule[row - keylength][0] ^ temp[0],
|
||||
keyschedule[row - keylength][1] ^ temp[1],
|
||||
keyschedule[row - keylength][2] ^ temp[2],
|
||||
keyschedule[row - keylength][3] ^ temp[3]
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,378 @@
|
||||
/*!
|
||||
* Crypto-JS contribution from Simon Greatrix
|
||||
*/
|
||||
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Create pad namespace
|
||||
var C_pad = C.pad = {};
|
||||
|
||||
// Calculate the number of padding bytes required.
|
||||
function _requiredPadding(cipher, message) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4;
|
||||
var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
|
||||
return reqd;
|
||||
};
|
||||
|
||||
// Remove padding when the final byte gives the number of padding bytes.
|
||||
var _unpadLength = function (message) {
|
||||
var pad = message.pop();
|
||||
for (var i = 1; i < pad; i++) {
|
||||
message.pop();
|
||||
}
|
||||
};
|
||||
|
||||
// No-operation padding, used for stream ciphers
|
||||
C_pad.NoPadding = {
|
||||
pad : function (cipher,message) {},
|
||||
unpad : function (message) {}
|
||||
};
|
||||
|
||||
// Zero Padding.
|
||||
//
|
||||
// If the message is not an exact number of blocks, the final block is
|
||||
// completed with 0x00 bytes. There is no unpadding.
|
||||
C_pad.ZeroPadding = {
|
||||
pad : function (cipher, message) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4;
|
||||
var reqd = message.length % blockSizeInBytes;
|
||||
if( reqd!=0 ) {
|
||||
for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) {
|
||||
message.push(0x00);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
unpad : function (message) {}
|
||||
};
|
||||
|
||||
// ISO/IEC 7816-4 padding.
|
||||
//
|
||||
// Pads the plain text with an 0x80 byte followed by as many 0x00
|
||||
// bytes are required to complete the block.
|
||||
C_pad.iso7816 = {
|
||||
pad : function (cipher, message) {
|
||||
var reqd = _requiredPadding(cipher, message);
|
||||
message.push(0x80);
|
||||
for (; reqd > 1; reqd--) {
|
||||
message.push(0x00);
|
||||
}
|
||||
},
|
||||
|
||||
unpad : function (message) {
|
||||
while (message.pop() != 0x80) {}
|
||||
}
|
||||
};
|
||||
|
||||
// ANSI X.923 padding
|
||||
//
|
||||
// The final block is padded with zeros except for the last byte of the
|
||||
// last block which contains the number of padding bytes.
|
||||
C_pad.ansix923 = {
|
||||
pad : function (cipher, message) {
|
||||
var reqd = _requiredPadding(cipher, message);
|
||||
for (var i = 1; i < reqd; i++) {
|
||||
message.push(0x00);
|
||||
}
|
||||
message.push(reqd);
|
||||
},
|
||||
|
||||
unpad : _unpadLength
|
||||
};
|
||||
|
||||
// ISO 10126
|
||||
//
|
||||
// The final block is padded with random bytes except for the last
|
||||
// byte of the last block which contains the number of padding bytes.
|
||||
C_pad.iso10126 = {
|
||||
pad : function (cipher, message) {
|
||||
var reqd = _requiredPadding(cipher, message);
|
||||
for (var i = 1; i < reqd; i++) {
|
||||
message.push(Math.floor(Math.random() * 256));
|
||||
}
|
||||
message.push(reqd);
|
||||
},
|
||||
|
||||
unpad : _unpadLength
|
||||
};
|
||||
|
||||
// PKCS7 padding
|
||||
//
|
||||
// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
|
||||
// value of each added byte is the number of bytes that are added,
|
||||
// i.e. N bytes, each of value N are added.
|
||||
C_pad.pkcs7 = {
|
||||
pad : function (cipher, message) {
|
||||
var reqd = _requiredPadding(cipher, message);
|
||||
for (var i = 0; i < reqd; i++) {
|
||||
message.push(reqd);
|
||||
}
|
||||
},
|
||||
|
||||
unpad : _unpadLength
|
||||
};
|
||||
|
||||
// Create mode namespace
|
||||
var C_mode = C.mode = {};
|
||||
|
||||
/**
|
||||
* Mode base "class".
|
||||
*/
|
||||
var Mode = C_mode.Mode = function (padding) {
|
||||
if (padding) {
|
||||
this._padding = padding;
|
||||
}
|
||||
};
|
||||
|
||||
Mode.prototype = {
|
||||
encrypt: function (cipher, m, iv) {
|
||||
this._padding.pad(cipher, m);
|
||||
this._doEncrypt(cipher, m, iv);
|
||||
},
|
||||
|
||||
decrypt: function (cipher, m, iv) {
|
||||
this._doDecrypt(cipher, m, iv);
|
||||
this._padding.unpad(m);
|
||||
},
|
||||
|
||||
// Default padding
|
||||
_padding: C_pad.iso7816
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Electronic Code Book mode.
|
||||
*
|
||||
* ECB applies the cipher directly against each block of the input.
|
||||
*
|
||||
* ECB does not require an initialization vector.
|
||||
*/
|
||||
var ECB = C_mode.ECB = function () {
|
||||
// Call parent constructor
|
||||
Mode.apply(this, arguments);
|
||||
};
|
||||
|
||||
// Inherit from Mode
|
||||
var ECB_prototype = ECB.prototype = new Mode;
|
||||
|
||||
// Concrete steps for Mode template
|
||||
ECB_prototype._doEncrypt = function (cipher, m, iv) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4;
|
||||
// Encrypt each block
|
||||
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
|
||||
cipher._encryptblock(m, offset);
|
||||
}
|
||||
};
|
||||
ECB_prototype._doDecrypt = function (cipher, c, iv) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4;
|
||||
// Decrypt each block
|
||||
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
|
||||
cipher._decryptblock(c, offset);
|
||||
}
|
||||
};
|
||||
|
||||
// ECB never uses an IV
|
||||
ECB_prototype.fixOptions = function (options) {
|
||||
options.iv = [];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cipher block chaining
|
||||
*
|
||||
* The first block is XORed with the IV. Subsequent blocks are XOR with the
|
||||
* previous cipher output.
|
||||
*/
|
||||
var CBC = C_mode.CBC = function () {
|
||||
// Call parent constructor
|
||||
Mode.apply(this, arguments);
|
||||
};
|
||||
|
||||
// Inherit from Mode
|
||||
var CBC_prototype = CBC.prototype = new Mode;
|
||||
|
||||
// Concrete steps for Mode template
|
||||
CBC_prototype._doEncrypt = function (cipher, m, iv) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4;
|
||||
|
||||
// Encrypt each block
|
||||
for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
|
||||
if (offset == 0) {
|
||||
// XOR first block using IV
|
||||
for (var i = 0; i < blockSizeInBytes; i++)
|
||||
m[i] ^= iv[i];
|
||||
} else {
|
||||
// XOR this block using previous crypted block
|
||||
for (var i = 0; i < blockSizeInBytes; i++)
|
||||
m[offset + i] ^= m[offset + i - blockSizeInBytes];
|
||||
}
|
||||
// Encrypt block
|
||||
cipher._encryptblock(m, offset);
|
||||
}
|
||||
};
|
||||
CBC_prototype._doDecrypt = function (cipher, c, iv) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4;
|
||||
|
||||
// At the start, the previously crypted block is the IV
|
||||
var prevCryptedBlock = iv;
|
||||
|
||||
// Decrypt each block
|
||||
for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
|
||||
// Save this crypted block
|
||||
var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
|
||||
// Decrypt block
|
||||
cipher._decryptblock(c, offset);
|
||||
// XOR decrypted block using previous crypted block
|
||||
for (var i = 0; i < blockSizeInBytes; i++) {
|
||||
c[offset + i] ^= prevCryptedBlock[i];
|
||||
}
|
||||
prevCryptedBlock = thisCryptedBlock;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cipher feed back
|
||||
*
|
||||
* The cipher output is XORed with the plain text to produce the cipher output,
|
||||
* which is then fed back into the cipher to produce a bit pattern to XOR the
|
||||
* next block with.
|
||||
*
|
||||
* This is a stream cipher mode and does not require padding.
|
||||
*/
|
||||
var CFB = C_mode.CFB = function () {
|
||||
// Call parent constructor
|
||||
Mode.apply(this, arguments);
|
||||
};
|
||||
|
||||
// Inherit from Mode
|
||||
var CFB_prototype = CFB.prototype = new Mode;
|
||||
|
||||
// Override padding
|
||||
CFB_prototype._padding = C_pad.NoPadding;
|
||||
|
||||
// Concrete steps for Mode template
|
||||
CFB_prototype._doEncrypt = function (cipher, m, iv) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4,
|
||||
keystream = iv.slice(0);
|
||||
|
||||
// Encrypt each byte
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
|
||||
var j = i % blockSizeInBytes;
|
||||
if (j == 0) cipher._encryptblock(keystream, 0);
|
||||
|
||||
m[i] ^= keystream[j];
|
||||
keystream[j] = m[i];
|
||||
}
|
||||
};
|
||||
CFB_prototype._doDecrypt = function (cipher, c, iv) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4,
|
||||
keystream = iv.slice(0);
|
||||
|
||||
// Encrypt each byte
|
||||
for (var i = 0; i < c.length; i++) {
|
||||
|
||||
var j = i % blockSizeInBytes;
|
||||
if (j == 0) cipher._encryptblock(keystream, 0);
|
||||
|
||||
var b = c[i];
|
||||
c[i] ^= keystream[j];
|
||||
keystream[j] = b;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Output feed back
|
||||
*
|
||||
* The cipher repeatedly encrypts its own output. The output is XORed with the
|
||||
* plain text to produce the cipher text.
|
||||
*
|
||||
* This is a stream cipher mode and does not require padding.
|
||||
*/
|
||||
var OFB = C_mode.OFB = function () {
|
||||
// Call parent constructor
|
||||
Mode.apply(this, arguments);
|
||||
};
|
||||
|
||||
// Inherit from Mode
|
||||
var OFB_prototype = OFB.prototype = new Mode;
|
||||
|
||||
// Override padding
|
||||
OFB_prototype._padding = C_pad.NoPadding;
|
||||
|
||||
// Concrete steps for Mode template
|
||||
OFB_prototype._doEncrypt = function (cipher, m, iv) {
|
||||
|
||||
var blockSizeInBytes = cipher._blocksize * 4,
|
||||
keystream = iv.slice(0);
|
||||
|
||||
// Encrypt each byte
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
|
||||
// Generate keystream
|
||||
if (i % blockSizeInBytes == 0)
|
||||
cipher._encryptblock(keystream, 0);
|
||||
|
||||
// Encrypt byte
|
||||
m[i] ^= keystream[i % blockSizeInBytes];
|
||||
|
||||
}
|
||||
};
|
||||
OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;
|
||||
|
||||
/**
|
||||
* Counter
|
||||
* @author Gergely Risko
|
||||
*
|
||||
* After every block the last 4 bytes of the IV is increased by one
|
||||
* with carry and that IV is used for the next block.
|
||||
*
|
||||
* This is a stream cipher mode and does not require padding.
|
||||
*/
|
||||
var CTR = C_mode.CTR = function () {
|
||||
// Call parent constructor
|
||||
Mode.apply(this, arguments);
|
||||
};
|
||||
|
||||
// Inherit from Mode
|
||||
var CTR_prototype = CTR.prototype = new Mode;
|
||||
|
||||
// Override padding
|
||||
CTR_prototype._padding = C_pad.NoPadding;
|
||||
|
||||
CTR_prototype._doEncrypt = function (cipher, m, iv) {
|
||||
var blockSizeInBytes = cipher._blocksize * 4;
|
||||
var counter = iv.slice(0);
|
||||
|
||||
for (var i = 0; i < m.length;) {
|
||||
// do not lose iv
|
||||
var keystream = counter.slice(0);
|
||||
|
||||
// Generate keystream for next block
|
||||
cipher._encryptblock(keystream, 0);
|
||||
|
||||
// XOR keystream with block
|
||||
for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
|
||||
m[i] ^= keystream[j];
|
||||
}
|
||||
|
||||
// Increase counter
|
||||
if(++(counter[blockSizeInBytes-1]) == 256) {
|
||||
counter[blockSizeInBytes-1] = 0;
|
||||
if(++(counter[blockSizeInBytes-2]) == 256) {
|
||||
counter[blockSizeInBytes-2] = 0;
|
||||
if(++(counter[blockSizeInBytes-3]) == 256) {
|
||||
counter[blockSizeInBytes-3] = 0;
|
||||
++(counter[blockSizeInBytes-4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,155 @@
|
||||
if (typeof Crypto == "undefined" || ! Crypto.util)
|
||||
{
|
||||
(function(){
|
||||
|
||||
var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
// Global Crypto object
|
||||
// with browser window or with node module
|
||||
var Crypto = (typeof window === 'undefined') ? exports.Crypto = {} : window.Crypto = {};
|
||||
|
||||
// Crypto utilities
|
||||
var util = Crypto.util = {
|
||||
|
||||
// Bit-wise rotate left
|
||||
rotl: function (n, b) {
|
||||
return (n << b) | (n >>> (32 - b));
|
||||
},
|
||||
|
||||
// Bit-wise rotate right
|
||||
rotr: function (n, b) {
|
||||
return (n << (32 - b)) | (n >>> b);
|
||||
},
|
||||
|
||||
// Swap big-endian to little-endian and vice versa
|
||||
endian: function (n) {
|
||||
|
||||
// If number given, swap endian
|
||||
if (n.constructor == Number) {
|
||||
return util.rotl(n, 8) & 0x00FF00FF |
|
||||
util.rotl(n, 24) & 0xFF00FF00;
|
||||
}
|
||||
|
||||
// Else, assume array and swap all items
|
||||
for (var i = 0; i < n.length; i++)
|
||||
n[i] = util.endian(n[i]);
|
||||
return n;
|
||||
|
||||
},
|
||||
|
||||
// Generate an array of any length of random bytes
|
||||
randomBytes: function (n) {
|
||||
for (var bytes = []; n > 0; n--)
|
||||
bytes.push(Math.floor(Math.random() * 256));
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a byte array to big-endian 32-bit words
|
||||
bytesToWords: function (bytes) {
|
||||
for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
|
||||
words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32);
|
||||
return words;
|
||||
},
|
||||
|
||||
// Convert big-endian 32-bit words to a byte array
|
||||
wordsToBytes: function (words) {
|
||||
for (var bytes = [], b = 0; b < words.length * 32; b += 8)
|
||||
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a byte array to a hex string
|
||||
bytesToHex: function (bytes) {
|
||||
for (var hex = [], i = 0; i < bytes.length; i++) {
|
||||
hex.push((bytes[i] >>> 4).toString(16));
|
||||
hex.push((bytes[i] & 0xF).toString(16));
|
||||
}
|
||||
return hex.join("");
|
||||
},
|
||||
|
||||
// Convert a hex string to a byte array
|
||||
hexToBytes: function (hex) {
|
||||
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
||||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a byte array to a base-64 string
|
||||
bytesToBase64: function (bytes) {
|
||||
|
||||
// Use browser-native function if it exists
|
||||
if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes));
|
||||
|
||||
for(var base64 = [], i = 0; i < bytes.length; i += 3) {
|
||||
var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
|
||||
for (var j = 0; j < 4; j++) {
|
||||
if (i * 8 + j * 6 <= bytes.length * 8)
|
||||
base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
|
||||
else base64.push("=");
|
||||
}
|
||||
}
|
||||
|
||||
return base64.join("");
|
||||
|
||||
},
|
||||
|
||||
// Convert a base-64 string to a byte array
|
||||
base64ToBytes: function (base64) {
|
||||
|
||||
// Use browser-native function if it exists
|
||||
if (typeof atob == "function") return Binary.stringToBytes(atob(base64));
|
||||
|
||||
// Remove non-base-64 characters
|
||||
base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
|
||||
|
||||
for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
|
||||
if (imod4 == 0) continue;
|
||||
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
|
||||
(base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Crypto character encodings
|
||||
var charenc = Crypto.charenc = {};
|
||||
|
||||
// UTF-8 encoding
|
||||
var UTF8 = charenc.UTF8 = {
|
||||
|
||||
// Convert a string to a byte array
|
||||
stringToBytes: function (str) {
|
||||
return Binary.stringToBytes(unescape(encodeURIComponent(str)));
|
||||
},
|
||||
|
||||
// Convert a byte array to a string
|
||||
bytesToString: function (bytes) {
|
||||
return decodeURIComponent(escape(Binary.bytesToString(bytes)));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Binary encoding
|
||||
var Binary = charenc.Binary = {
|
||||
|
||||
// Convert a string to a byte array
|
||||
stringToBytes: function (str) {
|
||||
for (var bytes = [], i = 0; i < str.length; i++)
|
||||
bytes.push(str.charCodeAt(i) & 0xFF);
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a byte array to a string
|
||||
bytesToString: function (bytes) {
|
||||
for (var str = [], i = 0; i < bytes.length; i++)
|
||||
str.push(String.fromCharCode(bytes[i]));
|
||||
return str.join("");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcut
|
||||
var util = C.util;
|
||||
|
||||
// Convert n to unsigned 32-bit integer
|
||||
util.u32 = function (n) {
|
||||
return n >>> 0;
|
||||
};
|
||||
|
||||
// Unsigned 32-bit addition
|
||||
util.add = function () {
|
||||
var result = this.u32(arguments[0]);
|
||||
for (var i = 1; i < arguments.length; i++)
|
||||
result = this.u32(result + this.u32(arguments[i]));
|
||||
return result;
|
||||
};
|
||||
|
||||
// Unsigned 32-bit multiplication
|
||||
util.mult = function (m, n) {
|
||||
return this.add((n & 0xFFFF0000) * m,
|
||||
(n & 0x0000FFFF) * m);
|
||||
};
|
||||
|
||||
// Unsigned 32-bit greater than (>) comparison
|
||||
util.gt = function (m, n) {
|
||||
return this.u32(m) > this.u32(n);
|
||||
};
|
||||
|
||||
// Unsigned 32-bit less than (<) comparison
|
||||
util.lt = function (m, n) {
|
||||
return this.u32(m) < this.u32(n);
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,38 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
C.HMAC = function (hasher, message, key, options) {
|
||||
|
||||
// Convert to byte arrays
|
||||
if (message.constructor == String) message = UTF8.stringToBytes(message);
|
||||
if (key.constructor == String) key = UTF8.stringToBytes(key);
|
||||
/* else, assume byte arrays already */
|
||||
|
||||
// Allow arbitrary length keys
|
||||
if (key.length > hasher._blocksize * 4)
|
||||
key = hasher(key, { asBytes: true });
|
||||
|
||||
// XOR keys with pad constants
|
||||
var okey = key.slice(0),
|
||||
ikey = key.slice(0);
|
||||
for (var i = 0; i < hasher._blocksize * 4; i++) {
|
||||
okey[i] ^= 0x5C;
|
||||
ikey[i] ^= 0x36;
|
||||
}
|
||||
|
||||
var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true });
|
||||
|
||||
return options && options.asBytes ? hmacbytes :
|
||||
options && options.asString ? Binary.bytesToString(hmacbytes) :
|
||||
util.bytesToHex(hmacbytes);
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,117 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
var MARC4 = C.MARC4 = {
|
||||
|
||||
/**
|
||||
* Public API
|
||||
*/
|
||||
|
||||
encrypt: function (message, password) {
|
||||
|
||||
var
|
||||
|
||||
// Convert to bytes
|
||||
m = UTF8.stringToBytes(message),
|
||||
|
||||
// Generate random IV
|
||||
iv = util.randomBytes(16),
|
||||
|
||||
// Generate key
|
||||
k = password.constructor == String ?
|
||||
// Derive key from passphrase
|
||||
C.PBKDF2(password, iv, 32, { asBytes: true }) :
|
||||
// else, assume byte array representing cryptographic key
|
||||
password;
|
||||
|
||||
// Encrypt
|
||||
MARC4._marc4(m, k, 1536);
|
||||
|
||||
// Return ciphertext
|
||||
return util.bytesToBase64(iv.concat(m));
|
||||
|
||||
},
|
||||
|
||||
decrypt: function (ciphertext, password) {
|
||||
|
||||
var
|
||||
|
||||
// Convert to bytes
|
||||
c = util.base64ToBytes(ciphertext),
|
||||
|
||||
// Separate IV and message
|
||||
iv = c.splice(0, 16),
|
||||
|
||||
// Generate key
|
||||
k = password.constructor == String ?
|
||||
// Derive key from passphrase
|
||||
C.PBKDF2(password, iv, 32, { asBytes: true }) :
|
||||
// else, assume byte array representing cryptographic key
|
||||
password;
|
||||
|
||||
// Decrypt
|
||||
MARC4._marc4(c, k, 1536);
|
||||
|
||||
// Return plaintext
|
||||
return UTF8.bytesToString(c);
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
// The core
|
||||
_marc4: function (m, k, drop) {
|
||||
|
||||
// State variables
|
||||
var i, j, s, temp;
|
||||
|
||||
// Key setup
|
||||
for (i = 0, s = []; i < 256; i++) s[i] = i;
|
||||
for (i = 0, j = 0; i < 256; i++) {
|
||||
|
||||
j = (j + s[i] + k[i % k.length]) % 256;
|
||||
|
||||
// Swap
|
||||
temp = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = temp;
|
||||
|
||||
}
|
||||
|
||||
// Clear counters
|
||||
i = j = 0;
|
||||
|
||||
// Encryption
|
||||
for (var k = -drop; k < m.length; k++) {
|
||||
|
||||
i = (i + 1) % 256;
|
||||
j = (j + s[i]) % 256;
|
||||
|
||||
// Swap
|
||||
temp = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = temp;
|
||||
|
||||
// Stop here if we're still dropping keystream
|
||||
if (k < 0) continue;
|
||||
|
||||
// Encrypt
|
||||
m[k] ^= s[(s[i] + s[j]) % 256];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,158 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
// Public API
|
||||
var MD5 = C.MD5 = function (message, options) {
|
||||
var digestbytes = util.wordsToBytes(MD5._md5(message));
|
||||
return options && options.asBytes ? digestbytes :
|
||||
options && options.asString ? Binary.bytesToString(digestbytes) :
|
||||
util.bytesToHex(digestbytes);
|
||||
};
|
||||
|
||||
// The core
|
||||
MD5._md5 = function (message) {
|
||||
|
||||
// Convert to byte array
|
||||
if (message.constructor == String) message = UTF8.stringToBytes(message);
|
||||
/* else, assume byte array already */
|
||||
|
||||
var m = util.bytesToWords(message),
|
||||
l = message.length * 8,
|
||||
a = 1732584193,
|
||||
b = -271733879,
|
||||
c = -1732584194,
|
||||
d = 271733878;
|
||||
|
||||
// Swap endian
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |
|
||||
((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;
|
||||
}
|
||||
|
||||
// Padding
|
||||
m[l >>> 5] |= 0x80 << (l % 32);
|
||||
m[(((l + 64) >>> 9) << 4) + 14] = l;
|
||||
|
||||
// Method shortcuts
|
||||
var FF = MD5._ff,
|
||||
GG = MD5._gg,
|
||||
HH = MD5._hh,
|
||||
II = MD5._ii;
|
||||
|
||||
for (var i = 0; i < m.length; i += 16) {
|
||||
|
||||
var aa = a,
|
||||
bb = b,
|
||||
cc = c,
|
||||
dd = d;
|
||||
|
||||
a = FF(a, b, c, d, m[i+ 0], 7, -680876936);
|
||||
d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
|
||||
c = FF(c, d, a, b, m[i+ 2], 17, 606105819);
|
||||
b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
|
||||
a = FF(a, b, c, d, m[i+ 4], 7, -176418897);
|
||||
d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);
|
||||
c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
|
||||
b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
|
||||
a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);
|
||||
d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
|
||||
c = FF(c, d, a, b, m[i+10], 17, -42063);
|
||||
b = FF(b, c, d, a, m[i+11], 22, -1990404162);
|
||||
a = FF(a, b, c, d, m[i+12], 7, 1804603682);
|
||||
d = FF(d, a, b, c, m[i+13], 12, -40341101);
|
||||
c = FF(c, d, a, b, m[i+14], 17, -1502002290);
|
||||
b = FF(b, c, d, a, m[i+15], 22, 1236535329);
|
||||
|
||||
a = GG(a, b, c, d, m[i+ 1], 5, -165796510);
|
||||
d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);
|
||||
c = GG(c, d, a, b, m[i+11], 14, 643717713);
|
||||
b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
|
||||
a = GG(a, b, c, d, m[i+ 5], 5, -701558691);
|
||||
d = GG(d, a, b, c, m[i+10], 9, 38016083);
|
||||
c = GG(c, d, a, b, m[i+15], 14, -660478335);
|
||||
b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
|
||||
a = GG(a, b, c, d, m[i+ 9], 5, 568446438);
|
||||
d = GG(d, a, b, c, m[i+14], 9, -1019803690);
|
||||
c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
|
||||
b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);
|
||||
a = GG(a, b, c, d, m[i+13], 5, -1444681467);
|
||||
d = GG(d, a, b, c, m[i+ 2], 9, -51403784);
|
||||
c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);
|
||||
b = GG(b, c, d, a, m[i+12], 20, -1926607734);
|
||||
|
||||
a = HH(a, b, c, d, m[i+ 5], 4, -378558);
|
||||
d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
|
||||
c = HH(c, d, a, b, m[i+11], 16, 1839030562);
|
||||
b = HH(b, c, d, a, m[i+14], 23, -35309556);
|
||||
a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);
|
||||
d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);
|
||||
c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
|
||||
b = HH(b, c, d, a, m[i+10], 23, -1094730640);
|
||||
a = HH(a, b, c, d, m[i+13], 4, 681279174);
|
||||
d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
|
||||
c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
|
||||
b = HH(b, c, d, a, m[i+ 6], 23, 76029189);
|
||||
a = HH(a, b, c, d, m[i+ 9], 4, -640364487);
|
||||
d = HH(d, a, b, c, m[i+12], 11, -421815835);
|
||||
c = HH(c, d, a, b, m[i+15], 16, 530742520);
|
||||
b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
|
||||
|
||||
a = II(a, b, c, d, m[i+ 0], 6, -198630844);
|
||||
d = II(d, a, b, c, m[i+ 7], 10, 1126891415);
|
||||
c = II(c, d, a, b, m[i+14], 15, -1416354905);
|
||||
b = II(b, c, d, a, m[i+ 5], 21, -57434055);
|
||||
a = II(a, b, c, d, m[i+12], 6, 1700485571);
|
||||
d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
|
||||
c = II(c, d, a, b, m[i+10], 15, -1051523);
|
||||
b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
|
||||
a = II(a, b, c, d, m[i+ 8], 6, 1873313359);
|
||||
d = II(d, a, b, c, m[i+15], 10, -30611744);
|
||||
c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
|
||||
b = II(b, c, d, a, m[i+13], 21, 1309151649);
|
||||
a = II(a, b, c, d, m[i+ 4], 6, -145523070);
|
||||
d = II(d, a, b, c, m[i+11], 10, -1120210379);
|
||||
c = II(c, d, a, b, m[i+ 2], 15, 718787259);
|
||||
b = II(b, c, d, a, m[i+ 9], 21, -343485551);
|
||||
|
||||
a = (a + aa) >>> 0;
|
||||
b = (b + bb) >>> 0;
|
||||
c = (c + cc) >>> 0;
|
||||
d = (d + dd) >>> 0;
|
||||
|
||||
}
|
||||
|
||||
return util.endian([a, b, c, d]);
|
||||
|
||||
};
|
||||
|
||||
// Auxiliary functions
|
||||
MD5._ff = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b & c | ~b & d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
MD5._gg = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b & d | c & ~d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
MD5._hh = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b ^ c ^ d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
MD5._ii = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
|
||||
// Package private blocksize
|
||||
MD5._blocksize = 16;
|
||||
|
||||
MD5._digestsize = 16;
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,49 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
C.PBKDF2 = function (password, salt, keylen, options) {
|
||||
|
||||
// Convert to byte arrays
|
||||
if (password.constructor == String) password = UTF8.stringToBytes(password);
|
||||
if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
|
||||
/* else, assume byte arrays already */
|
||||
|
||||
// Defaults
|
||||
var hasher = options && options.hasher || C.SHA1,
|
||||
iterations = options && options.iterations || 1;
|
||||
|
||||
// Pseudo-random function
|
||||
function PRF(password, salt) {
|
||||
return C.HMAC(hasher, salt, password, { asBytes: true });
|
||||
}
|
||||
|
||||
// Generate key
|
||||
var derivedKeyBytes = [],
|
||||
blockindex = 1;
|
||||
while (derivedKeyBytes.length < keylen) {
|
||||
var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
|
||||
for (var u = block, i = 1; i < iterations; i++) {
|
||||
u = PRF(password, u);
|
||||
for (var j = 0; j < block.length; j++) block[j] ^= u[j];
|
||||
}
|
||||
derivedKeyBytes = derivedKeyBytes.concat(block);
|
||||
blockindex++;
|
||||
}
|
||||
|
||||
// Truncate excess bytes
|
||||
derivedKeyBytes.length = keylen;
|
||||
|
||||
return options && options.asBytes ? derivedKeyBytes :
|
||||
options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
|
||||
util.bytesToHex(derivedKeyBytes);
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,88 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
if (!C.nextTick) {
|
||||
// node.js has setTime out but prefer process.nextTick
|
||||
if (typeof process != 'undefined' && typeof process.nextTick !== 'undefined') {
|
||||
C.nextTick = process.nextTick;
|
||||
} else if (typeof setTimeout !== 'undefined') {
|
||||
C.nextTick = function (callback) {
|
||||
setTimeout(callback, 0);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
C.PBKDF2Async = function (password, salt, keylen, callback, options) {
|
||||
|
||||
// Convert to byte arrays
|
||||
if (password.constructor == String) password = UTF8.stringToBytes(password);
|
||||
if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
|
||||
/* else, assume byte arrays already */
|
||||
|
||||
// Defaults
|
||||
var hasher = options && options.hasher || C.SHA1,
|
||||
iterations = options && options.iterations || 1;
|
||||
|
||||
// Progress callback option
|
||||
var progressChangeHandler = options && options.onProgressChange;
|
||||
var totalIterations = Math.ceil(keylen / hasher._digestsize) * iterations;
|
||||
function fireProgressChange(currentIteration) {
|
||||
if (progressChangeHandler) {
|
||||
var iterationsSoFar = derivedKeyBytes.length / hasher._digestsize * iterations + currentIteration;
|
||||
setTimeout(function () {
|
||||
progressChangeHandler(Math.round(iterationsSoFar / totalIterations * 100));
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Pseudo-random function
|
||||
function PRF(password, salt) {
|
||||
return C.HMAC(hasher, salt, password, { asBytes: true });
|
||||
}
|
||||
|
||||
var nextTick = C.nextTick;
|
||||
|
||||
// Generate key
|
||||
var derivedKeyBytes = [],
|
||||
blockindex = 1;
|
||||
|
||||
var outer, inner;
|
||||
nextTick(outer = function () {
|
||||
if (derivedKeyBytes.length < keylen) {
|
||||
var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
|
||||
fireProgressChange(1);
|
||||
|
||||
var u = block, i = 1;
|
||||
nextTick(inner = function () {
|
||||
if (i < iterations) {
|
||||
u = PRF(password, u);
|
||||
for (var j = 0; j < block.length; j++) block[j] ^= u[j];
|
||||
i++;
|
||||
fireProgressChange(i);
|
||||
|
||||
nextTick(inner);
|
||||
} else {
|
||||
derivedKeyBytes = derivedKeyBytes.concat(block);
|
||||
blockindex++;
|
||||
nextTick(outer);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Truncate excess bytes
|
||||
derivedKeyBytes.length = keylen;
|
||||
callback(
|
||||
options && options.asBytes ? derivedKeyBytes :
|
||||
options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
|
||||
util.bytesToHex(derivedKeyBytes));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,221 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
// Inner state
|
||||
var x = [],
|
||||
c = [],
|
||||
b;
|
||||
|
||||
var Rabbit = C.Rabbit = {
|
||||
|
||||
/**
|
||||
* Public API
|
||||
*/
|
||||
|
||||
encrypt: function (message, password) {
|
||||
|
||||
var
|
||||
|
||||
// Convert to bytes
|
||||
m = UTF8.stringToBytes(message),
|
||||
|
||||
// Generate random IV
|
||||
iv = util.randomBytes(8),
|
||||
|
||||
// Generate key
|
||||
k = password.constructor == String ?
|
||||
// Derive key from passphrase
|
||||
C.PBKDF2(password, iv, 32, { asBytes: true }) :
|
||||
// else, assume byte array representing cryptographic key
|
||||
password;
|
||||
|
||||
// Encrypt
|
||||
Rabbit._rabbit(m, k, util.bytesToWords(iv));
|
||||
|
||||
// Return ciphertext
|
||||
return util.bytesToBase64(iv.concat(m));
|
||||
|
||||
},
|
||||
|
||||
decrypt: function (ciphertext, password) {
|
||||
|
||||
var
|
||||
|
||||
// Convert to bytes
|
||||
c = util.base64ToBytes(ciphertext),
|
||||
|
||||
// Separate IV and message
|
||||
iv = c.splice(0, 8),
|
||||
|
||||
// Generate key
|
||||
k = password.constructor == String ?
|
||||
// Derive key from passphrase
|
||||
C.PBKDF2(password, iv, 32, { asBytes: true }) :
|
||||
// else, assume byte array representing cryptographic key
|
||||
password;
|
||||
|
||||
// Decrypt
|
||||
Rabbit._rabbit(c, k, util.bytesToWords(iv));
|
||||
|
||||
// Return plaintext
|
||||
return UTF8.bytesToString(c);
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Internal methods
|
||||
*/
|
||||
|
||||
// Encryption/decryption scheme
|
||||
_rabbit: function (m, k, iv) {
|
||||
|
||||
Rabbit._keysetup(k);
|
||||
if (iv) Rabbit._ivsetup(iv);
|
||||
|
||||
for (var s = [], i = 0; i < m.length; i++) {
|
||||
|
||||
if (i % 16 == 0) {
|
||||
|
||||
// Iterate the system
|
||||
Rabbit._nextstate();
|
||||
|
||||
// Generate 16 bytes of pseudo-random data
|
||||
s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16);
|
||||
s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16);
|
||||
s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16);
|
||||
s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16);
|
||||
|
||||
// Swap endian
|
||||
for (var j = 0; j < 4; j++) {
|
||||
s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF |
|
||||
((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00;
|
||||
}
|
||||
|
||||
// Convert words to bytes
|
||||
for (var b = 120; b >= 0; b -= 8)
|
||||
s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF;
|
||||
|
||||
}
|
||||
|
||||
m[i] ^= s[i % 16];
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Key setup scheme
|
||||
_keysetup: function (k) {
|
||||
|
||||
// Generate initial state values
|
||||
x[0] = k[0];
|
||||
x[2] = k[1];
|
||||
x[4] = k[2];
|
||||
x[6] = k[3];
|
||||
x[1] = (k[3] << 16) | (k[2] >>> 16);
|
||||
x[3] = (k[0] << 16) | (k[3] >>> 16);
|
||||
x[5] = (k[1] << 16) | (k[0] >>> 16);
|
||||
x[7] = (k[2] << 16) | (k[1] >>> 16);
|
||||
|
||||
// Generate initial counter values
|
||||
c[0] = util.rotl(k[2], 16);
|
||||
c[2] = util.rotl(k[3], 16);
|
||||
c[4] = util.rotl(k[0], 16);
|
||||
c[6] = util.rotl(k[1], 16);
|
||||
c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF);
|
||||
c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF);
|
||||
c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF);
|
||||
c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF);
|
||||
|
||||
// Clear carry bit
|
||||
b = 0;
|
||||
|
||||
// Iterate the system four times
|
||||
for (var i = 0; i < 4; i++) Rabbit._nextstate();
|
||||
|
||||
// Modify the counters
|
||||
for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7];
|
||||
|
||||
},
|
||||
|
||||
// IV setup scheme
|
||||
_ivsetup: function (iv) {
|
||||
|
||||
// Generate four subvectors
|
||||
var i0 = util.endian(iv[0]),
|
||||
i2 = util.endian(iv[1]),
|
||||
i1 = (i0 >>> 16) | (i2 & 0xFFFF0000),
|
||||
i3 = (i2 << 16) | (i0 & 0x0000FFFF);
|
||||
|
||||
// Modify counter values
|
||||
c[0] ^= i0;
|
||||
c[1] ^= i1;
|
||||
c[2] ^= i2;
|
||||
c[3] ^= i3;
|
||||
c[4] ^= i0;
|
||||
c[5] ^= i1;
|
||||
c[6] ^= i2;
|
||||
c[7] ^= i3;
|
||||
|
||||
// Iterate the system four times
|
||||
for (var i = 0; i < 4; i++) Rabbit._nextstate();
|
||||
|
||||
},
|
||||
|
||||
// Next-state function
|
||||
_nextstate: function () {
|
||||
|
||||
// Save old counter values
|
||||
for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i];
|
||||
|
||||
// Calculate new counter values
|
||||
c[0] = (c[0] + 0x4D34D34D + b) >>> 0;
|
||||
c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0;
|
||||
c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0;
|
||||
c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0;
|
||||
c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0;
|
||||
c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0;
|
||||
c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0;
|
||||
c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0;
|
||||
b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0;
|
||||
|
||||
// Calculate the g-values
|
||||
for (var g = [], i = 0; i < 8; i++) {
|
||||
|
||||
var gx = (x[i] + c[i]) >>> 0;
|
||||
|
||||
// Construct high and low argument for squaring
|
||||
var ga = gx & 0xFFFF,
|
||||
gb = gx >>> 16;
|
||||
|
||||
// Calculate high and low result of squaring
|
||||
var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb,
|
||||
gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0;
|
||||
|
||||
// High XOR low
|
||||
g[i] = gh ^ gl;
|
||||
|
||||
}
|
||||
|
||||
// Calculate new state values
|
||||
x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16));
|
||||
x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7];
|
||||
x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16));
|
||||
x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1];
|
||||
x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16));
|
||||
x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3];
|
||||
x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16));
|
||||
x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5];
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,86 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
// Public API
|
||||
var SHA1 = C.SHA1 = function (message, options) {
|
||||
var digestbytes = util.wordsToBytes(SHA1._sha1(message));
|
||||
return options && options.asBytes ? digestbytes :
|
||||
options && options.asString ? Binary.bytesToString(digestbytes) :
|
||||
util.bytesToHex(digestbytes);
|
||||
};
|
||||
|
||||
// The core
|
||||
SHA1._sha1 = function (message) {
|
||||
|
||||
// Convert to byte array
|
||||
if (message.constructor == String) message = UTF8.stringToBytes(message);
|
||||
/* else, assume byte array already */
|
||||
|
||||
var m = util.bytesToWords(message),
|
||||
l = message.length * 8,
|
||||
w = [],
|
||||
H0 = 1732584193,
|
||||
H1 = -271733879,
|
||||
H2 = -1732584194,
|
||||
H3 = 271733878,
|
||||
H4 = -1009589776;
|
||||
|
||||
// Padding
|
||||
m[l >> 5] |= 0x80 << (24 - l % 32);
|
||||
m[((l + 64 >>> 9) << 4) + 15] = l;
|
||||
|
||||
for (var i = 0; i < m.length; i += 16) {
|
||||
|
||||
var a = H0,
|
||||
b = H1,
|
||||
c = H2,
|
||||
d = H3,
|
||||
e = H4;
|
||||
|
||||
for (var j = 0; j < 80; j++) {
|
||||
|
||||
if (j < 16) w[j] = m[i + j];
|
||||
else {
|
||||
var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
|
||||
w[j] = (n << 1) | (n >>> 31);
|
||||
}
|
||||
|
||||
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
|
||||
j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
|
||||
j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
|
||||
j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
|
||||
(H1 ^ H2 ^ H3) - 899497514);
|
||||
|
||||
H4 = H3;
|
||||
H3 = H2;
|
||||
H2 = (H1 << 30) | (H1 >>> 2);
|
||||
H1 = H0;
|
||||
H0 = t;
|
||||
|
||||
}
|
||||
|
||||
H0 += a;
|
||||
H1 += b;
|
||||
H2 += c;
|
||||
H3 += d;
|
||||
H4 += e;
|
||||
|
||||
}
|
||||
|
||||
return [H0, H1, H2, H3, H4];
|
||||
|
||||
};
|
||||
|
||||
// Package private blocksize
|
||||
SHA1._blocksize = 16;
|
||||
|
||||
SHA1._digestsize = 20;
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,130 @@
|
||||
(function(){
|
||||
|
||||
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
|
||||
|
||||
// Shortcuts
|
||||
var util = C.util,
|
||||
charenc = C.charenc,
|
||||
UTF8 = charenc.UTF8,
|
||||
Binary = charenc.Binary;
|
||||
|
||||
// Constants
|
||||
var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
||||
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
||||
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
||||
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
||||
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
||||
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
||||
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
||||
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
||||
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
||||
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
||||
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
||||
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
||||
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
||||
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
||||
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
||||
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ];
|
||||
|
||||
// Public API
|
||||
var SHA256 = C.SHA256 = function (message, options) {
|
||||
var digestbytes = util.wordsToBytes(SHA256._sha256(message));
|
||||
return options && options.asBytes ? digestbytes :
|
||||
options && options.asString ? Binary.bytesToString(digestbytes) :
|
||||
util.bytesToHex(digestbytes);
|
||||
};
|
||||
|
||||
// The core
|
||||
SHA256._sha256 = function (message) {
|
||||
|
||||
// Convert to byte array
|
||||
if (message.constructor == String) message = UTF8.stringToBytes(message);
|
||||
/* else, assume byte array already */
|
||||
|
||||
var m = util.bytesToWords(message),
|
||||
l = message.length * 8,
|
||||
H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
||||
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ],
|
||||
w = [],
|
||||
a, b, c, d, e, f, g, h, i, j,
|
||||
t1, t2;
|
||||
|
||||
// Padding
|
||||
m[l >> 5] |= 0x80 << (24 - l % 32);
|
||||
m[((l + 64 >> 9) << 4) + 15] = l;
|
||||
|
||||
for (var i = 0; i < m.length; i += 16) {
|
||||
|
||||
a = H[0];
|
||||
b = H[1];
|
||||
c = H[2];
|
||||
d = H[3];
|
||||
e = H[4];
|
||||
f = H[5];
|
||||
g = H[6];
|
||||
h = H[7];
|
||||
|
||||
for (var j = 0; j < 64; j++) {
|
||||
|
||||
if (j < 16) w[j] = m[j + i];
|
||||
else {
|
||||
|
||||
var gamma0x = w[j - 15],
|
||||
gamma1x = w[j - 2],
|
||||
gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
|
||||
((gamma0x << 14) | (gamma0x >>> 18)) ^
|
||||
(gamma0x >>> 3),
|
||||
gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
|
||||
((gamma1x << 13) | (gamma1x >>> 19)) ^
|
||||
(gamma1x >>> 10);
|
||||
|
||||
w[j] = gamma0 + (w[j - 7] >>> 0) +
|
||||
gamma1 + (w[j - 16] >>> 0);
|
||||
|
||||
}
|
||||
|
||||
var ch = e & f ^ ~e & g,
|
||||
maj = a & b ^ a & c ^ b & c,
|
||||
sigma0 = ((a << 30) | (a >>> 2)) ^
|
||||
((a << 19) | (a >>> 13)) ^
|
||||
((a << 10) | (a >>> 22)),
|
||||
sigma1 = ((e << 26) | (e >>> 6)) ^
|
||||
((e << 21) | (e >>> 11)) ^
|
||||
((e << 7) | (e >>> 25));
|
||||
|
||||
|
||||
t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0);
|
||||
t2 = sigma0 + maj;
|
||||
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = (d + t1) >>> 0;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = (t1 + t2) >>> 0;
|
||||
|
||||
}
|
||||
|
||||
H[0] += a;
|
||||
H[1] += b;
|
||||
H[2] += c;
|
||||
H[3] += d;
|
||||
H[4] += e;
|
||||
H[5] += f;
|
||||
H[6] += g;
|
||||
H[7] += h;
|
||||
|
||||
}
|
||||
|
||||
return H;
|
||||
|
||||
};
|
||||
|
||||
// Package private blocksize
|
||||
SHA256._blocksize = 16;
|
||||
|
||||
SHA256._digestsize = 32;
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"author": "Jeff Guo <gwjjeff@gmail.com>",
|
||||
"name": "cryptojs",
|
||||
"tags": ["Hash", "MD5", "SHA1", "SHA-1", "SHA256", "SHA-256", "RC4", "Rabbit", "AES", "DES", "PBKDF2", "HMAC", "OFB", "CFB", "CTR", "CBC", "Base64"],
|
||||
"description": "Following googlecode project crypto-js, provide standard and secure cryptographic algorithms for NodeJS. Support MD5, SHA-1, SHA-256, RC4, Rabbit, AES, DES, PBKDF2, HMAC, OFB, CFB, CTR, CBC, Base64",
|
||||
"version": "2.5.3",
|
||||
"homepage": "https://github.com/gwjjeff/cryptojs",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/gwjjeff/cryptojs.git"
|
||||
},
|
||||
"main": "cryptojs.js",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
var assert = require('assert');
|
||||
var Crypto = require('../cryptojs').Crypto;
|
||||
|
||||
(function test_PBKDF2() {
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8), "cdedb5281bb2f801565a1122b2563515");
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8), "cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837");
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8, { iterations : 2 }), "01dbee7f4a9e243e988b62c73cda935d");
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8, { iterations : 2 }), "01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86");
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 128 / 8, { iterations : 1200}), "5c08eb61fdf71e4e4ec3cf6ba1f5512b");
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "ATHENA.MIT.EDUraeburn", 256 / 8, { iterations : 1200}), "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13");
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "\x12\x34\x56\x78\x78\x56\x34\x12", 128 / 8, { iterations : 5 }), "d1daa78615f287e6a1c8b120d7062a49");
|
||||
assert.strictEqual(Crypto.PBKDF2("password", "\x12\x34\x56\x78\x78\x56\x34\x12", 256 / 8, { iterations : 5 }), "d1daa78615f287e6a1c8b120d7062a493f98d203e6be49a6adf4fa574b6e64ee");
|
||||
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase equals block size", 128 / 8, { iterations : 1200 }), "139c30c0966bc32ba55fdbf212530ac9");
|
||||
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase equals block size", 256 / 8, { iterations : 1200 }), "139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1");
|
||||
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 128 / 8, { iterations : 1200 }), "9ccad6d468770cd51b10e6a68721be61");
|
||||
assert.strictEqual(Crypto.PBKDF2("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 256 / 8, { iterations : 1200 }), "9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a");
|
||||
assert.strictEqual(Crypto.PBKDF2([0xf0, 0x9d, 0x84, 0x9e], "EXAMPLE.COMpianist", 128 / 8, { iterations : 50 }), "6b9cf26d45455a43a5b8bb276a403b39");
|
||||
assert.strictEqual(Crypto.PBKDF2([0xf0, 0x9d, 0x84, 0x9e], "EXAMPLE.COMpianist", 256 / 8, { iterations : 50 }), "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0c41e02c281ff3069e1e94f52");
|
||||
})();
|
||||
|
||||
(function test_PBKSD2Async() {
|
||||
Crypto.PBKDF2Async("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "pass phrase exceeds block size", 256 / 8, function(result) {
|
||||
assert.strictEqual(result, "9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a");
|
||||
}, { iterations : 1200 });
|
||||
})();
|
||||
@@ -0,0 +1,13 @@
|
||||
Crypto = (require '../cryptojs').Crypto
|
||||
key = '12345678'
|
||||
us = 'Hello, 世界!'
|
||||
|
||||
mode = new Crypto.mode.ECB Crypto.pad.pkcs7
|
||||
|
||||
console.log "ub = #{ub = Crypto.charenc.UTF8.stringToBytes us}"
|
||||
console.log "eb = #{eb = Crypto.DES.encrypt ub, key, {asBytes: true, mode: mode}}"
|
||||
console.log "ehs= #{ehs= Crypto.util.bytesToHex eb}"
|
||||
|
||||
console.log "eb2= #{eb2= Crypto.util.hexToBytes ehs}"
|
||||
console.log "ub2= #{ub2= Crypto.DES.decrypt eb2, key, {asBytes: true, mode: mode}}"
|
||||
console.log "us2= #{us2= Crypto.charenc.UTF8.bytesToString ub2}"
|
||||
@@ -0,0 +1,19 @@
|
||||
const formatTime = date => {
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth() + 1
|
||||
const day = date.getDate()
|
||||
const hour = date.getHours()
|
||||
const minute = date.getMinutes()
|
||||
const second = date.getSeconds()
|
||||
|
||||
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
|
||||
}
|
||||
|
||||
const formatNumber = n => {
|
||||
n = n.toString()
|
||||
return n[1] ? n : `0${n}`
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
formatTime
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
// components/imageUpload/imageUpload.js
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
// 最大上传个数
|
||||
maxLength: {
|
||||
type: Number,
|
||||
value: 9
|
||||
},
|
||||
// 单个图片限制 单位MB
|
||||
maxSize: {
|
||||
type: Number,
|
||||
value: 1
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
// 图片路径数组
|
||||
tempFilePaths: []
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
// 选择图片
|
||||
upload() {
|
||||
let that = this;
|
||||
let maxSize = this.data.maxSize * 1024 * 1024
|
||||
let flag = true
|
||||
let maxLength = this.data.maxLength
|
||||
console.log("maxLength",maxLength);
|
||||
wx.chooseImage({
|
||||
count: maxLength, // 默认9
|
||||
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
|
||||
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
|
||||
success: res => {
|
||||
wx.showToast({
|
||||
title: '正在上传...',
|
||||
icon: 'loading',
|
||||
mask: true,
|
||||
duration: 1000
|
||||
})
|
||||
// 判断数量
|
||||
if (res.tempFiles.length > maxLength) {
|
||||
wx.hideToast()
|
||||
flag = false
|
||||
wx.showToast({
|
||||
title: `最多上传${maxLength}张`,
|
||||
mask: true,
|
||||
duration: 1000
|
||||
})
|
||||
return false
|
||||
}
|
||||
res.tempFiles.forEach(item => {
|
||||
if (item.size > maxSize) {
|
||||
wx.hideToast()
|
||||
flag = false
|
||||
wx.showModal({
|
||||
title: '错误提示',
|
||||
content: `图片大于${that.data.maxSize}M`,
|
||||
showCancel: false,
|
||||
success(res) {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定')
|
||||
}
|
||||
}
|
||||
})
|
||||
return false
|
||||
}
|
||||
})
|
||||
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
|
||||
let tempFilePaths = res.tempFilePaths;
|
||||
if (flag) {
|
||||
that.setData({
|
||||
tempFilePaths: tempFilePaths
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 上传完成后把文件上传到服务器
|
||||
*/
|
||||
// if (flag) {
|
||||
// let count = 0;
|
||||
// for (let i = 0; i < tempFilePaths.length; i++) {
|
||||
// //上传文件
|
||||
// wx.uploadFile({
|
||||
// url: 'imgUploadUrl',
|
||||
// filePath: tempFilePaths[i],
|
||||
// name: 'uploadfile_ant',
|
||||
// header: {
|
||||
// "Content-Type": "multipart/form-data"
|
||||
// },
|
||||
// success: function (res) {
|
||||
// console.log("上传图片", res);
|
||||
// count++;
|
||||
// //如果是最后一张,则隐藏等待中
|
||||
// if (count == tempFilePaths.length) {
|
||||
// wx.hideToast();
|
||||
// }
|
||||
// },
|
||||
// fail: function (res) {
|
||||
// wx.hideToast();
|
||||
// wx.showModal({
|
||||
// title: '错误提示',
|
||||
// content: '上传图片失败',
|
||||
// showCancel: false,
|
||||
// success: function (res) {}
|
||||
// })
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
},
|
||||
|
||||
fail(err) {
|
||||
console.log("失败", err);
|
||||
}
|
||||
})
|
||||
},
|
||||
// 预览图片
|
||||
previewImage(e) {
|
||||
console.log("e", e);
|
||||
let index = e.target.dataset.index;
|
||||
let that = this;
|
||||
wx.previewImage({
|
||||
current: that.data.tempFilePaths[index],
|
||||
urls: that.data.tempFilePaths,
|
||||
success: function (res) {
|
||||
console.log("res", res);
|
||||
},
|
||||
fail: function (fail) {
|
||||
//console.log('fail')
|
||||
}
|
||||
})
|
||||
},
|
||||
// 删除图片
|
||||
deleteImage(e) {
|
||||
let that = this;
|
||||
let tempFilePaths = that.data.tempFilePaths;
|
||||
let index = e.currentTarget.dataset.index; //获取当前长按图片下标
|
||||
wx.showModal({
|
||||
title: '提示',
|
||||
content: '确定要删除此图片吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
console.log('确定');
|
||||
tempFilePaths.splice(index, 1);
|
||||
} else if (res.cancel) {
|
||||
console.log('取消');
|
||||
return false;
|
||||
}
|
||||
that.setData({
|
||||
tempFilePaths
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<!--components/imageUpload/imageUpload.wxml-->
|
||||
<view class="img_box">
|
||||
<view class="imgs" wx:for="{{tempFilePaths}}" wx:key="index">
|
||||
<image src='{{item}}' bindlongpress="deleteImage" bindtap="previewImage" data-index="{{index}}" mode='widthFix' />
|
||||
</view>
|
||||
<view class="imgs">
|
||||
<view class="images" bindtap="upload">
|
||||
<text class="add-images">+</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,49 @@
|
||||
/* components/imageUpload/imageUpload.wxss */
|
||||
/* 图片 */
|
||||
.img_box{
|
||||
width:690rpx;
|
||||
position:relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin:0 auto;
|
||||
}
|
||||
.imgs{
|
||||
width:33.33333333%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom:20rpx;
|
||||
}
|
||||
.imgs image{
|
||||
width:90%;
|
||||
max-height:212rpx;
|
||||
border:1px solid rgba(214, 212, 212, 0.1);
|
||||
/* box-shadow: 5rpx 5rpx 1rpx 3rpx #e2e0e0; */
|
||||
}
|
||||
.imgs .images{
|
||||
position:relative;
|
||||
}
|
||||
.images button{
|
||||
width:100%;
|
||||
height:100%;
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
}
|
||||
.img_box .images{
|
||||
width:90%;
|
||||
height: 212rpx;
|
||||
border:1px solid #E8E8E8;
|
||||
border-radius:4rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.img_box .images>image{
|
||||
width:60rpx;
|
||||
height:60rpx;
|
||||
}
|
||||
/* 上传加号 */
|
||||
.add-images {
|
||||
color: #ccc;
|
||||
font-size: 100rpx;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// index.js
|
||||
// 获取应用实例
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
data: {
|
||||
motto: 'Hello World',
|
||||
userInfo: {},
|
||||
hasUserInfo: false,
|
||||
canIUse: wx.canIUse('button.open-type.getUserInfo'),
|
||||
canIUseGetUserProfile: false,
|
||||
canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false
|
||||
},
|
||||
// 事件处理函数
|
||||
bindViewTap() {
|
||||
wx.navigateTo({
|
||||
url: '../logs/logs'
|
||||
})
|
||||
},
|
||||
onLoad() {
|
||||
if (wx.getUserProfile) {
|
||||
this.setData({
|
||||
canIUseGetUserProfile: true
|
||||
})
|
||||
}
|
||||
},
|
||||
getUserProfile(e) {
|
||||
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
|
||||
wx.getUserProfile({
|
||||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
this.setData({
|
||||
userInfo: res.userInfo,
|
||||
hasUserInfo: true
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getUserInfo(e) {
|
||||
// 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
|
||||
console.log(e)
|
||||
this.setData({
|
||||
userInfo: e.detail.userInfo,
|
||||
hasUserInfo: true
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<!--index.wxml-->
|
||||
<view class="container">
|
||||
<view class="userinfo">
|
||||
<block wx:if="{{canIUseOpenData}}">
|
||||
<view class="userinfo-avatar" bindtap="bindViewTap">
|
||||
<open-data type="userAvatarUrl"></open-data>
|
||||
</view>
|
||||
<open-data type="userNickName"></open-data>
|
||||
</block>
|
||||
<block wx:elif="{{!hasUserInfo}}">
|
||||
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
|
||||
<button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
|
||||
<view wx:else> 请使用1.4.4及以上版本基础库 </view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
|
||||
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
|
||||
</block>
|
||||
</view>
|
||||
<view class="usermotto">
|
||||
<text class="user-motto">{{motto}}</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -0,0 +1,19 @@
|
||||
/**index.wxss**/
|
||||
.userinfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.userinfo-avatar {
|
||||
overflow: hidden;
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
margin: 20rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.usermotto {
|
||||
margin-top: 200px;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// logs.js
|
||||
const util = require('../../utils/util.js')
|
||||
|
||||
Page({
|
||||
data: {
|
||||
logs: []
|
||||
},
|
||||
onLoad() {
|
||||
this.setData({
|
||||
logs: (wx.getStorageSync('logs') || []).map(log => {
|
||||
return {
|
||||
date: util.formatTime(new Date(log)),
|
||||
timeStamp: log
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationBarTitleText": "查看启动日志",
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<!--logs.wxml-->
|
||||
<view class="container log-list">
|
||||
<block wx:for="{{logs}}" wx:key="timeStamp" wx:for-item="log">
|
||||
<text class="log-item">{{index + 1}}. {{log.date}}</text>
|
||||
</block>
|
||||
</view>
|
||||
@@ -0,0 +1,8 @@
|
||||
.log-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 40rpx;
|
||||
}
|
||||
.log-item {
|
||||
margin: 10rpx;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// pages/meeting/meeting.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!--pages/meeting/meeting.wxml-->
|
||||
<text>pages/meeting/meeting.wxml</text>
|
||||
@@ -0,0 +1 @@
|
||||
/* pages/meeting/meeting.wxss */
|
||||
@@ -0,0 +1,66 @@
|
||||
// pages/mine/mine.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!--pages/mine/mine.wxml-->
|
||||
<text>pages/mine/mine.wxml</text>
|
||||
@@ -0,0 +1 @@
|
||||
/* pages/mine/mine.wxss */
|
||||
@@ -0,0 +1,66 @@
|
||||
// pages/notice/notice.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!--pages/notice/notice.wxml-->
|
||||
<view class="container"></view>
|
||||
@@ -0,0 +1 @@
|
||||
/* pages/notice/notice.wxss */
|
||||
@@ -0,0 +1,66 @@
|
||||
// pages/project/project.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!--pages/project/project.wxml-->
|
||||
<text>pages/project/project.wxml</text>
|
||||
@@ -0,0 +1 @@
|
||||
/* pages/project/project.wxss */
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"description": "项目配置文件",
|
||||
"packOptions": {
|
||||
"ignore": []
|
||||
},
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"es6": true,
|
||||
"enhance": true,
|
||||
"postcss": true,
|
||||
"preloadBackgroundData": false,
|
||||
"minified": true,
|
||||
"newFeature": false,
|
||||
"coverView": true,
|
||||
"nodeModules": false,
|
||||
"autoAudits": false,
|
||||
"showShadowRootInWxmlPanel": true,
|
||||
"scopeDataCheck": false,
|
||||
"uglifyFileName": false,
|
||||
"checkInvalidKey": true,
|
||||
"checkSiteMap": true,
|
||||
"uploadWithSourceMap": true,
|
||||
"compileHotReLoad": false,
|
||||
"lazyloadPlaceholderEnable": false,
|
||||
"useMultiFrameRuntime": true,
|
||||
"useApiHook": true,
|
||||
"useApiHostProcess": false,
|
||||
"babelSetting": {
|
||||
"ignore": [],
|
||||
"disablePlugins": [],
|
||||
"outputPath": ""
|
||||
},
|
||||
"enableEngineNative": false,
|
||||
"useIsolateContext": true,
|
||||
"userConfirmedBundleSwitch": false,
|
||||
"packNpmManually": false,
|
||||
"packNpmRelationList": [],
|
||||
"minifyWXSS": true,
|
||||
"showES6CompileOption": false,
|
||||
"bundle": false
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "2.19.0",
|
||||
"appid": "wx62b116308b97d953",
|
||||
"projectname": "income_payments_applet",
|
||||
"debugOptions": {
|
||||
"hidedInDevtools": []
|
||||
},
|
||||
"scripts": {},
|
||||
"staticServerOptions": {
|
||||
"baseURL": "",
|
||||
"servePath": ""
|
||||
},
|
||||
"isGameTourist": false,
|
||||
"condition": {
|
||||
"search": {
|
||||
"list": []
|
||||
},
|
||||
"conversation": {
|
||||
"list": []
|
||||
},
|
||||
"game": {
|
||||
"list": []
|
||||
},
|
||||
"plugin": {
|
||||
"list": []
|
||||
},
|
||||
"gamePlugin": {
|
||||
"list": []
|
||||
},
|
||||
"miniprogram": {
|
||||
"list": []
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
const formatTime = date => {
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth() + 1
|
||||
const day = date.getDate()
|
||||
const hour = date.getHours()
|
||||
const minute = date.getMinutes()
|
||||
const second = date.getSeconds()
|
||||
|
||||
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
|
||||
}
|
||||
|
||||
const formatNumber = n => {
|
||||
n = n.toString()
|
||||
return n[1] ? n : `0${n}`
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
formatTime
|
||||
}
|
||||