Commit 568058bb authored by wang's avatar wang

解密函数完成

parent d2aa09f3
This diff is collapsed.
......@@ -595,6 +595,7 @@ try {
return Math.round(+new Date() / 1e3);
}
function Mt(t) {
debugger;
pt = t;
}
var xt;
......@@ -2407,6 +2408,7 @@ try {
var n = Eo;
var r = Ls(l.ts);
return delete l.ts, vo["forEach"](function (t) {
console.log('forEachforEachforEach',t, ho,l )
return ho[t] = l[t];
}), t(!r && l);
});
......@@ -3674,6 +3676,7 @@ try {
var a = t["slice"]();
var o = function () {
var t = pf;
console.log('sts', Gs())
var e = Gs() || "1604064986000";
return pe($(e), 10);
}();
......@@ -4081,6 +4084,8 @@ try {
cs: J,
pc: b
};
console.log(JSON.stringify(t))
console.log(w)
var A = mf(t, w);
var E = [Wf + A, Of + Bl[Hn], _f + Bl[Tn], Mf + Rs, Vf + Bl[Xn], Pf + al++, Lf + qf];
var I = Ns();
......@@ -4999,6 +5004,7 @@ try {
function wh() {
var t = i;
return new T(function (e) {
debugger;
m.storage && m.storage.estimate || e(u({}, t("YRRJB3EBXQ"), G("no_fp"))), m.storage.estimate().then(function (n) {
e(u({}, t("YRRJB3EBXQ"), G(n && n.quota || "no_fp")));
}).catch(function () {
......
......@@ -14,6 +14,7 @@ with open('js/encodepayload.js', 'r', encoding='utf-8') as f:
ctx = execjs.compile(jsCode)
ctxPC = execjs.compile(open('pc.js').read())
ctxStep2 = execjs.compile(open('captcha_step2.js').read())
ctxStep3 = execjs.compile(open('captcha_down.js').read())
def get_timestamp():
......@@ -32,8 +33,17 @@ class PxBypass():
'http': 'http://127.0.0.1:7890',
'https': 'http://127.0.0.1:7890',
}
code1 = ''
code2 = ''
tag = ''
vid = ''
uuid = ''
token = ''
sts = ''
ci = ''
cs = ''
sid = ''
cts = ''
# session.proxies = {
# 'http': "http://user-unifflcc-region-us:q39CEBTs5A5YQXor@pr.roxlabs.cn:4600",
# 'https': "http://user-unifflcc-region-us:q39CEBTs5A5YQXor@pr.roxlabs.cn:4600",
......@@ -48,18 +58,34 @@ class PxBypass():
self._step_1()
self._step_2()
self.__token()
self._step_3()
c = self.__token()
if c == 403:
self._step_1()
self._step_2()
self._step_3()
self.log.info(self.session.cookies.get_dict())
def _init(self):
headers = {
res = self.session.get(
'https://booking.flyfrontier.com/Flight/InternalSelect?o1=DEN&d1=LAS&dd1=2023-08-30&ADT=1&umnr=false&mon=true',
headers={
"authority": "www.flyfrontier.com",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,ru;q=0.6",
"cache-control": "no-cache",
"pragma": "no-cache",
"sec-ch-ua": "\"Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"115\", \"Chromium\";v=\"115\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"macOS\"",
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "none",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
}
res = self.session.get(self.target_url, headers=headers, allow_redirects=True)
}, allow_redirects=True)
self.log.info(f"初始化请求 res {res.status_code}")
self.params = {}
for k, v in self.session.cookies.items():
......@@ -68,9 +94,11 @@ class PxBypass():
vids = re.findall("_pxVid = '(.+?)'", res.text)
if len(vids) != 0:
self.vid = vids[0]
self.log.info(f'获取到vid {self.vid}')
uuids = re.findall("_pxUuid = '(.+?)'", res.text)
if len(uuids) != 0:
self.uuid = uuids[0]
self.log.info(f'获取到uuid {self.uuid}')
with open('index.html', 'w') as f:
f.write(res.text)
......@@ -141,7 +169,24 @@ class PxBypass():
t = data[3].split('_')
self.token = t[0]
self.ci = t[1]
if key == '0III0III':
self.sts = data[0]
if key == 'I0I0I0':
self.hash = data[1]
self.hash2 = data[2]
self.hashv = data[3]
if key == 'I0I0II':
self.sid = data[0]
if key == 'I000I0':
self.vid = data[0]
if key == 'I00III':
self.code2 = data[0]
if key == 'IIII00':
self.tag = data[0]
if key == '0III00I0':
self.cts = data[0]
if key == '0III0II0':
self.code1 = data[0]
if 'pxde' in i:
self.session.cookies.update({
'_pxde': tmp[3]
......@@ -169,12 +214,13 @@ class PxBypass():
})
self.log.info(f'cookies1 {self.session.cookies.keys()}')
self.m = m
self.token = m['I00II0']
# self.token = m['I00II0']
self.log.info(self.m)
def _step_1(self):
t1 = int(time.time() * 1000)
self.init_time = t1
t2 = t1 + random.randint(3, 12)
if self.uuid == '':
self.uuid = self.__uuid()
......@@ -287,15 +333,25 @@ class PxBypass():
print(response.status_code)
with open('index.html', 'w') as f:
f.write(response.text)
vids = re.findall("_pxVid = '(.+?)'", response.text)
if len(vids) != 0:
self.vid = vids[0]
self.log.info(f'获取到vid {self.vid}')
uuids = re.findall("_pxUuid = '(.+?)'", response.text)
if len(uuids) != 0:
self.uuid = uuids[0]
self.log.info(f'获取到uuid {self.uuid}')
return response.status_code
def _step_2(self):
self.log.info(self.m)
self.log.info(self.uuid)
data_str = ctxStep2.call('genPayload2', self.m, self.uuid)
# genPayload2(vid, sid, uuid, sts, code1, code2, tag)
data_str = ctxStep2.call('genPayload2', self.vid,self.sid,self.uuid, self.sts, self.code1, self.code2, self.tag)
self.log.info(f'data_str2 {data_str}')
payload = ctx.call('encodePayload', data_str, self.uuid, '')
payload = ctx.call('encodePayload', data_str, self.uuid, self.sts)
self.log.info(f'payload {payload}')
tag = "v8.6.6"
ft = "316"
......@@ -308,11 +364,11 @@ class PxBypass():
"ft": ft,
"seq": "1",
"en": "NTA",
"cs": self.m['00III0'],
"cs": self.cs,
"pc": pc,
"sid": self.m['I0I0II'],
"vid": self.m['I000I0'],
"cts": self.m['0III00I0'],
"sid": self.sid,
"vid": self.vid,
"cts": self.cts,
"rsc": "1"
}
url = "https://collector-pxvb73hteg.px-cloud.net/assets/js/bundle"
......@@ -371,6 +427,92 @@ class PxBypass():
self.log.info(f'cookies2 {self.session.cookies.keys()}')
self.m = m
self.log.info(self.m)
def _step_3(self):
# self.log.info(self.m)
# self.log.info(self.uuid)
time.sleep(5)
data_str = ctxStep3.call('genPayload', self.uuid, self.vid, self.hash, self.hash2, self.hashv, self.token, self.ci, self.init_time)
self.log.info(f'data_str2 {data_str}')
data_str = json.dumps(data_str)
payload = ctx.call('encodePayload', data_str, self.uuid, self.sts)
self.log.info(f'payload {payload}')
tag = "v8.6.6"
ft = "316"
pc = self.__gen_pc(data_str, f'{self.uuid}:{tag}:{ft}')
body = {
"payload": payload,
"appId": "PXVb73hTEg",
"tag": tag,
"uuid": self.uuid,
"ft": ft,
"seq": "4",
"en": "NTA",
"cs": self.cs,
"pc": pc,
"sid": self.sid,
"vid": self.vid,
"ci": self.ci,
"cts": self.cts,
"rsc": "3"
}
url = "https://collector-pxvb73hteg.px-cloud.net/assets/js/bundle"
headers = {
"authority": "collector-PXVb73hTEg.px-cloud.net",
"accept": "*/*",
"accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
"cache-control": "no-cache",
"content-type": "application/x-www-form-urlencoded",
"origin": "https://www.flyfrontier.com",
"pragma": "no-cache",
"referer": "https://www.flyfrontier.com/",
"sec-ch-ua": "\"Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"115\", \"Chromium\";v=\"115\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "cross-site",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
}
response = self.session.post(url, headers=headers, data=body)
self.log.info(f'collector3 {response.text}')
resp = response.json()
m = {}
if 'ob' in resp:
cookies = self.encrypt(base64.b64decode(resp['ob'].encode()), 866 % 128).decode()
print(cookies.split('~~~~'))
for i in cookies.split('~~~~'):
tmp = i.split('|')
m[tmp[0]] = tmp[1]
if 'pxde' in i:
self.session.cookies.update({
'_pxde': tmp[3]
})
elif '_px2' in i:
self.session.cookies.update({
'_px2': tmp[3]
})
elif '31536000' in i:
self.session.cookies.update({
'_pxvid': tmp[1]
})
else:
for i in resp['do']:
tmp = i.split('|')
# print(len(tmp), tmp)
if len(tmp) == 6 and tmp[1] in ['_px', '_px3', '_pxde']:
self.session.cookies.update({
tmp[1]: tmp[3]
})
elif len(tmp) in [3, 4] and tmp[1] in ['cts', 'vid']:
self.session.cookies.update({
tmp[0]: tmp[1]
})
self.log.info(f'cookies2 {self.session.cookies.keys()}')
self.m = m
self.log.info(self.m)
if __name__ == '__main__':
......
......@@ -789,7 +789,7 @@ for (let j = 0; j < 3; j++) {
if (args[1] === undefined) return;
// console.log('xxx', callee.name)
// console.log(generator(path.node).code)
if (generator(path.node).code.indexOf('(1277, 1264)') > -1)debugger
if (generator(path.node).code.indexOf('(1277, 1264)') > -1) debugger
if (funcTemp[callee.name]) {
let arggs = [];
......@@ -915,11 +915,11 @@ traverse(ast, {
debugger
}
if (!binding) return;
// console.log(id.name, init.name, binding.references)
console.log(id.name, init.name, binding.references)
for (const referencePath of binding.referencePaths) {
// console.log(referencePath);
// console.log(generator(referencePath.parent).code)
console.log(generator(referencePath.parent).code)
// console.log(referencePath.parentPath.type)
if (types.isCallExpression(referencePath.parent)) {
......@@ -929,7 +929,7 @@ traverse(ast, {
let res = o(arguments[0].value)
// if (id.name === 'xs') {
//
// console.log(generator(referencePath.parent).code, res)
console.log(generator(referencePath.parent).code, res)
// }
referencePath.parentPath.replaceWith(types.StringLiteral(res))
}
......@@ -941,7 +941,27 @@ traverse(ast, {
}
})
traverse(ast, {
CallExpression(path) {
// console.log(referencePath.parentPath.type)
let {callee, arguments} = path.node;
if (!types.isIdentifier(callee))return;
if (arguments.length === 1 && types.isStringLiteral(arguments[0])
&& arguments[0].value.length < 50) {
try {
let res = o(arguments[0].value)
// if (id.name === 'xs') {
//
console.log(generator(path.node).code, res)
// }
path.replaceWith(types.StringLiteral(res))
} catch (e) {
}
}
}
})
//end
console.timeEnd("处理完毕,耗时");
......
This diff is collapsed.
This diff is collapsed.
......@@ -96,26 +96,26 @@ function getNoPX(data) {
let ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36';
function genPayload2(m, uuid) {
let vid = m['I000I0']
let sid = m['I0I0II']
function genPayload2(vid,sid, uuid, sts,code1, code2, tag) {
// let vid = m['I000I0']
// let sid = m['I0I0II']
console.log(vid, sid)
let data = {
// "PX11431": 1692944411084, // 0III0III
"PX11431": m['0III0III'], //
"PX11431": sts, //
// "75602>44073>?2261175": "46531=77340=<1152246",
"PX12454": m['0III0II0'], // 0III0II0
"PX11701": m['I00III'], // I00III
"PX12454": code1, // 0III0II0
"PX11701": code2, // I00III
"PX11529": 102721973,// usedJSHeapSize
"PX11555": 4294705152,// jsHeapSizeLimit
"PX11833": 122502277,// totalJSHeapSize
// "PX11840": "Fri Aug 25 2023 14:20:11 GMT+0800 (中国标准时间)",
"PX11840": new Date() + '',
// "PX12573": "e29b74b1", // parseInt(0III0III/10)
"PX12573": getPX12573(m['0III0III'], m['I000I0'], uuid), // parseInt(0III0III/10)
"PX12573": getPX12573(sts, vid, uuid), // parseInt(0III0III/10)
// "PX11804": "36f924a304c56d1ae9971c767ca7f510", //uuid 转换
"PX11804": createPx2(ua, uuid), //uuid 转换
"PX12118": m['IIII00'],// 第一步返回 0ll0ll
"PX12118": tag,// 第一步返回 IIII00
"PX11746": createPx2(ua, vid), //_pxvid // I000I0
"PX11371": createPx2(ua, sid), // pxsid sessionStorage // I0I0II
"PX12501": md5(vid), // vid md5
......@@ -325,7 +325,7 @@ function genPayload2(m, uuid) {
"PX11387": 0,
"PX12150": 1920,
"PX12304": true,
"PX11651": 970,
"PX11651": 1055,
"PX11867": "missing",
"PX12254": true,
"PX11540": true,
......@@ -376,6 +376,8 @@ let m = {
'00I0I0': 'cu',
'I00III': '67516906593483079816'
}
console.log(genPayload2(m, '0c01fa19-6c58-1031-92d0-cb50f373e9d4'))
console.log(genPayload2('856480e4-4718-11ee-a09c-59eac09c79dd', '8d791613-4718-11ee-9cce-644567695074', '85647912-4718-11ee-a09c-7a41594b4170', '1693388127359', '2406', '64992269230534002466', 'cjngqns8o1hn7usv8t10'))
// console.log(JSON.stringify(data))
// console.log(data[0].d.PX11804)
\ No newline at end of file
......@@ -9,19 +9,19 @@
</head>
<body>
<script>
window._pxVid = '';
window._pxUuid = '32f11b33-464c-11ee-bc69-5a6959504766';
window._pxVid = '2f5d0d79-4719-11ee-bc23-5a0cace3b0d3';
window._pxUuid = '2f5d09c5-4719-11ee-bc23-4f7477666252';
window._pxAppId = 'PXVb73hTEg';
window._pxHostUrl = 'https://collector-PXVb73hTEg.perimeterx.net';
window._pxCustomLogo = '';
window._pxJsClientSrc = '//client.perimeterx.net/PXVb73hTEg/main.min.js';
window._pxFirstPartyEnabled = 'false';
var script = document.createElement('script');
script.src = '//captcha.perimeterx.net/PXVb73hTEg/captcha.js?a=c&u=32f11b33-464c-11ee-bc69-5a6959504766&v=&m=0';
script.src = '//captcha.perimeterx.net/PXVb73hTEg/captcha.js?a=&u=2f5d09c5-4719-11ee-bc23-4f7477666252&v=2f5d0d79-4719-11ee-bc23-5a0cace3b0d3&m=0';
document.head.appendChild(script);
script.onerror = function () {
script = document.createElement('script');
script.src = 'https://captcha.px-cloud.net/PXVb73hTEg/captcha.js?a=c&u=32f11b33-464c-11ee-bc69-5a6959504766&v=&m=0';
script.src = 'https://captcha.px-cloud.net/PXVb73hTEg/captcha.js?a=&u=2f5d09c5-4719-11ee-bc23-4f7477666252&v=2f5d0d79-4719-11ee-bc23-5a0cace3b0d3&m=0';
script.onerror = window._pxDisplayErrorMessage;
document.head.appendChild(script);
};
......
This diff is collapsed.
......@@ -333,18 +333,21 @@ function genPayload2(m, uuid) {
}
let m = {
'IIIIII': 'cc',
'I000I0': '78356ad9-45b6-11ee-99d6-31d3d6e2cfff',
'0III0II0': '7739',
'0III00I0': 'f8ca58ff-4706-11ee-8ad9-614247755465',
'00III0': 'cad902e272e8962eb647a943dcd3e2b33a51b2dd2984c00116b0e63df1ce9fd8',
'IIII00': 'cjnevo1ushun7urncgfg',
'IIIIII': 'fp',
'I00III': '15030756842869753411',
'I0I0II': 'f8ca555c-4706-11ee-8ad9-614247755465',
'0III0III': '1693380576466',
'IIII0I': 'ccc:300',
'0III0II0': '7651',
'I00II0': '1',
'I0I0I0': '1',
'IIIII0': '_px2',
'IIII00': 'cjmbml7i2tmdkbrr7oog',
'I0I0II': '7996c011-45b6-11ee-8082-7a507a665249',
'0III00I0': '7996c46d-45b6-11ee-8082-7a507a665249',
'00III0': 'd3277e7172bb0da06d0bf4a6d7b4348b91662484ca9461f8575ea799ea07b3fd',
'0III0III': '1693236052168',
'00I0I0': 'cu',
'I00III': '67516906593483079816'
'00I0I0': 'cu'
}
console.log(genPayload2(m, '0c01fa19-6c58-1031-92d0-cb50f373e9d4'))
console.log(genPayload2(m, 'f3920367-4706-11ee-b994-674b47685845'))
// console.log(JSON.stringify(data))
// console.log(data[0].d.PX11804)
\ No newline at end of file
......@@ -460,7 +460,7 @@ function oaa2(n) {
console.log(btoa(u).replaceAll('=',''))
return btoa(uu).replaceAll('=','')
}
console.log('oaa2',oaa2("PX12040"))
console.log('oaa2',oaa2("PX12362"))
function $C_pMN(t) {
......
......@@ -60,10 +60,29 @@ a2 = "KysrKytSHj0SGlAeUVFSHgcbKFMrCA0LLBg3GjgmLxUvJTcWLCY7UiwbUhovNTQOLjUnFSw1Mx
a2 = "UisrUitSHhEBDRAHHlIeAAsMAxAbHBwcHCsrKysrUh49EhpQHlFRUh4HGyhTKwgNCzsINA8sJjsYLA87FiwmO1IsG1IaLzU0Di41J1MsJSsWLBgjUiwYM1csJglSOwgBGysLFQsGCytUKw8zFS01M1ctNjNTLjYzUCwmARYvNiQOODFTCiw2MAsuNjMYLyYGCi9QJxg4NScaOCErESsMMwstCDcYLzYzUiwIMxUvIRULAyErVCsICg4tJiQPLwgnGi8lJxosJg4POxg3FTg2MA4tNTtTLAg3Vzg1Oxo7UDAJOCYzVzsYOA4vGCtRO1AnGDgIN1MsJicYLTUnGDsPM1IvGDgPO1A7Gi8YAQsEM19fHhYQFwceUVJSHBwcHFIrK1IrUh4RAQ0QBx5SHgALDAMQGxwcHBxSKysrK1JSUh49EhoGBx5RUVIeUVRRU1JRBlEAVFJUA1pQV1QEB1VXBgFXVAcHUQQHVVVUBFFRV1paV1VSAVYHVgRUAVdXAAFQAFoAWgdbUFEGBlgHGyhSAzVTDgFRMAoAOiMLLQgnUC02LxstNgVTLBg3ViwIMFseFhAXBx5RUlIcHBwcUisrK1IrUlIeUhwcHBxSUitSK1IeARc="
a2 = "KysrKytSHj0SGlAeUVFSHgcbKFMrCA0LLxgoDy82JAsvGC8WLCY7UjsbUhovNTQOLjUoCCwICRYsNSdQLTY3Vyw2I1IsGDtQKwsVCwYLK1QrCDQOOxgjVzg2K1AuNjNQLCUvFi82JA44MVMKLSYzUC41M1EsGAYPLFA7GywmK1MvGysRKwwzCy0IJ1AtNi8YLyYjUS8YCVAsGAERKw8FCy0LKxs7NiQKOAg3UCwIDgo7NjtSLDUnVzgIMxsvJidSOAgGCixQKxsvDy9TODY7UCwIJ1AsCAFRO1A7VywYO1MsNiNTLA8kCjgPLA8vNjQOOCU4Diw1OA8rDFJfHhYQFwceUVJSHBwcHFJSK1IrUh4BFw=="
a2 ="UlIrUitSHgEXHBwcHFIrKytSK1JSHlIcHBwcKysrKytSHj0SGlAeUVFSHgcbKFMrCA0LLDUnUC02O1E4Ni8WLCYBFSwxUhovNTQOLjYOCDtQKxYsGAFSOxg3UywICVEsJjdTKwsVCwYLK1QrCDQKLAgJUDs1N1cuNjNRLyY3Fi82JA44MVJXO1AsCy42BVYvGDcbLwgvUi82Ixs7MSsRKwwzCy0IJ1AtNi8YLSYjGC8IK1IsNicRKw8FCy0LKAkvGAoILDUwDzgmCg47UDgPLSYgCSw1NAk4NTgLLBg4Cjs1K1AsNglWOxgKDzsIIAo4CCMYLDUoCDsPJxgsJisaLCYvUSw2J1MtJTdXOw8vUy82JA8rDFJfHhYQFwceUVJS"
# 0III0I00 判断是否通过
b2 = base64.b64decode(a2.encode())
for i in bytes(encrypt(b2, 98)).decode().split('~~~~'):
print(i)
print('0III0I00'in i, i)
'''
I00II0|1|14e8b370-46df-11ee-9636-9d314c873224|8721|1627b0d797dbd3f6b58b265bcbe1d06f1982137a1c5b07061977272fce900d5f87bbf14528372ba6de2e9a2adb2e6667be0a672b1cfd53ff0d1cbee2d0700f5e_<<=:|0|NA
IIIII0|_px2|330|eyJ1IjoiYjIyYWI2MTEtNmM1OC0xMDMxLTlhNDAtZjU0MDBjNjdkNjMwIiwidiI6ImY0NmNhZmE1LTQ2ZGUtMTFlZS05MWM0LTRiYWRkZmE1YjNlMyIsInQiOjE2OTMzNjM3NDM3NTEsImgiOiJjMmY1ZjQ5Y2JhNjRhODBjN2I5ZWRlYzU3YjVlZDJkY2IxZjMzMDc1MTJhZTQ3NzIyYzlhY2VjZTQ0YjgyYmVkIn0=|true|300
I0I0I0|1|3f843d1f8022e5c954c8356388d1264949df69eccba81acf1447ff2ac806|606ac27aab15093b4bc5a307f293804843fc22ccd81c128cdce88448b7bc42c7|17|false
I00III|15041159139452913395
00I0I0|cu
IIII0I|ccc:300
IIIIII|cc|60|U2FtZVNpdGU9TGF4Ow==
0III00I0|14e5e081-46df-11ee-be3b-6b4862687642|true
IIIIII|rf|60|1
0III0II0|7500
0III0III|1693363443751
IIII00|cjnapsvd4thn7uq9lgm0
I0I0II|14e5dd68-46df-11ee-be3b-6b4862687642
IIIIII|fp|60|1
00III0|86809e0cf02a54019055668b6cd60d5f437718e85c33cbadb17c156f134514b5
'''
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment