Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
llewan-weixin-sdk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
llewan
llewan-weixin-sdk
Commits
7aa4b271
Commit
7aa4b271
authored
Sep 25, 2018
by
liuxinjun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
v1.003
parent
d2201100
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
249 additions
and
165 deletions
+249
-165
sdk.js
assets/llewan-weixin-sdk/sdk.js
+219
-162
sdk_conf.js
assets/llewan-weixin-sdk/sdk_conf.js
+30
-3
No files found.
assets/llewan-weixin-sdk/sdk.js
View file @
7aa4b271
...
@@ -17,6 +17,8 @@ var md5 = require("md5");
...
@@ -17,6 +17,8 @@ var md5 = require("md5");
var
mta
=
require
(
"mta"
);
var
mta
=
require
(
"mta"
);
var
sdk_conf
=
require
(
"sdk_conf"
);
var
sdk_conf
=
require
(
"sdk_conf"
);
var
aldgame
=
require
(
"ald-game"
);
var
aldgame
=
require
(
"ald-game"
);
var
sdk
=
{
var
sdk
=
{
md5
:
md5
,
md5
:
md5
,
mta
:
mta
,
mta
:
mta
,
...
@@ -24,13 +26,19 @@ var sdk = {
...
@@ -24,13 +26,19 @@ var sdk = {
ip2
:
"https://game.llewan.com:1899"
,
ip2
:
"https://game.llewan.com:1899"
,
ip3
:
"https://log.llewan.com:1999"
,
ip3
:
"https://log.llewan.com:1999"
,
ip4
:
"https://res.llewan.com:2099"
,
ip4
:
"https://res.llewan.com:2099"
,
loginBg
:
"https://res.g.llewan.com/uploadfile/common/20180831/20180831173032_3279.png"
,
loginBg
:
"https://res.g.llewan.com/uploadfile/common/20180831/20180831173032_3279.png"
,
loginBt
:
"https://res.g.llewan.com/uploadfile/common/20180831/20180831180006_1583.png"
,
loginBt
:
"https://res.g.llewan.com/uploadfile/common/20180831/20180831180006_1583.png"
,
debug
:
false
,
//是否开启调试
debug
:
false
,
//是否开启调试
login
:
'/Login/common'
,
login
:
'/Login/common'
,
modify
:
'/Login/modify'
,
Config
:
'/Config/common'
,
Config
:
'/Config/common'
,
//游戏数据存储/获取
set
:
"/game/set"
,
get
:
"/game/get"
,
ConfigData
:
{
ConfigData
:
{
"config1"
:
{},
"config1"
:
{},
"config2"
:
{},
"config2"
:
{},
...
@@ -66,6 +74,9 @@ var sdk = {
...
@@ -66,6 +74,9 @@ var sdk = {
*/
*/
init
(
args
,
callback
){
init
(
args
,
callback
){
var
self
=
this
;
var
self
=
this
;
//根据sdk_conf初始化api
this
.
init_api
();
return
;
if
(
args
.
debug
){
if
(
args
.
debug
){
this
.
debug
=
args
.
debug
;
this
.
debug
=
args
.
debug
;
}
}
...
@@ -153,6 +164,31 @@ var sdk = {
...
@@ -153,6 +164,31 @@ var sdk = {
},
},
//.根据配置初始化api
init_api
(
type
){
if
(
sdk_conf
.
env
===
'prod'
)
{
this
.
ip1
=
sdk_conf
.
env_apis
.
prod
.
ip1
;
this
.
ip2
=
sdk_conf
.
env_apis
.
prod
.
ip2
;
this
.
ip3
=
sdk_conf
.
env_apis
.
prod
.
ip3
;
this
.
ip4
=
sdk_conf
.
env_apis
.
prod
.
ip4
;
}
else
{
this
.
ip1
=
sdk_conf
.
env_apis
.
test
.
ip1
;
this
.
ip2
=
sdk_conf
.
env_apis
.
test
.
ip2
;
this
.
ip3
=
sdk_conf
.
env_apis
.
test
.
ip3
;
this
.
ip4
=
sdk_conf
.
env_apis
.
test
.
ip4
;
}
console
.
log
(
"ip1"
,
this
.
ip1
);
console
.
log
(
"ip2"
,
this
.
ip2
);
console
.
log
(
"ip3"
,
this
.
ip3
);
console
.
log
(
"ip4"
,
this
.
ip4
);
},
//.根据权重随机获取指定type类型的分享信息。(没有this.ShareList数据不能调用)
//.根据权重随机获取指定type类型的分享信息。(没有this.ShareList数据不能调用)
getShareByWeight
(
type
){
getShareByWeight
(
type
){
if
(
this
.
ShareList
.
length
>
0
){
if
(
this
.
ShareList
.
length
>
0
){
...
@@ -383,6 +419,7 @@ var sdk = {
...
@@ -383,6 +419,7 @@ var sdk = {
reqData
.
game
=
sdk_conf
.
game
;
reqData
.
game
=
sdk_conf
.
game
;
reqData
.
version
=
sdk_conf
.
version
;
reqData
.
version
=
sdk_conf
.
version
;
reqData
.
dev_platform
=
sdk_conf
.
dev_platform
;
reqData
.
dev_platform
=
sdk_conf
.
dev_platform
;
reqData
.
llewan_sdk_version
=
sdk_conf
.
llewan_sdk_version
;
var
ts
=
new
Date
().
getTime
();
var
ts
=
new
Date
().
getTime
();
reqData
.
ts
=
ts
;
reqData
.
ts
=
ts
;
var
token
=
""
;
var
token
=
""
;
...
@@ -394,7 +431,7 @@ var sdk = {
...
@@ -394,7 +431,7 @@ var sdk = {
var
source_id
=
options
.
query
.
source_id
;
var
source_id
=
options
.
query
.
source_id
;
//数据验证签名。规则为:MD5(ts.substr(9,4)+game.substr(0,2)+version.substr(0,1)+key),时间戳后4位、data前3位、key(服务端提供)然后进行MD5加密
//数据验证签名。规则为:MD5(ts.substr(9,4)+game.substr(0,2)+version.substr(0,1)+key),时间戳后4位、data前3位、key(服务端提供)然后进行MD5加密
reqData
.
sign
=
md5
(
ts
.
toString
().
substr
(
9
,
4
)
+
sdk_conf
.
game
.
substr
(
0
,
2
)
+
sdk_conf
.
version
.
substr
(
0
,
1
)
+
'$5dfjr$%dsadsfdsii'
);
reqData
.
sign
=
md5
(
ts
.
toString
().
substr
(
9
,
4
)
+
sdk_conf
.
game
.
substr
(
0
,
2
)
+
sdk_conf
.
version
.
substr
(
0
,
1
)
+
sdk_conf
.
md5_key
);
url
+=
"?"
;
url
+=
"?"
;
for
(
var
item
in
reqData
)
{
for
(
var
item
in
reqData
)
{
...
@@ -426,6 +463,7 @@ var sdk = {
...
@@ -426,6 +463,7 @@ var sdk = {
}
}
}
}
};
};
console
.
log
(
"get url is :"
,
url
);
xhr
.
open
(
"GET"
,
url
,
true
);
xhr
.
open
(
"GET"
,
url
,
true
);
xhr
.
send
();
xhr
.
send
();
},
},
...
@@ -449,6 +487,7 @@ var sdk = {
...
@@ -449,6 +487,7 @@ var sdk = {
reqData
.
game
=
sdk_conf
.
game
;
reqData
.
game
=
sdk_conf
.
game
;
reqData
.
version
=
sdk_conf
.
version
;
reqData
.
version
=
sdk_conf
.
version
;
reqData
.
dev_platform
=
sdk_conf
.
dev_platform
;
reqData
.
dev_platform
=
sdk_conf
.
dev_platform
;
reqData
.
llewan_sdk_version
=
sdk_conf
.
llewan_sdk_version
;
var
ts
=
new
Date
().
getTime
();
var
ts
=
new
Date
().
getTime
();
var
token
=
""
;
var
token
=
""
;
if
(
this
.
getUser
())
if
(
this
.
getUser
())
...
@@ -459,7 +498,7 @@ var sdk = {
...
@@ -459,7 +498,7 @@ var sdk = {
var
source_id
=
options
.
query
.
source_id
;
var
source_id
=
options
.
query
.
source_id
;
reqData
.
ts
=
ts
;
reqData
.
ts
=
ts
;
reqData
.
sign
=
md5
(
ts
.
toString
().
substr
(
9
,
4
)
+
sdk_conf
.
game
.
substr
(
0
,
2
)
+
sdk_conf
.
version
.
substr
(
0
,
1
)
+
'$5dfjr$%dsadsfdsii'
);
reqData
.
sign
=
md5
(
ts
.
toString
().
substr
(
9
,
4
)
+
sdk_conf
.
game
.
substr
(
0
,
2
)
+
sdk_conf
.
version
.
substr
(
0
,
1
)
+
sdk_conf
.
md5_key
);
//1.拼接请求参数
//1.拼接请求参数
var
param
=
""
;
var
param
=
""
;
...
@@ -468,6 +507,7 @@ var sdk = {
...
@@ -468,6 +507,7 @@ var sdk = {
}
}
param
+=
"token="
+
token
+
"&"
;
param
+=
"token="
+
token
+
"&"
;
param
+=
"source_id="
+
source_id
+
"&"
;
param
+=
"source_id="
+
source_id
+
"&"
;
//2.发起请求
//2.发起请求
var
xhr
=
new
XMLHttpRequest
();
var
xhr
=
new
XMLHttpRequest
();
...
@@ -983,44 +1023,37 @@ var sdk = {
...
@@ -983,44 +1023,37 @@ var sdk = {
if
(
auths
.
authSetting
[
"scope.userInfo"
]){
if
(
auths
.
authSetting
[
"scope.userInfo"
]){
self
.
setItem
(
"wxauth"
,
1
);
self
.
setItem
(
"wxauth"
,
1
);
console
.
log
(
'===已经授权==='
);
console
.
log
(
'===已经授权==='
);
wx
.
login
({
success
(
res2
){
var
reqData
=
{
var
reqData
=
{
rawData
:
res1
.
rawData
,
code
:
res2
.
code
,
iv
:
res1
.
iv
,
rawData
:
res1
.
rawData
,
encryptedData
:
res1
.
encryptedData
,
iv
:
res1
.
iv
,
signature
:
res1
.
signature
,
encryptedData
:
res1
.
encryptedData
,
signature
:
res1
.
signature
,
referee_id
:
referee_id
,
source_id
:
source_id
,
referee_id
:
referee_id
,
source_id2
:
source_id2
,
source_id
:
source_id
,
share_id
:
share_id
source_id2
:
source_id2
,
}
share_id
:
share_id
// console.log('==登录参数==', reqData)
}
self
.
Post
(
self
.
ip1
+
self
.
modify
,
reqData
,
function
(
data
){
// console.log('==登录参数==', reqData)
// console.log('==登录结果==', data)
self
.
Post
(
self
.
ip1
+
self
.
login
,
reqData
,
function
(
data
){
if
(
data
.
c
==
1
){
// console.log('==登录结果==', data)
self
.
setItem
(
'userinfo'
,
JSON
.
stringify
(
data
.
d
));
if
(
data
.
c
==
1
){
wx
.
hideToast
();
self
.
setItem
(
'userinfo'
,
JSON
.
stringify
(
data
.
d
));
maskNode
.
destroy
();
wx
.
hideToast
();
self
.
button
.
hide
();
maskNode
.
destroy
();
//.登录成功,重新初始化
self
.
button
.
hide
();
self
.
userid
=
data
.
d
.
uid
;
//.登录成功,重新初始化
self
.
init
({},(
d
)
=>
{})
self
.
userid
=
data
.
d
.
uid
;
self
.
init
({},(
d
)
=>
{})
callback
(
data
.
d
);
}
else
{
callback
(
data
.
d
);
// console.log('==登录接口请求失败==', data)
}
else
{
// console.log('==登录接口请求失败==', data)
wx
.
showToast
({
title
:
'登录失败请重试'
});
}
});
},
fail
(){
wx
.
showToast
({
title
:
'登录失败请重试'
});
wx
.
showToast
({
title
:
'登录失败请重试'
});
callback
(
false
)
}
},
});
})
}
else
{
}
else
{
callback
(
false
)
callback
(
false
)
}
}
...
@@ -1086,134 +1119,19 @@ var sdk = {
...
@@ -1086,134 +1119,19 @@ var sdk = {
//没有用户信息,也没有授权,就应该去登陆并且去授权后调用服务端member/update用户信息
//没有用户信息,也没有授权,就应该去登陆并且去授权后调用服务端member/update用户信息
this
.
WxLogin
((
d
)
=>
{
this
.
WxLogin
((
d
)
=>
{
console
.
log
(
"登陆"
);
console
.
log
(
"登陆"
);
this
.
WxAuthLogin
((
d
)
=>
{
console
.
log
(
"授权3"
);
callback
(
d
);
});
});
});
this
.
WxAuthLogin
((
d
)
=>
{
console
.
log
(
"授权3"
);
callback
(
d
);
});
}
}
}
}
},
},
// WeChatLogin(callback){
// var self = this;
// if (cc.sys.platform === cc.sys.WECHAT_GAME) {
// var options = wx.getLaunchOptionsSync();
// var referee_id = options.query.uid; //.推荐人id
// var source_id = options.query.source_id; //.用户来源id
// var source_id2 = options.query.source_id2; //.用户来源子id
// var share_id = options.query.share_id; //.分享素材ID
// var userinfo = this.getUser();
// var wxauth = this.getItem("wxauth"); //记录微信是否授权
// if(userinfo&&wxauth){
// //用户信息获取到并且授权了
// callback(userinfo)
// }else if(userinfo&&!wxauth)
// {
// //用户信息存在但是没有授权,就应该去授权后调用服务端member/update用户信息
// }else if(!userinfo&&wxauth)
// {
// //用户信息没有但是有授权,就应该去登陆并且去授权后调用服务端member/update用户信息
// }
// else{
// //没有用户信息,也没有授权,就应该去登陆并且去授权后调用服务端member/update用户信息
// //.登录遮罩背景
// var maskNode = new cc.Node('Sprite');
// maskNode.parent = cc.director.getScene().getChildByName('Canvas');
// maskNode.addComponent(cc.BlockInputEvents)
// var sp = maskNode.addComponent(cc.Sprite);
// maskNode.opacity = 178;
// maskNode.color = new cc.Color(25,88,95,255);
// sp.sizeMode = cc.Sprite.SizeMode.CUSTOM;
// self.createImage(sp, self.loginBg);
// maskNode.width = cc.view.getVisibleSize().width;
// maskNode.height = cc.view.getVisibleSize().height;
// // console.log(maskNode.width, maskNode.height)
// //.微信登录按钮
// if(self.button){
// self.button.show();
// }else{
// wx.getSystemInfo({
// success(res){
// var width = 507/2;
// var height = 464/2;
// self.button = wx.createUserInfoButton({
// type: 'image',
// image: self.loginBt,
// style: { width: width, height: height, left: res.screenWidth/2-width/2, top: res.screenHeight/2-height/2 }
// })
// self.button.onTap((res1) => {
// // 处理用户拒绝授权的情况
// // if (res1.errMsg.indexOf('auth deny') > -1 || res1.errMsg.indexOf('auth denied') > -1 ) {
// // wx.showToast();
// // }
// wx.showToast({title: '登录中...',icon:'loading',duration: 8});
// wx.getSetting({
// success(auths){
// if(auths.authSetting["scope.userInfo"]){
// this.setItem("wxauth",1);
// console.log('===已经授权===');
// wx.login({
// success(res2){
// var reqData = {
// code: res2.code,
// rawData: res1.rawData,
// iv: res1.iv,
// encryptedData: res1.encryptedData,
// signature: res1.signature,
// referee_id: referee_id,
// source_id: source_id,
// source_id2: source_id2,
// share_id: share_id
// }
// // console.log('==登录参数==', reqData)
// self.Post(self.ip1 + self.login, reqData, function(data){
// // console.log('==登录结果==', data)
// if(data.c == 1){
// self.setItem('userinfo', JSON.stringify(data.d));
// wx.hideToast();
// maskNode.destroy();
// self.button.hide();
// //.登录成功,重新初始化
// self.userid = data.d.uid;
// self.init({},(d)=>{})
// callback(data.d);
// }else{
// // console.log('==登录接口请求失败==', data)
// wx.showToast({title: '登录失败请重试'});
// }
// });
// },
// fail(){
// wx.showToast({title: '登录失败请重试'});
// callback(false)
// },
// })
// }else{
// callback(false)
// }
// }
// })
// })
// self.button.show()
// }
// })
// }
// }
// }
// },
/**
/**
* @apiGroup C
* @apiGroup C
* @apiName createBannerAd
* @apiName createBannerAd
...
@@ -1449,7 +1367,146 @@ var sdk = {
...
@@ -1449,7 +1367,146 @@ var sdk = {
})
})
}
}
},
//.一般性存储到服务器数据方法,并且做了本地缓存
/**
* @apiGroup C
* @apiName setToServer
* @api {setToServer} 数据存储 setToServer(存)
* @apiParam {String} dataKey 键
* @apiParam {String} dataType 数据类型
* @apiParam {String} data 需要保存的数据
* @apiParam {String} expireTime 过期时间
* sdk.setToServer("testKey","TestData","{'key':'test'}",4);
*
*/
setToServer
:
function
(
dataKey
,
dataType
,
data
,
expireTime
){
var
self
=
this
;
self
.
setLocalCache
(
dataKey
,
JSON
.
stringify
(
data
),
expireTime
);
console
.
log
(
dataKey
+
" setLocalCache "
+
JSON
.
stringify
(
data
));
this
.
Get
(
this
.
ip2
+
this
.
set
,
{
key
:
dataKey
,
data
:
JSON
.
stringify
(
data
),
data_type
:
dataType
,
expireTime
:
String
(
expireTime
)},
function
(
d
)
{
console
.
log
(
"setToServer 返回"
,
JSON
.
stringify
(
d
));
if
(
d
.
c
==
0
)
{
console
.
error
(
"设置失败,请联系服务端技术查看问题!"
);
}
});
},
//.一般性获取服务器数据方法,并且做了本地缓存
/**
* @apiGroup C
* @apiName getFromServer
* @api {getFromServer} 数据存储 getFromServer(获取)
* @apiParam {String} dataKey 键
* @apiParam {String} dataType 数据类型
* @apiParam {String} data 特殊情况下需要传递额外数据状况,一般不传递
* @apiParam {String} callback 回调
*
* sdk.getFromServer("testKey","TestData",null,(d)=>{
console.log("获取返回");
});
*/
getFromServer
:
function
(
dataKey
,
dataType
,
data
,
callbackFunction
){
var
self
=
this
;
var
cacheData
=
this
.
getLocalCache
(
dataKey
)
console
.
log
(
dataKey
+
" 本地获取值:"
+
cacheData
);
if
(
cacheData
==-
1
)
{
//去远程服务器拿数据
this
.
Get
(
this
.
ip2
+
this
.
get
,
{
key
:
dataKey
,
data_type
:
dataType
,
data
:
JSON
.
stringify
(
data
)},
function
(
d
)
{
console
.
log
(
dataKey
+
" 本地不存在,去服务器获取值:"
+
JSON
.
stringify
(
d
));
callbackFunction
(
d
);
});
}
else
if
(
cacheData
==
0
)
{
//本地缓存过期了直接返回
//callbackFunction(null);
//去远程服务器拿数据
this
.
Get
(
this
.
ip2
+
this
.
get
,
{
key
:
dataKey
,
data_type
:
dataType
,
data
:
JSON
.
stringify
(
data
)},
function
(
d
)
{
console
.
log
(
dataKey
+
" 本地已经过期,去服务器获取值:"
+
JSON
.
stringify
(
d
));
callbackFunction
(
d
);
});
}
else
{
//获取到数据
callbackFunction
(
cacheData
);
}
},
/**
* @apiGroup C
* @apiName setItem
* @api {set} 数据存储 setItem(存)
* @apiParam {String} key 键
* @apiParam {String} value 值
* @apiParam {String} expireTime 过期时间
*
* @apiSuccessExample {json} 示例:
* sdk.setLocalCache("nick","hello")
*/
setLocalCache
(
key
,
value
,
expireTime
){
var
nowTime
=
new
Date
().
getTime
();
console
.
log
(
"setLocalCache nowTime"
,
nowTime
);
expireTime
=
nowTime
+
expireTime
*
1000
;
console
.
log
(
"setLocalCache expireTime"
,
expireTime
);
var
localData
=
{
'data'
:
value
,
'expireTime'
:
expireTime
};
cc
.
sys
.
localStorage
.
setItem
(
key
,
JSON
.
stringify
(
localData
));
},
/**
* @apiGroup C
* @apiName getItem
* @api {数据存储} 数据存储 getItem(取)
* @apiParam {String} key 键
* @apiParam {String} value 值
*
* @apiSuccessExample {json} 示例:
* var nick = sdk.getLocalCache("nick")
*/
getLocalCache
(
key
){
var
nowTime
=
new
Date
().
getTime
();
console
.
log
(
"getLocalCache nowTime"
,
nowTime
);
var
localData
=
cc
.
sys
.
localStorage
.
getItem
(
key
);
if
(
localData
)
{
var
data
=
JSON
.
parse
(
localData
);
var
expireTime
=
data
.
expireTime
;
if
(
nowTime
>=
expireTime
)
{
cc
.
sys
.
localStorage
.
removeItem
(
key
);
console
.
log
(
"本地 dataKey : "
+
key
+
" is expire"
);
return
0
;
}
else
{
var
data
=
JSON
.
stringify
(
data
.
data
);
console
.
log
(
"本地 dataKey : "
+
key
+
" is "
+
data
);
return
data
;
}
}
else
{
//本地不存在数据,应该去远程服务器拿数据
return
-
1
;
}
}
}
};
};
...
...
assets/llewan-weixin-sdk/sdk_conf.js
View file @
7aa4b271
var
sdk_conf
=
{
var
sdk_conf
=
{
dev_platform
:
'weixin'
,
//.开发调试环境:prod 或 test,env_apis配合使用,主要是将接口切换正式环境和测试环境,上线务必修改为:prod
//.游戏唯一标识
env
:
'prod'
,
//.游戏唯一标识:由游戏技术修改
game
:
'zuiqiangchijiwang'
,
game
:
'zuiqiangchijiwang'
,
//.当前游戏版本
//.当前游戏版本
:由游戏技术修改
version
:
'1.005'
,
version
:
'1.005'
,
//.banner广告单元id
//.banner广告单元id
bannerAdUnitId
:
''
,
bannerAdUnitId
:
''
,
...
@@ -10,6 +11,32 @@ var sdk_conf = {
...
@@ -10,6 +11,32 @@ var sdk_conf = {
videoAdUnitId
:
''
,
videoAdUnitId
:
''
,
//.开发平台:由sdk维护者确定,weixin 或 toutiao,接入游戏的技术不需要修改
dev_platform
:
'weixin'
,
//.乐玩sdk的版本号:由sdk维护者确定,接入游戏的技术不需要修改
llewan_sdk_version
:
'1.003'
,
//.接口加密key,切勿修改
md5_key
:
'$5dfjr$%dsadsfdsii'
,
//相关api配置,由sdk维护者确定,接入游戏的技术不需要修改
env_apis
:{
prod
:{
ip1
:
"https://login.llewan.com:1799"
,
ip2
:
"https://game.llewan.com:1899"
,
ip3
:
"https://log.llewan.com:1999"
,
ip4
:
"https://res.llewan.com:2099"
,
},
test
:{
ip1
:
"https://login.test.llewan.com"
,
ip2
:
"https://game.test.llewan.com"
,
ip3
:
"https://log.test.llewan.com"
,
ip4
:
"https://res.test.llewan.com"
,
}
}
};
};
module
.
exports
=
sdk_conf
;
module
.
exports
=
sdk_conf
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment