Compare commits

..

18 Commits
init ... master

Author SHA1 Message Date
aozhiwei
7eef9d8438 1 2022-06-21 11:43:43 +08:00
aozhiwei
516e562ed0 更新华为key 2020-05-18 15:50:44 +08:00
aozhiwei
be16bf0233 修复uuid问题 2020-03-24 19:10:59 +08:00
aozhiwei
299189f7db 1 2020-03-19 14:05:21 +08:00
aozhiwei
eecccb17dc 1 2020-03-18 20:27:31 +08:00
aozhiwei
44ac3b0b31 1 2020-03-18 20:17:19 +08:00
aozhiwei
dcfb40db7b 1 2020-03-18 20:12:32 +08:00
aozhiwei
16bb1a0b53 1 2020-03-18 20:06:41 +08:00
aozhiwei
32d3fdbfc8 1 2020-03-18 20:02:03 +08:00
aozhiwei
0e5d663cc5 添加UrlValuesToMap函数 2020-03-18 19:43:15 +08:00
aozhiwei
d0ae1ba7ae 1 2020-03-18 17:41:20 +08:00
aozhiwei
341fb70c64 1 2020-03-18 14:32:38 +08:00
aozhiwei
7d3e0e3288 1 2020-03-18 14:05:56 +08:00
aozhiwei
efc97aca55 1 2020-03-18 13:07:23 +08:00
aozhiwei
1f0c2cb55c 添加qq小游戏密钥 2020-03-17 15:03:19 +08:00
aozhiwei
f71dfdaf4b 修复多封邮件问题 2020-03-05 16:39:38 +08:00
aozhiwei
0d0ca89b46 所有发给game的消息都转发一份到金蚕 2020-02-27 11:13:01 +08:00
aozhiwei
de4d07ecd6 转发流程已经ok 2020-02-21 19:53:05 +08:00
11 changed files with 204 additions and 56 deletions

View File

