VorDa Posted August 10, 2007 Share Posted August 10, 2007 Can someone help me to decode this source writen in pascal? I'm want to make some phone-pc program, but I need pdu<->txt decoder from this source. expandcollapse popup{ --------------------------------------------------------- } { Purposes : } { 1. Convert ASCII to 7-bit PDU } { 2. Convert 7-bit, 8-bit and 16-bit PDU to ASCII } { 3. Decode/Parsing the hexadecimal (PDU) of SMS message } { 4. Encode ASCII characters to be sent as SMS ready string } { } { --------------------------------------------------------- } { Coder : Daniel Eka Nugraha } { URL : http://www.averagecoder.com/ } { Email : pinoez@yahoo.com } { --------------------------------------------------------- } { This is not a perfect one, so Use it at your own risk ! } { --------------------------------------------------------- } unit SMSCODEC; interface uses Windows, Messages, SysUtils, Classes, StrUtils, Math, Dialogs; type TSMSCODEC = class(TComponent) private { Private declarations } protected { Protected declarations } public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Binerkan(Angka: integer): string; function Bin2Long(StrBiner: string): integer; function PDU7BIT2ASCII(StrPDU: string; PanjangUDH, PanjangData: integer): string; function PDU8BIT2ASCII(StrPDU: string; PanjangUDH, PanjangData: integer): string; function PDU16BIT2ASCII(StrPDU: string; PanjangUDH, PanjangData: integer): string; function ASCII2PDU7BIT(StrASCII: string): string; function DecodeSMS(StrSMS : string) : TStringList; function EncodeSMS(StrTujuan, StrPesan: string): string; published { Published declarations } end; procedure Register; implementation var Nono: integer; EQ7BIT2ASCII : array [0..127] of integer; // Table persamaan 7-bit ke ASCII EQASCII27BIT : array [0..255] of integer; // Table persamaan ASCII ke 7-bit procedure Register; begin RegisterComponents('averagecoder', [TSMSCODEC]); end; constructor TSMSCODEC.Create(AOwner: TComponent); var i : integer; begin inherited Create(AOwner); // This is the transition table from 7-bit to ASCII Nono := -1; EQ7BIT2ASCII[0] := 64; EQ7BIT2ASCII[1] := 163; EQ7BIT2ASCII[2] := 36; EQ7BIT2ASCII[3] := 165; EQ7BIT2ASCII[4] := 232; EQ7BIT2ASCII[5] := 223; EQ7BIT2ASCII[6] := 249; EQ7BIT2ASCII[7] := 236; EQ7BIT2ASCII[8] := 242; EQ7BIT2ASCII[9] := 199; EQ7BIT2ASCII[10] := 10; EQ7BIT2ASCII[11] := 216; EQ7BIT2ASCII[12] := 248; EQ7BIT2ASCII[13] := 13; EQ7BIT2ASCII[14] := 197; EQ7BIT2ASCII[15] := 229; EQ7BIT2ASCII[16] := Nono; EQ7BIT2ASCII[17] := 95; EQ7BIT2ASCII[18] := Nono; EQ7BIT2ASCII[19] := Nono; EQ7BIT2ASCII[20] := Nono; EQ7BIT2ASCII[21] := Nono; EQ7BIT2ASCII[22] := Nono; EQ7BIT2ASCII[23] := Nono; EQ7BIT2ASCII[24] := Nono; EQ7BIT2ASCII[25] := Nono; EQ7BIT2ASCII[26] := Nono; EQ7BIT2ASCII[27] := Nono; EQ7BIT2ASCII[28] := 198; EQ7BIT2ASCII[29] := 230; EQ7BIT2ASCII[30] := 223; EQ7BIT2ASCII[31] := 201; EQ7BIT2ASCII[32] := 32; EQ7BIT2ASCII[33] := 33; EQ7BIT2ASCII[34] := 34; EQ7BIT2ASCII[35] := 35; EQ7BIT2ASCII[36] := 164; EQ7BIT2ASCII[37] := 37; EQ7BIT2ASCII[38] := 38; EQ7BIT2ASCII[39] := 39; EQ7BIT2ASCII[40] := 40; EQ7BIT2ASCII[41] := 41; EQ7BIT2ASCII[42] := 42; EQ7BIT2ASCII[43] := 43; EQ7BIT2ASCII[44] := 44; EQ7BIT2ASCII[45] := 45; EQ7BIT2ASCII[46] := 46; EQ7BIT2ASCII[47] := 47; EQ7BIT2ASCII[48] := 48; EQ7BIT2ASCII[49] := 49; EQ7BIT2ASCII[50] := 50; EQ7BIT2ASCII[51] := 51; EQ7BIT2ASCII[52] := 52; EQ7BIT2ASCII[53] := 53; EQ7BIT2ASCII[54] := 54; EQ7BIT2ASCII[55] := 55; EQ7BIT2ASCII[56] := 56; EQ7BIT2ASCII[57] := 57; EQ7BIT2ASCII[58] := 58; EQ7BIT2ASCII[59] := 59; EQ7BIT2ASCII[60] := 60; EQ7BIT2ASCII[61] := 61; EQ7BIT2ASCII[62] := 62; EQ7BIT2ASCII[63] := 63; EQ7BIT2ASCII[64] := 161; EQ7BIT2ASCII[65] := 65; EQ7BIT2ASCII[66] := 66; EQ7BIT2ASCII[67] := 67; EQ7BIT2ASCII[68] := 68; EQ7BIT2ASCII[69] := 69; EQ7BIT2ASCII[70] := 70; EQ7BIT2ASCII[71] := 71; EQ7BIT2ASCII[72] := 72; EQ7BIT2ASCII[73] := 73; EQ7BIT2ASCII[74] := 74; EQ7BIT2ASCII[75] := 75; EQ7BIT2ASCII[76] := 76; EQ7BIT2ASCII[77] := 77; EQ7BIT2ASCII[78] := 78; EQ7BIT2ASCII[79] := 79; EQ7BIT2ASCII[80] := 80; EQ7BIT2ASCII[81] := 81; EQ7BIT2ASCII[82] := 82; EQ7BIT2ASCII[83] := 83; EQ7BIT2ASCII[84] := 84; EQ7BIT2ASCII[85] := 85; EQ7BIT2ASCII[86] := 86; EQ7BIT2ASCII[87] := 87; EQ7BIT2ASCII[88] := 88; EQ7BIT2ASCII[89] := 89; EQ7BIT2ASCII[90] := 90; EQ7BIT2ASCII[91] := 196; EQ7BIT2ASCII[92] := 204; EQ7BIT2ASCII[93] := 209; EQ7BIT2ASCII[94] := 220; EQ7BIT2ASCII[95] := 167; EQ7BIT2ASCII[96] := 191; EQ7BIT2ASCII[97] := 97; EQ7BIT2ASCII[98] := 98; EQ7BIT2ASCII[99] := 99; EQ7BIT2ASCII[100] := 100; EQ7BIT2ASCII[101] := 101; EQ7BIT2ASCII[102] := 102; EQ7BIT2ASCII[103] := 103; EQ7BIT2ASCII[104] := 104; EQ7BIT2ASCII[105] := 105; EQ7BIT2ASCII[106] := 106; EQ7BIT2ASCII[107] := 107; EQ7BIT2ASCII[108] := 108; EQ7BIT2ASCII[109] := 109; EQ7BIT2ASCII[110] := 110; EQ7BIT2ASCII[111] := 111; EQ7BIT2ASCII[112] := 112; EQ7BIT2ASCII[113] := 113; EQ7BIT2ASCII[114] := 114; EQ7BIT2ASCII[115] := 115; EQ7BIT2ASCII[116] := 116; EQ7BIT2ASCII[117] := 117; EQ7BIT2ASCII[118] := 118; EQ7BIT2ASCII[119] := 119; EQ7BIT2ASCII[120] := 120; EQ7BIT2ASCII[121] := 121; EQ7BIT2ASCII[122] := 122; EQ7BIT2ASCII[123] := 228; EQ7BIT2ASCII[124] := 246; EQ7BIT2ASCII[125] := 241; EQ7BIT2ASCII[126] := 252; EQ7BIT2ASCII[127] := 224; // This is the transition table from ASCII to 7-BIT; index reversing :) for i := 0 to High(EQ7BIT2ASCII) do begin if EQ7BIT2ASCII[i] <> Nono then EQASCII27BIT[EQ7BIT2ASCII[i]] := i; end; end; { TSMSCODEC.Create } destructor TSMSCODEC.Destroy; begin inherited Destroy; end; { TSMSCODEC.Destroy } { -------------------------------------------------------------------------------- function Binerkan -> Convert integer to binary -> parameters: Angka: integer; -> the integer value -> Return value: string of 1 and 0 (nothing genius at all :D) -------------------------------------------------------------------------------- } function TSMSCODEC.Binerkan(Angka : integer): string; var i : Integer; hasil : array [0..7] of Integer; SISA : array [0..7] of Integer; StrHasil : string; begin result := ''; if angka > 1 Then begin i := 1; repeat hasil[i] := Trunc(angka / 2); SISA[i] := angka mod 2; angka := hasil[i]; i := i + 1; StrHasil := IntToStr(SISA[i - 1]) + StrHasil; until hasil[i - 1] < 2; StrHasil := IntToStr(hasil[i - 1]) + StrHasil; end else if angka = 1 then StrHasil := '00000001' else if angka = 0 Then StrHasil := '00000000'; for i := 1 to (8 - Length(StrHasil)) do StrHasil := '0' + StrHasil; result := StrHasil; end; { TSMSCODEC.Binerkan } { -------------------------------------------------------------------------------- function Bin2Long -> Convert binaty string to integer -> Parameter: StrBiner: string; -> the binary string; -> Return value: integer; -------------------------------------------------------------------------------- } function TSMSCODEC.Bin2Long(StrBiner : string): integer; var i, x : integer; begin x := 0; for i := 1 to Length(StrBiner) do begin x := x + StrToInt(Copy(StrBiner, i, 1)) * Trunc(Power(2,(Length(StrBiner) - i))); end; result := x; end; { TSMSCODEC.Bin2Long } { -------------------------------------------------------------------------------- function PDU7BIT2ASCII -> Convert PDU (string 7-bit PDU) to ASCII -> Parameter: StrPDU: string -> the PDUString PanjangUDH: integer; -> the length of the UDH PanjangData: integer; -> the length of the data -> return value: ASCII string -------------------------------------------------------------------------------- } function TSMSCODEC.PDU7BIT2ASCII(StrPDU : string; PanjangUDH, PanjangData: integer) : string; var i,j,x,z : integer; y, StrASCII : string; ArrPDU : array of string; Arr7Bit : array of string; ArrASCII : array of string; begin j := 1; z := 0; // 2 PDU chars represent 1 ASCII chars, so the length of the // ASCII chars sequence is 1/2 of the string PDU length SetLength(ArrPDU,Length(StrPDU) div 2); // Load each pair of PDU string to the appropriate index of ArrPDU while j < Length(StrPDU) do begin ArrPDU[z] := '$' + Copy(StrPDU,j,2); // '$' + string = hexadecimal j := j + 2; Inc(z); end; // Convert each ArrPDU item to binary for decoding for i := 0 to High(ArrPDU) do begin y := ArrPDU[i]; ArrPDU[i] := ''; ArrPDU[i] := Binerkan(StrToInt(y)); end; x := 0; SetLength(Arr7BIT,x+1); // The core process - the bit mutation for i := 0 to High(ArrPDU) do begin if i mod 7 = 0 then begin Arr7BIT[x] := RightStr(ArrPDU[i],7); end else begin if i mod 7 = 6 then begin Arr7BIT[x] := RightStr(ArrPDU[i],1) + LeftStr(ArrPDU[i-1],6); x := x + 1; SetLength(Arr7BIT,x+1); Arr7BIT[x] := LeftStr(ArrPDU[i],7); end else Arr7BIT[x] := RightStr(ArrPDU[i],Length(ArrPDU[i])-(i mod 7)-1) + LeftStr(ArrPDU[i-1],i mod 7); end; x := x + 1; SetLength(Arr7BIT,x+1); end; { for } j := 0; while j <= High(Arr7BIT) do begin SetLength(ArrASCII,Length(ArrASCII)+1); if Bin2Long(Arr7BIT[j]) = 27 then begin inc(j); case Bin2Long(Arr7BIT[j]) of 10 : ArrASCII[High(ArrASCII)] := Chr(12); 20 : ArrASCII[High(ArrASCII)] := Chr(94); 40 : ArrASCII[High(ArrASCII)] := Chr(123); 41 : ArrASCII[High(ArrASCII)] := Chr(125); 47 : ArrASCII[High(ArrASCII)] := Chr(92); 60 : ArrASCII[High(ArrASCII)] := Chr(91); 61 : ArrASCII[High(ArrASCII)] := Chr(126); 62 : ArrASCII[High(ArrASCII)] := Chr(93); 64 : ArrASCII[High(ArrASCII)] := Chr(124); else ArrASCII[High(ArrASCII)] := Chr(0); end; end else begin ArrASCII[High(ArrASCII)] := Chr(EQ7BIT2ASCII[Bin2Long(Arr7BIT[j])]); end; Inc(j); end; { while } SetLength(ArrASCII,PanjangData); for i := 0 to High(ArrASCII) do StrASCII := StrASCII + (ArrASCII[i]); ArrPDU := nil; Arr7Bit := nil; ArrASCII := nil; // if no UDH, ignore the octet info of UDH length, // not part of SMS message. if PanjangUDH > 0 then StrASCII := Copy(StrASCII,PanjangUDH + 3,Length(StrASCII)); Result := StrASCII; end; { TSMSCODEC.PDU7BIT2ASCII } { -------------------------------------------------------------------------------- function PDU8BIT2ASCII -> Convert string 8-bit PDU to ASCII -> parameter: strPDU: string; -> the 8 bit PDU string PanjangUDH: integer; -> length of the UDH PanjangData: integer; -> Length of the data -> return value: string (ASCII) -------------------------------------------------------------------------------- } function TSMSCODEC.PDU8BIT2ASCII(StrPDU : string; PanjangUDH, PanjangData: integer) : string; var StrASCII : string; i, x, PjPDUPesan : integer; begin if PanjangUDH <> 0 then begin x := (PanjangUDH * 2) + 2; // PDU info UDH StrPDU := RightStr(StrPDU,(PanjangData * 2) - x); // PDU Pesan end; PjPDUPesan := Length(StrPDU); i := 1; while i <= PjPDUPesan do begin if i mod 2 = 0 then begin StrASCII := StrASCII + Chr(EQ7BIT2ASCII[StrToInt('$' + LeftStr(StrPDU,2))]); StrPDU := RightStr(StrPDU,Length(StrPDU)-2); end; Inc(i); end; result := StrASCII; end; { TSMSCODEC.PDU8BIT2ASCII } { -------------------------------------------------------------------------------- function PDU16BIT2ASCII -> COnvert StrPDU (string 16-bit PDU) to ASCII -> parameter: strPDU: string; -> the 8 bit PDU string PanjangUDH: integer; -> length of the UDH PanjangData: integer; -> Length of the data -> Return value: string (ASCII) -------------------------------------------------------------------------------- } function TSMSCODEC.PDU16BIT2ASCII(StrPDU : string; PanjangUDH, PanjangData: integer) : string; var StrASCII : string; i, x, PjPDUPesan : integer; begin if PanjangUDH <> 0 then begin x := (PanjangUDH * 2) + 2; StrPDU := RightStr(StrPDU,(PanjangData * 2) - x); end; PjPDUPesan := Length(StrPDU); i := 1; while i <= PjPDUPesan do begin if i mod 4 = 0 then begin StrASCII := StrASCII + Chr(EQ7BIT2ASCII[StrToInt('$' + LeftStr(StrPDU,4))]); StrPDU := RightStr(StrPDU,Length(StrPDU)-4); end; Inc(i); end; result := StrASCII; end; { TSMSCODEC.PDU16BIT2ASCII } { -------------------------------------------------------------------------------- function ASCII2PDU7BIT -> Convert par StrASCII (string ASCII) to 7-bit PDU -> parameter: strASCII: string; -> the ASCII string -> Return value: string (7-bit PDU) -------------------------------------------------------------------------------- } function TSMSCODEC.ASCII2PDU7BIT(StrASCII : string) : string; var i,x,z : integer; ArrPDU : array of string; Arr7Bit : array of string; StrPDU : string; begin for i := 1 to Length(StrASCII) do begin SetLength(Arr7BIT,Length(Arr7BIT)+1); case Ord(StrASCII[i]) of 12 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(10),7); end; 94 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(20),7); end; 123 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(40),7); end; 125 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(41),7); end; 92 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(47),7); end; 91 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(60),7); end; 126 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(61),7); end; 93 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(62),7); end; 124 : begin SetLength(Arr7BIT,Length(Arr7BIT)+1); Arr7BIT[High(Arr7BIT)-1] := RightStr(Binerkan(27),7); Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(64),7); end; else begin Arr7BIT[High(Arr7BIT)] := RightStr(Binerkan(EQASCII27BIT[Ord(StrASCII[i])]),7); end; end; { case } end; { for } i := 1; x := 1; z := 0; SetLength(ArrPDU,z+1); while i <= High(Arr7BIT) do begin if (i > 1) and ((i) mod 8 = 0) then begin x := 1; inc(i); end else begin ArrPDU[z] := RightStr(Arr7BIT[i],x) + Arr7BIT[i-1]; SetLength(Arr7BIT[i],Length(Arr7BIT[i])-x); inc(z); SetLength(ArrPDU,z+1); Inc(x); Inc(i); end; end; ArrPDU[High(ArrPDU)] := Arr7BIT[High(Arr7BIT)]; for i := 0 to High(ArrPDU) do StrPDU := StrPDU + IntToHex(Bin2Long(ArrPDU[i]),2); ArrPDU := nil; Arr7Bit := nil; {if RightStr(StrPDU,2) = '00' then StrPDU := LeftStr(StrPDU,Length(StrPDU)-2);} Result := StrPDU; end; { TSMSCODEC.ASCII2PDU7BIT } { -------------------------------------------------------------------------------- procedure DecodeSMS -> Decode the SMSPDU then parse the element (such as the sender and the message) to be returned. -> Return value: stringlist (length: 2, index 0: sender number, index 1: the message -------------------------------------------------------------------------------- } function TSMSCODEC.DecodeSMS(StrSMS : string) : TStringList; var i, j, x, y, z, PanjangUDH, PanjangData : integer; StrBiner, StrPDU, StrPengirim, s : string; PakeUDH, Alpha : boolean; Elemen : TStringList; zDCS : integer; zDCSBinIdx23 : string; begin Elemen := TStringList.Create; i := 1; PakeUDH := False; Alpha := False; x := StrToInt('$' + Copy(StrSMS,i,2)); i := i + 2; i := i + (x * 2); x := StrToInt('$' + Copy(StrSMS,i,2)); StrBiner := Binerkan(x); if StrBiner[2] = '1' then begin PakeUDH := True; end; i := i + 2; x := StrToInt('$' + Copy(StrSMS,i,2)); y := x; i := i + 2; z := StrToInt('$' + Copy(StrSMS,i,2)); StrBiner := Binerkan(z); if Copy(StrBiner,2,3) = '101' then Alpha := True; i := i + 2; if x mod 2 <> 0 then x := x + 1; s := Copy(StrSMS,i,x); for j := 1 to Length(s) do begin if j mod 2 = 0 then begin StrPengirim := StrPengirim + s[j] + s[j-1]; end; end; if Alpha = True then begin StrPengirim := PDU7BIT2ASCII(s,0,Length(s)); StrPengirim := StringReplace(StrPengirim,'@','',[rfReplaceAll]); end else StrPengirim := Copy(StrPengirim,1,y); Elemen.Add(StrPengirim); i := i + x + 2; // Data Coding Schemes (DCS) z := StrToInt('$' + Copy(StrSMS,i,2)); StrBiner := Binerkan(z); zDCSBinIdx23 := Copy(StrBiner,5,2); zDCS := 0; if zDCSBinIdx23 = '00' then zDCS := 0; // 7-bit if zDCSBinIdx23 = '01' then zDCS := 1; // 8-bit if zDCSBinIdx23 = '10' then zDCS := 2; // UCS2 if zDCSBinIdx23 = '11' then zDCS := 0; // reserved (pake 7-bit) i := i + 2; x := 14; // abaikan SCTS i := i + x; PanjangData := StrToInt('$' + Copy(StrSMS,i,2)); i := i + 2; StrPDU := Copy(StrSMS,i,Length(StrSMS)); if PakeUDH then PanjangUDH := StrToInt('$' + Copy(StrSMS,i,2)) else PanjangUDH := 0; case zDCS of 0 : Elemen.Add(PDU7BIT2ASCII(StrPDU, PanjangUDH, PanjangData)); 1 : Elemen.Add(PDU8BIT2ASCII(StrPDU, PanjangUDH, PanjangData)); 2 : Elemen.Add(PDU16BIT2ASCII(StrPDU, PanjangUDH, PanjangData)); else Elemen.Add(PDU7BIT2ASCII(StrPDU, PanjangUDH, PanjangData)); end; Result := Elemen; end; { TSMSCODEC.DecodeSMS } { -------------------------------------------------------------------------------- procedure EncodeSMS -> Compose an SMS message -> Paramaters: strTujuan = string; -> The destination number strPesan = string; -> Your message to be sent -> Return value: SMS-PDU -------------------------------------------------------------------------------- } function TSMSCODEC.EncodeSMS(StrTujuan, StrPesan: string): string; var zTujuan, zPesan, Gabung: string; i, pjTujuan : integer; begin pjTujuan := Length(StrTujuan); // If length of StrTujuan is odd, add "F" to the end if Length(StrTujuan) mod 2 = 1 then StrTujuan := StrTujuan + 'F'; // The reversing process of destination number (swapped nibble) for i := 1 to Length(StrTujuan) do begin if i mod 2 = 0 then begin zTujuan := zTujuan + StrTujuan[i] + StrTujuan[i-1]; end; end; // We use internasional format here, add 91 in front of the destination number zTujuan := IntToHex(pjTujuan,2) + '91' + zTujuan; if Length(StrPesan) > 0 then zPesan := ASCII2PDU7BIT(StrPesan); // We use 7Bit encoding here // Add the hexadecimal reperesentation of the PDU length (1/2 of the number of chars) in front of the PDU zPesan := IntToHex(Length(StrPesan),2) + zPesan; // We use the SMSC number in the cellphone/gsmmodem, no status report, no UDH Gabung := '000100' + zTujuan + '0000' + zPesan; result := Gabung; end; { TSMSCODEC.EncodeSMS } end. Anyone to try? Link to comment Share on other sites More sharing options...
Generator Posted August 10, 2007 Share Posted August 10, 2007 I think nobody is going to do it because the length of this code, i suggest you find some other way around this. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now