Show More
@@ -721,8 +721,9 b' class patchfile(object):' | |||||
721 | if self.remove: |
|
721 | if self.remove: | |
722 | self.backend.unlink(self.fname) |
|
722 | self.backend.unlink(self.fname) | |
723 | else: |
|
723 | else: | |
724 |
|
|
724 | l = h.new(self.lines) | |
725 |
self. |
|
725 | self.lines[:] = l | |
|
726 | self.offset += len(l) | |||
726 | self.dirty = True |
|
727 | self.dirty = True | |
727 | return 0 |
|
728 | return 0 | |
728 |
|
729 | |||
@@ -1016,9 +1017,10 b' class hunk(object):' | |||||
1016 | return old, oldstart, new, newstart |
|
1017 | return old, oldstart, new, newstart | |
1017 |
|
1018 | |||
1018 | class binhunk(object): |
|
1019 | class binhunk(object): | |
1019 |
'A binary patch file. |
|
1020 | 'A binary patch file.' | |
1020 | def __init__(self, lr, fname): |
|
1021 | def __init__(self, lr, fname): | |
1021 | self.text = None |
|
1022 | self.text = None | |
|
1023 | self.delta = False | |||
1022 | self.hunk = ['GIT binary patch\n'] |
|
1024 | self.hunk = ['GIT binary patch\n'] | |
1023 | self._fname = fname |
|
1025 | self._fname = fname | |
1024 | self._read(lr) |
|
1026 | self._read(lr) | |
@@ -1026,7 +1028,9 b' class binhunk(object):' | |||||
1026 | def complete(self): |
|
1028 | def complete(self): | |
1027 | return self.text is not None |
|
1029 | return self.text is not None | |
1028 |
|
1030 | |||
1029 | def new(self): |
|
1031 | def new(self, lines): | |
|
1032 | if self.delta: | |||
|
1033 | return [applybindelta(self.text, ''.join(lines))] | |||
1030 | return [self.text] |
|
1034 | return [self.text] | |
1031 |
|
1035 | |||
1032 | def _read(self, lr): |
|
1036 | def _read(self, lr): | |
@@ -1035,14 +1039,19 b' class binhunk(object):' | |||||
1035 | hunk.append(l) |
|
1039 | hunk.append(l) | |
1036 | return l.rstrip('\r\n') |
|
1040 | return l.rstrip('\r\n') | |
1037 |
|
1041 | |||
|
1042 | size = 0 | |||
1038 | while True: |
|
1043 | while True: | |
1039 | line = getline(lr, self.hunk) |
|
1044 | line = getline(lr, self.hunk) | |
1040 | if not line: |
|
1045 | if not line: | |
1041 | raise PatchError(_('could not extract "%s" binary data') |
|
1046 | raise PatchError(_('could not extract "%s" binary data') | |
1042 | % self._fname) |
|
1047 | % self._fname) | |
1043 | if line.startswith('literal '): |
|
1048 | if line.startswith('literal '): | |
|
1049 | size = int(line[8:].rstrip()) | |||
1044 | break |
|
1050 | break | |
1045 | size = int(line[8:].rstrip()) |
|
1051 | if line.startswith('delta '): | |
|
1052 | size = int(line[6:].rstrip()) | |||
|
1053 | self.delta = True | |||
|
1054 | break | |||
1046 | dec = [] |
|
1055 | dec = [] | |
1047 | line = getline(lr, self.hunk) |
|
1056 | line = getline(lr, self.hunk) | |
1048 | while len(line) > 1: |
|
1057 | while len(line) > 1: | |
@@ -1265,6 +1274,62 b' def iterhunks(fp):' | |||||
1265 | gp = gitpatches.pop() |
|
1274 | gp = gitpatches.pop() | |
1266 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy()) |
|
1275 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy()) | |
1267 |
|
1276 | |||
|
1277 | def applybindelta(binchunk, data): | |||
|
1278 | """Apply a binary delta hunk | |||
|
1279 | The algorithm used is the algorithm from git's patch-delta.c | |||
|
1280 | """ | |||
|
1281 | def deltahead(binchunk): | |||
|
1282 | i = 0 | |||
|
1283 | for c in binchunk: | |||
|
1284 | i += 1 | |||
|
1285 | if not (ord(c) & 0x80): | |||
|
1286 | return i | |||
|
1287 | return i | |||
|
1288 | out = "" | |||
|
1289 | s = deltahead(binchunk) | |||
|
1290 | binchunk = binchunk[s:] | |||
|
1291 | s = deltahead(binchunk) | |||
|
1292 | binchunk = binchunk[s:] | |||
|
1293 | i = 0 | |||
|
1294 | while i < len(binchunk): | |||
|
1295 | cmd = ord(binchunk[i]) | |||
|
1296 | i += 1 | |||
|
1297 | if (cmd & 0x80): | |||
|
1298 | offset = 0 | |||
|
1299 | size = 0 | |||
|
1300 | if (cmd & 0x01): | |||
|
1301 | offset = ord(binchunk[i]) | |||
|
1302 | i += 1 | |||
|
1303 | if (cmd & 0x02): | |||
|
1304 | offset |= ord(binchunk[i]) << 8 | |||
|
1305 | i += 1 | |||
|
1306 | if (cmd & 0x04): | |||
|
1307 | offset |= ord(binchunk[i]) << 16 | |||
|
1308 | i += 1 | |||
|
1309 | if (cmd & 0x08): | |||
|
1310 | offset |= ord(binchunk[i]) << 24 | |||
|
1311 | i += 1 | |||
|
1312 | if (cmd & 0x10): | |||
|
1313 | size = ord(binchunk[i]) | |||
|
1314 | i += 1 | |||
|
1315 | if (cmd & 0x20): | |||
|
1316 | size |= ord(binchunk[i]) << 8 | |||
|
1317 | i += 1 | |||
|
1318 | if (cmd & 0x40): | |||
|
1319 | size |= ord(binchunk[i]) << 16 | |||
|
1320 | i += 1 | |||
|
1321 | if size == 0: | |||
|
1322 | size = 0x10000 | |||
|
1323 | offset_end = offset + size | |||
|
1324 | out += data[offset:offset_end] | |||
|
1325 | elif cmd != 0: | |||
|
1326 | offset_end = i + cmd | |||
|
1327 | out += binchunk[i:offset_end] | |||
|
1328 | i += cmd | |||
|
1329 | else: | |||
|
1330 | raise PatchError(_('unexpected delta opcode 0')) | |||
|
1331 | return out | |||
|
1332 | ||||
1268 | def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'): |
|
1333 | def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'): | |
1269 | """Reads a patch from fp and tries to apply it. |
|
1334 | """Reads a patch from fp and tries to apply it. | |
1270 |
|
1335 |
@@ -320,6 +320,115 b' Multiple binary files:' | |||||
320 | 045c85ba38952325e126c70962cc0f9d9077bc67 644 mbinary1 |
|
320 | 045c85ba38952325e126c70962cc0f9d9077bc67 644 mbinary1 | |
321 | a874b471193996e7cb034bb301cac7bdaf3e3f46 644 mbinary2 |
|
321 | a874b471193996e7cb034bb301cac7bdaf3e3f46 644 mbinary2 | |
322 |
|
322 | |||
|
323 | Binary file and delta hunk: | |||
|
324 | ||||
|
325 | $ hg import -d "1000000 0" -m delta - <<'EOF' | |||
|
326 | > diff --git a/delta b/delta | |||
|
327 | > new file mode 100644 | |||
|
328 | > index 0000000000000000000000000000000000000000..8c9b7831b231c2600843e303e66b521353a200b3 | |||
|
329 | > GIT binary patch | |||
|
330 | > literal 3749 | |||
|
331 | > zcmV;W4qEYvP)<h;3K|Lk000e1NJLTq006iE002D*0ssI2kt{U(0000PbVXQnQ*UN; | |||
|
332 | > zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU=M@d9MRCwC#oC!>o#}>x{(W-y~UN*tK | |||
|
333 | > z%A%sxiUy2Ys)0Vm#ueArYKoYqX;GuiqZpgirM6nCVoYk?YNAz3G~z;BZ~@~&OQEe4 | |||
|
334 | > zmGvS5isFJI;Pd_7J+EKxyHZeu`^t4r2>F;h-+VK3{_{WoGv8dSpFDYDrA%3UX03pt | |||
|
335 | > zOaVoi0*W#P6lDr1$`nwPDWE7*rhuYM0Y#YtiZTThWeO<D6i}2YpqR<%$s>bRRaI42 | |||
|
336 | > zS3iFIxJ8Q=EnBv1Z7?pBw_bLjJb3V+tgP(Tty_2R-mR#p04x78n2n7MSOFyt4i1iv | |||
|
337 | > zjxH`PPEJmgD7U?IK&h;(EGQ@_DJc<@01=4fiNXHcKZ8LhZQ8T}E3U4tUS3}OrcgQW | |||
|
338 | > zWdX{K8#l7Ev&#$ysR)G#0*rC+<WGZ3?CtG4bm-ve>Dj$|_qJ`@D*stNP_AFUe&x!Q | |||
|
339 | > zJ9q9B7Z=ym)MyZ?Tg1ROunUYr81nV?B@!tYS~5_|%gfW#(_s<4UN1!Q?Dv8d>g#m6 | |||
|
340 | > z%*@R2@bI2JdnzxQ!EDU`$eQY!tgI~Zn$prz;gaXNod5*5p(1Bz=P$qfvZ$y?dC@X~ | |||
|
341 | > zlAD+NAKhB{=;6bMwzjqn>9mavvKOGd`s%A+fBiL>Q;xJWpa72C+}u{JTHUX>{~}Qj | |||
|
342 | > zUb%hyHgN~c?cBLjInvUALMD9g-aXt54ZL8AOCvXL-V6!~ijR*kEG$&Mv?!pE61OlI | |||
|
343 | > z8nzMSPE8F7bH|Py*RNl1VUCggq<V)>@_6gkEeiz7{rmTeuNTW6+KVS#0FG%IHf-3L | |||
|
344 | > zGiS21vn>WCCr+GLx^!uNetzB6u3o(w6&1C2?_LW8ij$+$sZ*zZ`|US3H@8N~%&V%Z | |||
|
345 | > zAeA0HdhFS=$6|nzn3%YH`SN<>DQRO;Qc^)dfdvA^5u`Xf;Zzu<ZQHgG?28V-#s<;T | |||
|
346 | > zzkh#LA)v7gpoE5ou3o*GoUUF%b#iht&kl9d0)><$FE1}ACr68;uCA`6DrGmz_U+rp | |||
|
347 | > zL>Rx;X_yhk$fP_yJrTCQ|NgsW0A<985g&c@k-NKly<>mgU8n||ZPPV<`SN8#%$+-T | |||
|
348 | > zfP$T!ou8jypFVwnzqhxyUvIxXd-wF~*U!ht=hCH1wzjqn9x#)IrhDa;S0JbK^z_$W | |||
|
349 | > zd(8rX@;7|t*;GJ5h$SZ{v(}+UBEs$4w~?{@9%`_Z<P<kox5bMWuUWH(sF9hONgd$Q | |||
|
350 | > zunCgwT@1|CU9+;X^4z&|M~@yw23Ay50NFWn=FqF%yLZEUty;AT2??1oV@B)Nt))J7 | |||
|
351 | > zh>{5j2@f7T=-an%L_`E)h;mZ4D_5>?7tjQtVPRo2XU-&;mX(!l-MSTJP4XWY82JAC | |||
|
352 | > z@57+y&!1=P{Mn{W8)-HzEsgAtd63}Cazc>O6vGb>51%@9DzbyI3?4j~$ijmT95_IS | |||
|
353 | > zS#r!LCDW%*4-O7CGnkr$xXR1RQ&UrA<CQt}^73NL%zk`)Jk!yxUAt-1r}ggLn-Zq} | |||
|
354 | > z*s){8pw68;i+kiG%CpBKYSJLLFyq&*U8}qDp+kpe&6<Vp(Z58%l#~>ZK?&s7y?b}i | |||
|
355 | > zuwcOgO%x-27A;y785zknl_{sU;E6v$8{pWmVS{KaJPpu`i;HP$#flY@u~Ua~K3%tN | |||
|
356 | > z-LhrNh{9SoHgDd%WXTc$$~Dq{?AWou3!H&?V8K{^{P9Ot5vecD?%1&-E-ntBFj87( | |||
|
357 | > zy5`QE%QRX7qcHC%1{Ua}M~}L6=`wQUNEQ=I;qc+ZMMXtK2T+0os;jEco;}OV9z1w3 | |||
|
358 | > zARqv^bm-85xnRCng3OT|MyVSmR3ND7^?KaQGG!^(aTbo1N;Nz;X3Q9FJbwK6`0?Yp | |||
|
359 | > zj*X2ac;Pw3!I2|JShDaF>-gJmzm1NLj){rk&o|$E^WAsfrK=x&@B!`w7Hik81sPz4 | |||
|
360 | > zuJTaiCppM>-+c!wPzcUw)5@?J4U-u|pJ~xbWUe-C+60k^7>9!)56DbjmA~`OJJ40v | |||
|
361 | > zu3hCA7eJXZWeN|1iJLu87$;+fS8+Kq6O`aT)*_x@sY#t7LxwoEcVw*)cWhhQW@l%! | |||
|
362 | > z{#Z=y+qcK@%z{p*D=8_Fcg278AnH3fI5;~yGu?9TscxXaaP*4$f<LIv!^5Lfr%vKg | |||
|
363 | > zpxmunH#%=+ICMvZA~wyNH%~eMl!-g^R!cYJ#WmLq5N8viz#J%%LPtkO?V)tZ81cp> | |||
|
364 | > z{ALK?fNPePmd;289&M8Q3>YwgZX5GcGY&n>K1<x)!`;Qjg&}bb!Lrnl@xH#kS~VYE | |||
|
365 | > zpJmIJO`A3iy+Y3X`k>cY-@}Iw2Onq`=!ba3eATgs3yg3Wej=+P-Z8WF#w=RXvS@J3 | |||
|
366 | > zEyhVTj-gO?kfDu1g9afo<RkPrYzG#_yF41IFxF%Ylg>9lx6<clPweR-b7Hn+r)e1l | |||
|
367 | > zO6c6FbNt@;;*w$z;N|H>h{czme)_4V6UC4hv**kX2@L^Bgds$(&P7M4dhfmWe)!=B | |||
|
368 | > zR3X=Y{P9N}p@-##@1ZNW1YbVaiP~D@8m&<dzEP&cO|87Ju#j*=;wH~Exr>i*Hpp&@ | |||
|
369 | > z`9!Sj+O;byD~s8qZ>6QB8uv7Bpn&&?xe;;e<M4F8KEID&pT7QmqoSgq&06adp5T=U | |||
|
370 | > z6DH*4=AB7C1D9Amu?ia-wtxSAlmTEO96XHx)-+rKP;ip$pukuSJGW3P1aUmc2yo%) | |||
|
371 | > z&<t3F>d1X+1qzaag-%x+eKHx{?Afz3GBQSw9u0lw<mB+I#v11TKRpKWQS+lvVL7=u | |||
|
372 | > zHr6)1ynEF<i3kO6A8&ppPMo-F=PnWfXkSj@i*7J6C<F}wR?s(O0niC?t+6;+k}pPq | |||
|
373 | > zrok&TPU40rL0ZYDwenNrrmPZ`gjo@DEF`7^cKP||pUr;+r)hyn9O37=xA`3%Bj-ih | |||
|
374 | > z+1usk<%5G-y+R?tA`qY=)6&vNjL{P?QzHg%P%>`ZxP=QB%DHY6L26?36V_p^{}n$q | |||
|
375 | > z3@9W=KmGI*Ng_Q#AzA%-z|Z^|#oW(hkfgpuS$RKRhlrarX%efMMCs}GLChec5+y{6 | |||
|
376 | > z1Qnxim_C-fmQuaAK_NUHUBV&;1c0V)wji<RcdZ*aAWTwyt>hVnlt^asFCe0&a@tqp | |||
|
377 | > zEEy;$L}D$X6)wfQNl8gu6Z>oB3_RrP=gTyK2@@w#LbQfLNHj>Q&z(C5wUFhK+}0aV | |||
|
378 | > zSohlc=7K+spN<ctf}5KgKqNyJDNP9;LZd)nTE=9|6Xdr9%Hzk63-tL2c9FD*rsyYY | |||
|
379 | > z!}t+Yljq7-p$X;4_YL?6d;mdY3R##o1e%rlPxrsMh8|;sKTr~^QD#sw3&vS$FwlTk | |||
|
380 | > zp1#Gw!Qo-$LtvpXt#ApV0g)^F=qFB`VB!W297x=$mr<$>rco3v$QKih_xN!k6;M=@ | |||
|
381 | > zCr?gDNQj7tm@;JwD;Ty&NlBSCYZk(b3dZeN8D4h2{r20dSFc7;(>E&r`s=TVtzpB4 | |||
|
382 | > zk+^N&zCAiRns(?p6iBlk9v&h{1ve(FNtc)td51M>)TkXhc6{>5C)`fS$&)A1*CP1% | |||
|
383 | > zld+peue4aYbg3C0!+4mu+}vE^j_feX+ZijvffBI7Ofh#RZ*U3<3J5(+nfRCzexqQ5 | |||
|
384 | > zgM&##Y4Dd{e%ZKjqrbm@|Ni}l4jo!AqtFynj3Xsd$o^?yV4$|UQ(j&UWCH>M=o_&N | |||
|
385 | > zmclXc3i|Q#<;#EoG>~V}4unTHbUK}u=y4;rA3S&vzC3^aJP!&D4RvvGfoyo(>C>la | |||
|
386 | > zijP<=v>X{3Ne&2BXo}DV8l0V-jdv`$am0ubG{Wuh%CTd|l9Q7m;G&|U@#Dvbhlj(d | |||
|
387 | > zg6W{3ATxYt#T?)3;SmIgOP4M|Dki~I_TX7SxP0x}wI~DQI7Lhm2BI7gph(aPIFAd; | |||
|
388 | > zQ&UsF`Q{rOz+z=87c5v%@5u~d6dWV5OlX`oH3cAH&UlvsZUEo(Q(P|lKs17rXvaiU | |||
|
389 | > zQcj}IEufi1+Bnh6&(EhF{7O3vLHp`jjlp0J<M1kh$+$2xGm~Zk7OY7(q=&Rdhq*RG | |||
|
390 | > zwrmcd5MnP}xByB_)P@{J>DR9x6;`cUwPM8z){yooNiXPOc9_{W-gtwxE5TUg0vJk6 | |||
|
391 | > zO#JGruV&1cL6VGK2?+_YQr4`+EY8;Sm$9U$uuGRN=uj3k7?O9b+R~J7t_y*K64ZnI | |||
|
392 | > zM+{aE<b(v?vSmw;9zFP!aE266zHIhlmdI@^xa6o2jwdRk54a$>pcRbC29ZyG!Cfdp | |||
|
393 | > zutFf`Q`vljgo!(wHf=)F#m2_MIuj;L(2ja2YsQRX+rswV{d<H`Ar;(@%aNa9VPU8Z | |||
|
394 | > z;tq*`y}dm#NDJHKlV}uTIm!_vAq5E7!X-p{P=Z=Sh668>PuVS1*6e}OwOiMc;u3OQ | |||
|
395 | > z@Bs)w3=lzfKoufH$SFuPG@uZ4NOnM#+=8LnQ2Q4zUd+nM+OT26;lqbN{P07dhH{jH | |||
|
396 | > zManE8^dLms-Q2;1kB<*Q1a3f8kZr;xX=!Qro@`~@xN*Qj>gx;i;0Z24!~i2uLb`}v | |||
|
397 | > zA?R$|wvC+m^Ups=*(4lDh*=UN8{5h(A?p#D^2N$8u4Z55!q?ZAh(iEEng9_Zi>IgO | |||
|
398 | > z#~**JC8hE4@n{hO&8btT5F*?nC_%LhA3i)PDhh-pB_&1wGrDIl^*=8x3n&;akBf^- | |||
|
399 | > zJd&86kq$%%907v^tgWoQdwI`|oNK%VvU~S#C<o^F?6c48?Cjj#-4P<>HFD%&|Ni~t | |||
|
400 | > zKJ(|#H`$<5W+6ZkBb213rXonKZLB+X>^L}J@W6osP3piLD_5?R!`S}*{xLBzFiL4@ | |||
|
401 | > zX+}l{`A%?f@T5tT%ztu60p;)be`fWC`tP@WpO=?cpf8Xuf1OSj6d3f@Ki(ovDYq%0 | |||
|
402 | > z{4ZSe`kOay5@=lAT!}vFzxyemC{sXDrhuYM0Y#ZI1r%ipD9W11{w=@&xgJ}t2x;ep | |||
|
403 | > P00000NkvXXu0mjfZ5|Er | |||
|
404 | > | |||
|
405 | > literal 0 | |||
|
406 | > HcmV?d00001 | |||
|
407 | > | |||
|
408 | > EOF | |||
|
409 | applying patch from stdin | |||
|
410 | ||||
|
411 | $ hg manifest --debug | grep delta | |||
|
412 | 9600f98bb60ce732634d126aaa4ac1ec959c573e 644 delta | |||
|
413 | ||||
|
414 | $ hg import -d "1000000 0" -m delta - <<'EOF' | |||
|
415 | > diff --git a/delta b/delta | |||
|
416 | > index 8c9b7831b231c2600843e303e66b521353a200b3..0021dd95bc0dba53c39ce81377126d43731d68df 100644 | |||
|
417 | > GIT binary patch | |||
|
418 | > delta 49 | |||
|
419 | > zcmZ1~yHs|=21Z8J$r~9bFdA-lVv=EEw4WT$qRf2QSa5SIOAHI6(&k4T8H|kLo4vWB | |||
|
420 | > FSO9ZT4bA`n | |||
|
421 | > | |||
|
422 | > delta 49 | |||
|
423 | > zcmV-10M7rV9i<(xumJ(}ld%Di0Xefm0vrMXpOaq%BLm9I%d>?9Tm%6Vv*HM70RcC& | |||
|
424 | > HOA1;9yU-AD | |||
|
425 | > | |||
|
426 | > EOF | |||
|
427 | applying patch from stdin | |||
|
428 | ||||
|
429 | $ hg manifest --debug | grep delta | |||
|
430 | 56094bbea136dcf8dbd4088f6af469bde1a98b75 644 delta | |||
|
431 | ||||
323 | Filenames with spaces: |
|
432 | Filenames with spaces: | |
324 |
|
433 | |||
325 | $ sed 's,EOL$,,g' <<EOF | hg import -d "1000000 0" -m spaces - |
|
434 | $ sed 's,EOL$,,g' <<EOF | hg import -d "1000000 0" -m spaces - | |
@@ -334,7 +443,7 b' Filenames with spaces:' | |||||
334 | applying patch from stdin |
|
443 | applying patch from stdin | |
335 |
|
444 | |||
336 | $ hg tip -q |
|
445 | $ hg tip -q | |
337 | 12:47500ce1614e |
|
446 | 14:4b79479c9a6d | |
338 |
|
447 | |||
339 | $ cat "foo bar" |
|
448 | $ cat "foo bar" | |
340 | foo |
|
449 | foo | |
@@ -357,7 +466,7 b' Copy then modify the original file:' | |||||
357 | applying patch from stdin |
|
466 | applying patch from stdin | |
358 |
|
467 | |||
359 | $ hg tip -q |
|
468 | $ hg tip -q | |
360 | 13:6757efb07ea9 |
|
469 | 15:9cbe44af4ae9 | |
361 |
|
470 | |||
362 | $ cat foo3 |
|
471 | $ cat foo3 | |
363 | foo |
|
472 | foo | |
@@ -392,8 +501,8 b' Move text file and patch as binary' | |||||
392 | Invalid base85 content |
|
501 | Invalid base85 content | |
393 |
|
502 | |||
394 | $ hg rollback |
|
503 | $ hg rollback | |
395 |
repository tip rolled back to revision 1 |
|
504 | repository tip rolled back to revision 16 (undo import) | |
396 |
working directory now based on revision |
|
505 | working directory now based on revision 16 | |
397 | $ hg revert -aq |
|
506 | $ hg revert -aq | |
398 | $ hg import -d "1000000 0" -m invalid-binary - <<"EOF" |
|
507 | $ hg import -d "1000000 0" -m invalid-binary - <<"EOF" | |
399 | > diff --git a/text2 b/binary2 |
|
508 | > diff --git a/text2 b/binary2 |
General Comments 0
You need to be logged in to leave comments.
Login now