@ -45,7 +45,7 @@ func HGamePreOrder(w http.ResponseWriter, r *http.Request) {
uid := r.PostFormValue("uid") uid := r.PostFormValue("uid")
sid := r.PostFormValue("server") sid := r.PostFormValue("server")
if !redis.HExists("game_info", sid) { if !redis.IsValidServerId(util.StringToUint32(sid)) {
log.Error("not Found server ", r.Form.Encode()) log.Error("not Found server ", r.Form.Encode())
return return
} }

View File

@ -48,7 +48,7 @@ func HuaweiPreOrder(w http.ResponseWriter, r *http.Request) {
sid := r.PostFormValue("server") sid := r.PostFormValue("server")
log.Debugf("HuaweiPreOrder Param %+v", r.Form) log.Debugf("HuaweiPreOrder Param %+v", r.Form)
if !redis.HExists("game_info", sid) { if !redis.IsValidServerId(util.StringToUint32(sid)) {
log.Error("not Found server ", r.Form.Encode()) log.Error("not Found server ", r.Form.Encode())
return return
} }

View File

@ -5,7 +5,8 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"game/base/log" "game/base/log"
"game/base/redis" //"game/base/redis"
"game/config"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
@ -13,6 +14,7 @@ import (
"os/signal" "os/signal"
"syscall" "syscall"
"time" "time"
"strconv"
) )
// Server 服务器 // Server 服务器
@ -29,6 +31,7 @@ func (srv *PayServer) Run() {
//开始access Token服务 //开始access Token服务
//platApi.StartAccessTokenMgr() //platApi.StartAccessTokenMgr()
/*
http.HandleFunc("/qqPreOrder", QQPreOrder) http.HandleFunc("/qqPreOrder", QQPreOrder)
http.HandleFunc("/qqCallback", srv.QQPayCallBack) http.HandleFunc("/qqCallback", srv.QQPayCallBack)
http.HandleFunc("/oppoPreOrder", OppoPreOrder) http.HandleFunc("/oppoPreOrder", OppoPreOrder)
@ -46,7 +49,9 @@ func (srv *PayServer) Run() {
http.HandleFunc("/huaweiPreOrder", HuaweiPreOrder) http.HandleFunc("/huaweiPreOrder", HuaweiPreOrder)
http.HandleFunc("/checkRegisterReward", srv.CheckRegisterReward) http.HandleFunc("/checkRegisterReward", srv.CheckRegisterReward)
http.HandleFunc("/RegisterReward", srv.RegisterReward) http.HandleFunc("/RegisterReward", srv.RegisterReward)
http.HandleFunc("/testGameProxy", srv.TestGameProxy)
http.HandleFunc("/selfChecking", srv.SelfChecking)
*/
server := http.Server{Addr: srv.addr, Handler: http.DefaultServeMux} server := http.Server{Addr: srv.addr, Handler: http.DefaultServeMux}
go func() { go func() {
err := server.ListenAndServe() err := server.ListenAndServe()
@ -119,8 +124,73 @@ type ServerInfo struct {
WorldName string `json:"worldName"` WorldName string `json:"worldName"`
} }
func (srv *PayServer) forwardKsGame(sid int, urlPath string, msg interface{}, name string) (respData []byte, e error) {
var data []byte
data, e = json.Marshal(msg)
if e != nil {
log.Debug("SendMsgToGameProxy e:", e)
return
}
var domain_name = "game1009proxy.kingsome.cn"
if config.CmConfig.IsProxyDebug {
domain_name = "game1009proxy-test.kingsome.cn"
}
sUrl := fmt.Sprintf("https://%s/webapp/index.php?c=GameProxy&a=forwardMsg&sid=%d&urlPath=%s&msg=%s&name=%s",
domain_name,
sid,
urlPath,
url.QueryEscape(string(data)),
url.QueryEscape(string(name)))
ss, _ := url.QueryUnescape(sUrl)
log.Info("SendMsgToGameProxy Url ", ss)
var resp *http.Response
resp, e = http.Get(sUrl)
if e != nil {
log.Error("SendMsgToGameProxy Get fail err:", e)
return
}
respData, e = ioutil.ReadAll(resp.Body)
if e != nil {
log.Error("SendMsgToGameProxy ReadAll fail err:", e)
return
}
resp.Body.Close()
log.Info("response", string(respData))
return respData, nil;
}
func (srv *PayServer) TestGameProxy(w http.ResponseWriter, r *http.Request) {
var msg = make(map[string]string)
var e error
if e = json.Unmarshal([]byte(r.FormValue("msg")), &msg); e != nil {
log.Error("SendMsgToGame Unmarshal fail err:", e)
return
}
var sid, _ = strconv.Atoi(r.FormValue("sid"));
var urlPath = "selfChecking"
if config.CmConfig.IsProxyDebug {
urlPath = r.FormValue("urlPath")
}
var name = r.FormValue("name")
var respData, _ = srv.forwardKsGame(
sid,
urlPath,
msg,
name)
log.Info("response", string(respData))
w.Write(respData)
}
func (srv *PayServer) SendMsgToGame(sid int, urlPath string, msg interface{}, name string) (respData []byte, e error) { func (srv *PayServer) SendMsgToGame(sid int, urlPath string, msg interface{}, name string) (respData []byte, e error) {
info := redis.HGet("game_info", sid) respData, e = srv.forwardKsGame(sid, urlPath, msg, name)
return respData, e
/*info := redis.HGet("game_info", sid)
if info == "" { if info == "" {
log.Debug("SendMsgToGame info=nil") log.Debug("SendMsgToGame info=nil")
return return
@ -164,5 +234,10 @@ func (srv *PayServer) SendMsgToGame(sid int, urlPath string, msg interface{}, na
return return
} }
log.Info("SendMail Fail msg:", msg, " sid:", sid, " name:", name, " rr:", rr) log.Info("SendMail Fail msg:", msg, " sid:", sid, " name:", name, " rr:", rr)
return return*/
} }
func (srv *PayServer) SelfChecking(w http.ResponseWriter, r *http.Request) {
w.Write([] byte(`{"errcode":0,"errmsg":"","healthy":1,"max_rundelay":1}`))
}

View File

@ -6,8 +6,10 @@ import (
"game/base/platApi" "game/base/platApi"
"game/base/util" "game/base/util"
"game/config" "game/config"
"game/excel"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings"
) )
func QQPreOrder(w http.ResponseWriter, r *http.Request) { func QQPreOrder(w http.ResponseWriter, r *http.Request) {
@ -22,11 +24,14 @@ func QQPreOrder(w http.ResponseWriter, r *http.Request) {
r.ParseForm() r.ParseForm()
openid := r.Form.Get("openid") openid := r.Form.Get("openid")
zone := r.Form.Get("zone") //uid := r.Form.Get("uid")
item := r.Form.Get("item") zone := r.Form.Get("sid")
amt := r.Form.Get("amt") item := r.Form.Get("produce")
sessionKey := r.Form.Get("sessionKey") sessionKey := r.Form.Get("session")
amount := util.StringToUint32(r.Form.Get("amount")) //amt := r.Form.Get("amt")
//amount := util.StringToUint32(r.Form.Get("amount"))
amt := "1"
amount := uint32(1)
token := platApi.GetAppAccessToken(config.QQAppID, config.QQAppSecret, platApi.Plat_QQ) token := platApi.GetAppAccessToken(config.QQAppID, config.QQAppSecret, platApi.Plat_QQ)
ret, err := platApi.QQPrePay(openid, config.QQAppID, zone, amt, item, amount, token, sessionKey) ret, err := platApi.QQPrePay(openid, config.QQAppID, zone, amt, item, amount, token, sessionKey)
@ -40,8 +45,10 @@ func QQPreOrder(w http.ResponseWriter, r *http.Request) {
} }
func (srv *PayServer) QQPayCallBack(w http.ResponseWriter, r *http.Request) { func (srv *PayServer) QQPayCallBack(w http.ResponseWriter, r *http.Request) {
var data []byte ret := &platApi.QQPayCallBackRet{}
defer func() { defer func() {
log.Info("QQPayCallBack ret:", ret)
data, _ := json.Marshal(ret)
w.Write(data) w.Write(data)
}() }()
@ -59,22 +66,47 @@ func (srv *PayServer) QQPayCallBack(w http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
return return
} }
log.Info(" req:", req)
ok := platApi.QQCallBackVerify(req, r.URL.Path, config.QQAppSecret) ok := platApi.QQCallBackVerify(req, r.URL.Path, config.QQAppSecret)
if !ok { if !ok {
ret.Code = 1
ret.Msg = "签名检验失败"
return return
} }
ret := &platApi.QQPayCallBackRet{} extInfo := strings.Split(req.AppRemark, "-")
//ret.Code= if len(extInfo) != 3 {
//ret.Msg = ret.Code = 2
ret.Msg = "app_remark参数格式错误"
log.Info("QQPayCallBack ret:", ret, " req:", req)
data, err = json.Marshal(ret)
if err != nil {
return return
} }
sid := util.StringToInt(extInfo[0])
produce := util.StringToUint32(extInfo[1])
uid := util.StringToUint64(extInfo[2])
info := excel.GetPlatformIdById(produce)
msg := &RechargeCommonC2SMsg{
RoleId: uid,
Rmb: float32(info.Money),
ChargeYb: info.Money * 10,
GiftYb: 0,
OrderId: r.FormValue("bill_no"),
POrderId: r.FormValue("bill_no"),
PlatformIp: r.Header.Get("X-Real_IP"),
AttType: info.Type,
AttValue: info.Index,
}
code, _ := srv.DeliverGood(sid, msg)
if code == 1 || code == 1002 {
ret.Code = 0
} else {
ret.Code = 3
}
log.Info("QQCallback DeliverRecv sid:", sid, " Role:", uid, " OrderId:", msg.OrderId, " POrderId:", msg.POrderId,
" Money:", info.Money, " produce:", produce, " Code:", ret.Code, " code:", code, " err:", err)
//TODO 发货 //TODO 发货
//var serverId uint64 //var serverId uint64
//var uid uint64 //var uid uint64

View File

@ -52,7 +52,7 @@ func XiaomiPreOrder(w http.ResponseWriter, r *http.Request) {
} }
return return
} }
if !redis.HExists("game_info", sid) { if !redis.IsValidServerId(util.StringToUint32(sid)) {
log.Error("not Found server ", r.Form.Encode()) log.Error("not Found server ", r.Form.Encode())
return return
} }

View File

@ -49,6 +49,20 @@ type QQPrePayRes struct {
PrepayId string `json:"prepayId"` PrepayId string `json:"prepayId"`
} }
type QQPrePayReq struct {
OpenId string `json:"openid"`
AppId string `json:"appid"`
Ts int `json:"ts"`
ZoneId string `json:"zone_id"`
Pf string `json:"pf"`
Amt int `json:"amt"`
GoodId string `json:"goodid"`
GoodNum int `json:"good_num"`
AppRemark string `json:"app_remark"`
BillNo string `json:"bill_no"`
Sig string `json:"sig"`
}
func QQPrePay(openid string, appid string, zone string, amt string, goodId string, goodNum uint32, token string, sessionKey string) (*QQPrePayRes, error) { func QQPrePay(openid string, appid string, zone string, amt string, goodId string, goodNum uint32, token string, sessionKey string) (*QQPrePayRes, error) {
u := "https://api.q.qq.com/api/json/openApiPay/GamePrePay?access_token=" + token u := "https://api.q.qq.com/api/json/openApiPay/GamePrePay?access_token=" + token
value := url.Values{} value := url.Values{}
@ -58,9 +72,10 @@ func QQPrePay(openid string, appid string, zone string, amt string, goodId strin
value.Add("zone_id", zone) value.Add("zone_id", zone)
value.Add("pf", "qq_m_qq-2001-android-2011") value.Add("pf", "qq_m_qq-2001-android-2011")
value.Add("amt", amt) value.Add("amt", amt)
value.Add("goodid", goodId) value.Add("goodid", "31b654ce0caeda34ad583d069551481c")
value.Add("good_nun", util.Uint32ToString(goodNum)) //value.Add("goodid", goodId)
value.Add("app_remark", appid) value.Add("good_num", util.Uint32ToString(goodNum))
value.Add("app_remark", zone + "-" + goodId + "-" + openid)
billNo, _ := util.NextId() billNo, _ := util.NextId()
value.Add("bill_no", util.Int64ToString(billNo)) value.Add("bill_no", util.Int64ToString(billNo))
@ -69,7 +84,14 @@ func QQPrePay(openid string, appid string, zone string, amt string, goodId strin
h.Write([]byte(param)) h.Write([]byte(param))
sign := hex.EncodeToString(h.Sum(nil)) sign := hex.EncodeToString(h.Sum(nil))
value.Set("sig", sign) value.Set("sig", sign)
data, _ := json.Marshal(value) req := &QQPrePayReq{};
raw_data, _ := json.Marshal(util.UrlValuesToMap(value))
err := json.Unmarshal(raw_data, &req)
req.ZoneId = "1"
req.Amt = 1
req.Ts = int(time.Now().Unix())
req.GoodNum = 1
data, _ := json.Marshal(req)
resp, err := http.Post(u, "application/json;charset=UTF-8", bytes.NewReader(data)) resp, err := http.Post(u, "application/json;charset=UTF-8", bytes.NewReader(data))
if err != nil { if err != nil {
log.Error("Post error ", err) log.Error("Post error ", err)

View File

@ -69,3 +69,7 @@ func initPool() {
} }
} }
} }
func IsValidServerId(sid uint32) (bool) {
return sid > 0 && sid < 200000000;
}

View File

@ -4,6 +4,7 @@ import (
"encoding/binary" "encoding/binary"
"math" "math"
"math/rand" "math/rand"
"net/url"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -401,3 +402,15 @@ func CombineMapU64U32(m1, m2 map[uint64]uint32) map[uint64]uint32 {
return m1 return m1
} }
func UrlValuesToMap(v url.Values) map[string]string {
ret := make(map[string]string)
for k := range v {
if len(v[k]) > 0 {
ret[k] = v[k][0]
} else {
ret[k] = ""
}
}
return ret
}

View File

@ -66,7 +66,8 @@ func (id *idWorker) nextid() (int64, error) {
} else { } else {
id.sequence = 0 id.sequence = 0
} }
sarly := time.Now().Unix() % nodeMask var sarly int64 = 1
//sarly := time.Now().Unix() % nodeMask
id.lastTimestamp = timestamp id.lastTimestamp = timestamp
return ((timestamp - id.twepoch) << timestampLeftShift) | (sarly << nodeIdShift) | id.sequence, nil return ((timestamp - id.twepoch) << timestampLeftShift) | (sarly << nodeIdShift) | id.sequence, nil
} }

View File

@ -12,6 +12,7 @@ type CommonConfig struct {
Debug bool `yaml:"debug"` // 是否测试环境 Debug bool `yaml:"debug"` // 是否测试环境
IsHGameDebug bool `yaml:"isHGameDebug"` // 测试的充值渠道 IsHGameDebug bool `yaml:"isHGameDebug"` // 测试的充值渠道
IsHuaweiPayDebug bool `yaml:"isHuaweiPayDebug"` // 测试华为的充值渠道 IsHuaweiPayDebug bool `yaml:"isHuaweiPayDebug"` // 测试华为的充值渠道
IsProxyDebug bool `yaml:"isProxyDebug"` // 测试代理服务器
} }
type RedisConfig struct { type RedisConfig struct {

View File

@ -3,8 +3,8 @@ package config
const ( const (
WXAppID = "" WXAppID = ""
WXAppSecret = "" WXAppSecret = ""
QQAppID = "" QQAppID = "1109788480"
QQAppSecret = "" QQAppSecret = "a6xKTrhGM2IvGEaU"
// oppo的APPid // oppo的APPid
OppoAppID = "30203124" OppoAppID = "30203124"
// OPPO的支付秘钥 // OPPO的支付秘钥
@ -49,34 +49,34 @@ NF3guaUf9bEOBc8WVQIDAQAB`
// 华为 // 华为
const ( const (
HuaweiAppId = "101381633" HuaweiAppId = "101381633"
HuaweiPayId = "890086000300110644" HuaweiPayId = "890086000300096364"
HuaweiAppSecret = "a78915d8df88e59d0a2b552d2abe147d3f8c62cfc345176a198bbea3f905b076" HuaweiAppSecret = "a78915d8df88e59d0a2b552d2abe147d3f8c62cfc345176a198bbea3f905b076"
HuaweiPublicKey = `MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqpRCMMJqNgP2oj40Isnh HuaweiPublicKey = `MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsO0P48iyB/lJpyooyUd+
diRh9eRqWHg9NFOaDTB7zL/TRSJ++SUlB2WoLHoZzM2aw/L+grWFRO4XvTI4hT9sivWNa37pmTu n+XCc2T3SQjDkb9Ci4AuiW61z3oRv6JBtLyhT3z55HdJL87W3IgJdERDHiPt7XMmMs806w6K15Q
b+Q1+r7Iszwwq1NuOaW+9tpvDespq3H+YMOqCGhZCBNZrtHIw86kIDfjjG26UI0TgW/LGo8Jv0k Xp9xi17x/aDA956oHT54qbK6akZuHb35Yf9ptFK5tjd1eJjHJywg2tUzLEl032QKTYZd9NkPWMv
q4RiI7Ok2hzM26+Rcf7L42EQuEcVfixQnHNQTUSwrGZX6M2LBT6YjBceqzYRhZsRHe5V2y8Uo80 q6+E4UbXWSGZpEEwG6UxYfqKh9uFoF9AD8cIwKIrZeJLalQj4GODxyPYvjPy2Ce57oFCl4HJsbH
zUe0+cyi/faPjCZy2fdkMJ5OQixpAmSndh4PyIrxLSufgfm153dceRPb/okPcXsA/kbJ03lA6Yp Oxzh0So7PP5kg2G4OhXrEHrQkekF88nSLXRWeby2aQqX/Jye+0WDkuANkB2j8ycoEToOvOdvAMK
u4WRNs02gjH3nagKLOEcOwIDAQAB` gBRHcTjQGuLjHnbNqFgjWwIDAQAB`
HuaweiPrivateKey = `MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCqlEIwwmo2A/ai HuaweiPrivateKey = `MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCw7Q/jyLIH+Umn
PjQiyeF2JGH15GpYeD00U5oNMHvMv9NFIn75JSUHZagsehnMzZrD8v6CtYVE7he9MjiFP2yK9Y1 KijJR36f5cJzZPdJCMORv0KLgC6JbrXPehG/okG0vKFPfPnkd0kvztbciAl0REMeI+3tcyYyzzT
rfumZO5v5DX6vsizPDCrU245pb722m8N6ymrcf5gw6oIaFkIE1mu0cjDzqQgN+OMbbpQjROBb8s rDorXlBen3GLXvH9oMD3nqgdPnipsrpqRm4dvflh/2m0Urm2N3V4mMcnLCDa1TMsSXTfZApNhl3
ajwm/SSrhGIjs6TaHMzbr5Fx/svjYRC4RxV+LFCcc1BNRLCsZlfozYsFPpiMFx6rNhGFmxEd7lX 02Q9Yy+rr4ThRtdZIZmkQTAbpTFh+oqH24WgX0APxwjAoitl4ktqVCPgY4PHI9i+M/LYJ7nugUK
bLxSjzTNR7T5zKL99o+MJnLZ92Qwnk5CLGkCZKd2Hg/IivEtK5+B+bXnd1x5E9v+iQ9xewD+Rsn Xgcmxsc7HOHRKjs8/mSDYbg6FesQetCR6QXzydItdFZ5vLZpCpf8nJ77RYOS4A2QHaPzJygROg6
TeUDpim7hZE2zTaCMfedqAos4Rw7AgMBAAECggEACffaAMSlTxZfAYIsqvyTLioLU3XcRRYM6Mb 8528AwqAFEdxONAa4uMeds2oWCNbAgMBAAECggEABc2YxN9leJfwIqaQrC7kSDfloHc7AtIb/vb
nhLr/MRFKRL4yuPDtWTsc+P4CdFzVHRUd8s0UYAyhDhxZZmgB05w5fgoPl2j+9C62s+7vywJ4ak GD35N9wDaBYJDtwpEW4vxQl/H/Clz0355KoCCgWu4rMO6HFbxxvA5lFkQWlEByFp9sXm4FQGLWH
uRgFXYVBiFwHvQ6aVgyZ/N2vDPPaS67I0tXfMHY0TWuLhDwRl55vjb/mvfyJeFGKSAO0PN5Sj1G F+CCt198VvnxbuRZ4mDz1SWW4sH0gjdl8o38O5+jHqN2178lLXzeARMy5otJh81M2CFt77WdUFu
PxVQaW4x7hYa5kntwmumdvAA3OaqlxmZdIXyirn9Rbv5x+ZClkKorr9UahL9Hc1Cj6JyBy1tK7k 2l6j3uj4EF+PcwyaBAD8RWjbDZL9U4KNj2TVdc9zaTTNOl4laTfcZhMiCtuvZwa1d2eA8JvkqPP
Ry4J3kyjRrvHI81zDN3qi9HIlRtdqkafxsBtGHlF63ORbWkdLJkJYk6/bmF7FCX7aJDddZgKNj2 CbpH+l4PvJfrSp+3ugj+PNNtD6uihDtE3JWd1wOkwTX1XKcMJw3W+qnrEMCr7TyfPRk+NcD1fNL
aU1ccIQKBgQDlnYcE1IdL270msFFQ4VMXKldzZI8THyLEaTttG6tnQHtj04BmgO1WVYRYvEUIoX /6APZgQKBgQDmrcyLBuFTPEXv/Bh/fwFLRiZF2p3zSaf/QlH33xU54KQwq70wKoixtVHPR/ZQc1
P/PAvuBwrCnUOKi8AJfgR1J4ak23kh5QsR++NTBTmZEMNtdTjybu6bm1ys9AycOOxYGHxF+Xvt8 c5HLpXFZiVDrJOtRNG+uBE0CLg40PlkzrmR4yLTpN37cXs/yMBgm3mbBZjtgbhqMA7TghdEaJgN
xSmmYPBpwIT+nhaFTIUs8ipZBEIZGCcywKBgQC+Lhgqhz95Ngf3QfPZJxtVZzWueMr+/NOp4kNV cK2F48gH9nwYYhxpfvtr95kqW/V4N/XgQKBgQDEWMdASXPXnKfZEcU366++C7NRLpWIdG9jgGWA
4rpP5J+lM7tBvDkKxnw9SCVZrJaTTOmK2dtRMpcy4umDz+00Mvqxns132tI1nZk7g9yNJhPWjC2 VvHs851Tdoqb4wfmmesgbmwVbljor9jNkwuNiYAyx7D7lCVg+OyhUJWvrClSaLBRAN6vqSYyumS
sHSj94VN0x8KRvIUnrNiLOI4bk7FEZyvsBQcGGOTsrwRGvY9aWFnA0H6AUQKBgCqOAWIByXljpj 0MmZfbLnfW/a1PpeJQEM532zyEC7stPqgytPPfIEdRDHSITxlNrX+137I2wKBgHHuBMflbgQeEK
CvaMKmn/GhJUf7kRCoKpdgMWVNRX0DVFrx7dARgOsJOlf/vIOW+JqLFGLu5y2eW9AnilW4Bzd3N ymZbMSlyEGVIDLqJcwGbkImFND6sfbGzyulZHkb/7U/sLRV+YEEWAzwBSipel4iLg21n6ICZvy8
dsD2fVQL7cLidvvEfeuRanZmc5EhPBN4OUk7dleK19AWnfVfwRgkqk1tleDjj0JpJh9aSSxFTVf EcB99a7EKwLSm7DMDJbTRXwLOnh8UWMvMIidOOe5NJlh9vvibLa2n/0wsuq74i5oxn+UJ7j7YLp
mFCH2ef1AoGAf3HIRAeqY4HvyKRr0uPAD3VAphDQiBvJhBjaYt2zWQKucTi/jgeiejQU4cRNM1D 7EJF/kgBAoGBAJVX0XYcaHg/N4vr8E4wfmPXEnVVMXew2GieaJXNjAXm5mttZtBbRs8nk6f/VUa
S/xcVkjT4IeuzIyior+pQ3SAkm479xgnfwIpCO33b+MLBnI8HtEU+SRQMpz+Ohbc9zB6qZnGZ2a XwBh8aDM0/TySsWfua7dvX17690Fbwf70vBlqd3Glb7u8tMkw7RgCnctHL7msgWIqUaibsIZ8Yq
UZr+srpdigoldgYbPPO9CgFj0KuIl/nGECgYEAjg0V7IMMXRoK09Sw0RGcKEDSYZ1bgPaQhrSQJ lbldWFcnyKycCvuqVAEYT6sq1ph9RmpJCxAoGAe0t7nY7JFImFv633m2QYbJNDajDs+SPbCdbr4
XUU+K+E+HwdK8+xvaJQg3bHaCQ5m8VVITaG3hjdlgaPx9bVKdHGpeg6JpbNX9KiWA1TxRUW2pxP jOm16JoXjPZXO3T3FD4OrXAdn2YA67dThrcrhtL0/vtqoeh8t3QVlmBS3KML5d7G2uGp7w3RGqG
ssQoYIQzDNNyRZd23XhvOYLffVyuN3tNsOSQ/2GlAD45YWrcKhNNiQHz2wE=` X3Yzi3GiYw9xOjLaBO7a20z3tK8u/U1IR0lDTKNmuLzaIKiJV2VC2NeQqeQ=`
) )