summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/MirandaNGHistoryToDB/About.dfm208
-rw-r--r--plugins/MirandaNGHistoryToDB/About.pas146
-rw-r--r--plugins/MirandaNGHistoryToDB/Contacts.pas211
-rw-r--r--plugins/MirandaNGHistoryToDB/Database.pas421
-rw-r--r--plugins/MirandaNGHistoryToDB/FSMonitor.pas222
-rw-r--r--plugins/MirandaNGHistoryToDB/Global.inc2
-rw-r--r--plugins/MirandaNGHistoryToDB/Global.pas1250
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas1583
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr32
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj197
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest21
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes163
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otaresbin0 -> 96 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.resbin0 -> 146856 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.icobin0 -> 144763 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm530
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas1497
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas210
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc1430
-rw-r--r--plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt38
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr15
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj109
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.resbin0 -> 5280 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm125
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas176
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcrbin0 -> 1728 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk38
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj168
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.resbin0 -> 5560 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.icobin0 -> 4286 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas612
-rw-r--r--plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas456
-rw-r--r--plugins/MirandaNGHistoryToDB/MapStream.pas185
-rw-r--r--plugins/MirandaNGHistoryToDB/Menu.pas326
-rw-r--r--plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr935
-rw-r--r--plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj226
-rw-r--r--plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes163
-rw-r--r--plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.resbin0 -> 1100 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/MsgExport.dfm4447
-rw-r--r--plugins/MirandaNGHistoryToDB/MsgExport.pas452
-rw-r--r--plugins/MirandaNGHistoryToDB/copy_langs.bat14
-rw-r--r--plugins/MirandaNGHistoryToDB/icons.resbin0 -> 321592 bytes
-rw-r--r--plugins/MirandaNGHistoryToDB/jedi.inc1430
-rw-r--r--plugins/MirandaNGHistoryToDB/langs/English.xml505
-rw-r--r--plugins/MirandaNGHistoryToDB/langs/Russian.xml506
-rw-r--r--plugins/MirandaNGHistoryToDB/m_historytodb.inc40
46 files changed, 19089 insertions, 0 deletions
diff --git a/plugins/MirandaNGHistoryToDB/About.dfm b/plugins/MirandaNGHistoryToDB/About.dfm
new file mode 100644
index 0000000000..9aeea290e8
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/About.dfm
@@ -0,0 +1,208 @@
+object AboutForm: TAboutForm
+ Left = 200
+ Top = 108
+ BorderIcons = [biMinimize, biMaximize]
+ BorderStyle = bsSingle
+ Caption = 'About'
+ ClientHeight = 263
+ ClientWidth = 346
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ Icon.Data = {
+ 0000010001001010000001000000680400001600000028000000100000002000
+ 0000010020000000000000040000000000000000000000000000000000000000
+ 0000000000000000000000000000FF1F2A000000000000000000000000000000
+ 00000000000000000000FF1F2A00000000000000000000000000000000000000
+ 00000000000000000000FF1F2A00FEEFA900FF1F2A00CDCDCD00CDCDCD00CDCD
+ CD00CDCDCD00FF1F2A00FEEFA900FF1F2A000000000000000000000000000000
+ 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F
+ 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000
+ 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FECF4D00FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A0000000000FF1F
+ 2A00FEEFA900FFE55F00FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A000000
+ 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A00000000000000
+ 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F
+ 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000
+ 000000000000C1BDB600FF1F2A00FEEFA900FF1F2A00C1B7AF00D2BEB900D2BE
+ B900D2BEB900FF1F2A00FEEFA900FF1F2A00C1BDB60000000000000000000000
+ 000000000000BAB7AF00A39A8F00FF1F2A00CAC1B800DFD5CC00FAE2DF00F7DB
+ D900DFD5CC00CAC1B800FF1F2A00A39A8F00BAB7AF0000000000000000000000
+ 000000000000B1AB9F00C9C2B900CFC7BF00D5CCC400DCD3CA00E8DDD500E4D6
+ CF00E4D6CF00D5CCC400CFC7BF00C9C2B900B1AB9F0000000000000000000000
+ 000000000000B0AB9E00C7C0B600CCC4BB00D3C9C100DAD0C700EBE1DA00E4D9
+ D100DDD2CA00DBCDC500DDCAC400DBC4BF00C1ADA40000000000000000000000
+ 000000000000AFAA9D00C8C1B700E8E3DB00F5F0E800FDF8F200FBF7F000FCF7
+ F100FDF8F200F7F0EA00ECE3DC00CDC3BB00B2AA9E0000000000000000000000
+ 000000000000AEA89C00FBF5EF00EEE7DE00E0D8CE00DDD5CC00DDD4CB00DDD4
+ CB00DDD5CC00E0D7CE00EDE6DE00FBF6EF00AEA89C0000000000000000000000
+ 000000000000AFA99D00E1D8CE00E1D7CE00DFD6CC00DFD5CB00DFD5CB00DFD5
+ CB00DFD5CB00DFD6CC00E1D7CE00E1D8CE00AFA99D0000000000000000000000
+ 000000000000D9D9D900B6B0A400D6CFC400E6DED500EFE7DD00EEE6DC00EEE6
+ DC00EFE7DD00E6DED500D6CFC400B6B0A400D9D9D90000000000000000000000
+ 00000000000000000000D9D9D900C4C0B700AEA99C00AEA89C00AEA89C00AEA8
+ 9C00AEA89C00AEA99C00C4C0B700D9D9D900000000000000000000000000F7EF
+ FFFFE007FFFFC003FFFF8001FFFF0000FFFF8001FFFFC003FFFFC003FFFFC003
+ FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFE007FFFF}
+ OldCreateOrder = False
+ Position = poScreenCenter
+ OnClose = FormClose
+ OnCreate = FormCreate
+ OnShow = FormShow
+ PixelsPerInch = 96
+ TextHeight = 13
+ object AboutImage: TImage
+ Left = 8
+ Top = 2
+ Width = 328
+ Height = 55
+ Transparent = True
+ end
+ object CloseButton: TButton
+ Left = 270
+ Top = 233
+ Width = 70
+ Height = 25
+ Caption = 'Close'
+ TabOrder = 0
+ OnClick = CloseButtonClick
+ end
+ object AboutPageControl: TPageControl
+ Left = 8
+ Top = 63
+ Width = 332
+ Height = 168
+ ActivePage = VersionTabSheet
+ TabOrder = 1
+ object VersionTabSheet: TTabSheet
+ Caption = #1054' '#1087#1088#1086#1075#1088#1072#1084#1084#1077
+ DesignSize = (
+ 324
+ 140)
+ object BAbout: TBevel
+ Left = 3
+ Top = 7
+ Width = 318
+ Height = 130
+ Anchors = [akLeft, akTop, akRight, akBottom]
+ ExplicitWidth = 363
+ ExplicitHeight = 187
+ end
+ object LProgramName: TLabel
+ Left = 16
+ Top = 16
+ Width = 72
+ Height = 13
+ Caption = 'HistoryToDB'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = [fsBold]
+ ParentFont = False
+ end
+ object LCopyright: TLabel
+ Left = 16
+ Top = 32
+ Width = 124
+ Height = 13
+ Caption = 'Copyright '#169' 2011-2013 by'
+ end
+ object LabelAuthor: TLabel
+ Left = 143
+ Top = 32
+ Width = 80
+ Height = 13
+ Cursor = crHandPoint
+ Caption = 'Michael Grigorev'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clBlue
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ OnClick = LabelAuthorClick
+ end
+ object LVersionNum: TLabel
+ Left = 56
+ Top = 48
+ Width = 33
+ Height = 13
+ Caption = '1.0.0.0'
+ end
+ object LVersion: TLabel
+ Left = 16
+ Top = 48
+ Width = 41
+ Height = 13
+ Caption = 'Version: '
+ end
+ object LLicense: TLabel
+ Left = 16
+ Top = 64
+ Width = 43
+ Height = 13
+ Caption = 'License: '
+ end
+ object LLicenseType: TLabel
+ Left = 59
+ Top = 64
+ Width = 33
+ Height = 13
+ Caption = 'GPLv3'
+ end
+ object LWeb: TLabel
+ Left = 16
+ Top = 80
+ Width = 29
+ Height = 13
+ Caption = 'Web: '
+ end
+ object LabelWebSite: TLabel
+ Left = 46
+ Top = 80
+ Width = 82
+ Height = 13
+ Cursor = crHandPoint
+ Caption = 'www.im-history.ru'
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clBlue
+ Font.Height = -11
+ Font.Name = 'MS Sans Serif'
+ Font.Style = []
+ ParentFont = False
+ OnClick = LabelWebSiteClick
+ end
+ end
+ object ThankYouTabSheet: TTabSheet
+ Caption = #1041#1083#1072#1075#1086#1076#1072#1088#1085#1086#1089#1090#1080
+ ImageIndex = 1
+ DesignSize = (
+ 324
+ 140)
+ object BThankYou: TBevel
+ Left = 3
+ Top = 3
+ Width = 318
+ Height = 134
+ Anchors = [akLeft, akTop, akRight, akBottom]
+ ExplicitWidth = 311
+ ExplicitHeight = 115
+ end
+ object ThankYou: TLabel
+ Left = 11
+ Top = 11
+ Width = 305
+ Height = 118
+ AutoSize = False
+ Caption = #1057#1087#1072#1089#1080#1073#1086' '#1074#1089#1077#1084'!'
+ WordWrap = True
+ end
+ end
+ end
+end
diff --git a/plugins/MirandaNGHistoryToDB/About.pas b/plugins/MirandaNGHistoryToDB/About.pas
new file mode 100644
index 0000000000..7d175adb84
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/About.pas
@@ -0,0 +1,146 @@
+{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+unit About;
+
+interface
+
+uses Windows, Messages, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
+ Buttons, ExtCtrls, ShellAPI, Global, ComCtrls;
+
+type
+ TAboutForm = class(TForm)
+ AboutImage: TImage;
+ CloseButton: TButton;
+ AboutPageControl: TPageControl;
+ VersionTabSheet: TTabSheet;
+ ThankYouTabSheet: TTabSheet;
+ BAbout: TBevel;
+ LProgramName: TLabel;
+ LCopyright: TLabel;
+ LabelAuthor: TLabel;
+ LVersionNum: TLabel;
+ LVersion: TLabel;
+ LLicense: TLabel;
+ LLicenseType: TLabel;
+ LWeb: TLabel;
+ LabelWebSite: TLabel;
+ BThankYou: TBevel;
+ ThankYou: TLabel;
+ procedure FormCreate(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure CloseButtonClick(Sender: TObject);
+ procedure LabelAuthorClick(Sender: TObject);
+ procedure LabelWebSiteClick(Sender: TObject);
+ procedure MemoThankYouEnter(Sender: TObject);
+ private
+ { Private declarations }
+ //
+ procedure OnLanguageChanged(var Msg: TMessage); message WM_LANGUAGECHANGED;
+ procedure LoadLanguageStrings;
+ public
+ { Public declarations }
+ end;
+
+var
+ AboutForm: TAboutForm;
+
+implementation
+
+{$R *.dfm}
+{$R icons.res}
+
+procedure TAboutForm.CloseButtonClick(Sender: TObject);
+begin
+ Close;
+end;
+
+procedure TAboutForm.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+ // -
+ Global_AboutForm_Showing := False;
+end;
+
+procedure TAboutForm.FormCreate(Sender: TObject);
+var
+ AboutBitmap: TBitmap;
+begin
+ //
+ AboutFormHandle := Handle;
+ SetWindowLong(Handle, GWL_HWNDPARENT, 0);
+ SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
+ //
+ AboutBitmap := TBitmap.Create;
+ try
+ AboutBitmap.LoadFromResourceName(HInstance, 'About');
+ AboutImage.Picture.Assign(AboutBitmap);
+ finally
+ AboutBitmap.Free;
+ end;
+ LabelAuthor.Cursor := crHandPoint;
+ LabelWebSite.Cursor := crHandPoint;
+ //
+ LoadLanguageStrings;
+end;
+
+procedure TAboutForm.FormShow(Sender: TObject);
+begin
+ // -
+ Global_AboutForm_Showing := True;
+ // " "
+ LVersionNum.Caption := IntToStr(htdVerMajor) + '.' + IntToStr(htdVerMinor) + '.' + IntToStr(htdVerRelease) + '.' + IntToStr(htdVerBuild) + ' ' + htdPlatform;
+end;
+
+procedure TAboutForm.LabelAuthorClick(Sender: TObject);
+begin
+ ShellExecute(0, 'open', 'mailto:sleuthhound@gmail.com', nil, nil, SW_RESTORE);
+end;
+
+procedure TAboutForm.LabelWebSiteClick(Sender: TObject);
+begin
+ ShellExecute(0, 'open', 'http://www.im-history.ru', nil, nil, SW_RESTORE);
+end;
+
+// - Memo :-D
+procedure TAboutForm.MemoThankYouEnter(Sender: TObject);
+begin
+ CloseButton.SetFocus;
+end;
+
+//
+procedure TAboutForm.OnLanguageChanged(var Msg: TMessage);
+begin
+ LoadLanguageStrings;
+end;
+
+//
+procedure TAboutForm.LoadLanguageStrings;
+begin
+ Caption := GetLangStr('AboutFormCaption');
+ LProgramName.Caption := htdPluginShortName;
+ CloseButton.Caption := GetLangStr('CloseButton');
+ LVersion.Caption := GetLangStr('Version');
+ LLicense.Caption := GetLangStr('License');
+ VersionTabSheet.Caption := GetLangStr('AboutFormCaption');
+ ThankYouTabSheet.Caption := GetLangStr('LThankYou');
+ //
+ LVersionNum.Left := LVersion.Left + 1 + LVersion.Width;
+ LLicenseType.Left := LLicense.Left + 1 + LLicense.Width;
+ //
+ if CoreLanguage = 'Russian' then
+ ThankYou.Caption := ThankYouText_Rus
+ else
+ ThankYou.Caption := ThankYouText_Eng;
+ // End
+end;
+
+end.
+
diff --git a/plugins/MirandaNGHistoryToDB/Contacts.pas b/plugins/MirandaNGHistoryToDB/Contacts.pas
new file mode 100644
index 0000000000..8d95b5f3bc
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/Contacts.pas
@@ -0,0 +1,211 @@
+{ ################################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ################################################################################ }
+
+{ ################################################################################ }
+{ # # }
+{ # History++ plugin for Miranda IM: the free IM client for Microsoft* Windows* # }
+{ # # }
+{ # Copyright (C) 2006-2009 theMIROn, 2003-2006 Art Fedorov. # }
+{ # History+ parts (C) 2001 Christian Kastner # }
+{ # # }
+{ # This program is free software; you can redistribute it and/or modify # }
+{ # it under the terms of the GNU General Public License as published by # }
+{ # the Free Software Foundation; either version 2 of the License, or # }
+{ # (at your option) any later version. # }
+{ # # }
+{ # This program is distributed in the hope that it will be useful, # }
+{ # but WITHOUT ANY WARRANTY; without even the implied warranty of # }
+{ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # }
+{ # GNU General Public License for more details. # }
+{ # # }
+{ # You should have received a copy of the GNU General Public License # }
+{ # along with this program; if not, write to the Free Software # }
+{ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # }
+{ # # }
+{ ################################################################################ }
+
+unit Contacts;
+
+interface
+
+uses
+ Windows, SysUtils, Forms, Classes, Global;
+
+function GetContactDisplayName(hContact: THandle; Proto: AnsiString = ''; Contact: Boolean = False): String;
+function GetContactProto(hContact: THandle): AnsiString; overload;
+function GetContactProto(hContact: THandle; var SubContact: THandle; var SubProtocol: AnsiString): AnsiString; overload;
+function GetContactID(hContact: THandle; Proto: AnsiString = ''; Contact: boolean = false): AnsiString;
+function TranslateAnsiW(const S: AnsiString): WideString;
+function GetMyContactDisplayName(Proto: AnsiString): String;
+function GetMyContactID(Proto: AnsiString): String;
+
+implementation
+
+uses m_api;
+
+function GetContactProto(hContact: THandle): AnsiString;
+begin
+ Result := PAnsiChar(CallService(MS_PROTO_GETCONTACTBASEPROTO, hContact, 0));
+end;
+
+function GetContactProto(hContact: THandle; var SubContact: THandle; var SubProtocol: AnsiString): AnsiString;
+begin
+ Result := PAnsiChar(CallService(MS_PROTO_GETCONTACTBASEPROTO, hContact, 0));
+ if MetaContactsEnabled and (Result = MetaContactsProto) then
+ begin
+ SubContact := CallService(MS_MC_GETMOSTONLINECONTACT, hContact, 0);
+ SubProtocol := PAnsiChar(CallService(MS_PROTO_GETCONTACTBASEPROTO, SubContact, 0));
+ end
+ else
+ begin
+ SubContact := hContact;
+ SubProtocol := Result;
+ end;
+end;
+
+function GetContactDisplayName(hContact: THandle; Proto: AnsiString = ''; Contact: Boolean = False): String;
+var
+ ci: TContactInfo;
+ RetPWideChar, UW: PChar;
+begin
+ if (hContact = 0) and Contact then
+ Result := TranslateW('Server')
+ else
+ begin
+ if Proto = '' then
+ Proto := GetContactProto(hContact);
+ if Proto = '' then
+ Result := TranslateW('Unknown Contact')
+ else
+ begin
+ ci.cbSize := SizeOf(ci);
+ ci.hContact := hContact;
+ ci.szProto := PAnsiChar(Proto);
+ ci.dwFlag := CNF_DISPLAY + CNF_UNICODE;
+ if CallService(MS_CONTACT_GETCONTACTINFO, 0, LPARAM(@ci)) = 0 then
+ begin
+ RetPWideChar := ci.retval.szVal.w;
+ UW := TranslateW('Unknown Contact');
+ if WideCompareText(RetPWideChar, UW) = 0 then
+ Result := AnsiToWideString(GetContactID(hContact, Proto), CP_ACP)
+ else
+ Result := RetPWideChar;
+ end
+ else
+ Result := String(GetContactID(hContact, Proto));
+ if Result = '' then
+ Result := TranslateAnsiW(Proto);
+ end;
+ end;
+end;
+
+function GetContactID(hContact: THandle; Proto: AnsiString = ''; Contact: Boolean = False): AnsiString;
+var
+ uid: PAnsiChar;
+ dbv: TDBVARIANT;
+ cgs: TDBCONTACTGETSETTING;
+ tmp: String;
+begin
+ Result := '';
+ if not((hContact = 0) and Contact) then
+ begin
+ if Proto = '' then
+ Proto := GetContactProto(hContact);
+ uid := PAnsiChar(CallProtoService(PAnsiChar(Proto), PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0));
+ if (Cardinal(uid) <> CALLSERVICE_NOTFOUND) and (uid <> nil) then
+ begin
+ cgs.szModule := PAnsiChar(Proto);
+ cgs.szSetting := uid;
+ cgs.pValue := @dbv;
+ try
+ if CallService(MS_DB_CONTACT_GETSETTING, hContact, LPARAM(@cgs)) = 0 then
+ begin
+ case dbv._type of
+ DBVT_BYTE:
+ Result := AnsiString(intToStr(dbv.bVal));
+ DBVT_WORD:
+ Result := AnsiString(intToStr(dbv.wVal));
+ DBVT_DWORD:
+ Result := AnsiString(intToStr(dbv.dVal));
+ DBVT_ASCIIZ:
+ Result := AnsiString(dbv.szVal.a);
+ DBVT_UTF8:
+ begin
+ tmp := AnsiToWideString(dbv.szVal.a, CP_UTF8);
+ Result := WideToAnsiString(tmp, hppCodepage);
+ end;
+ DBVT_WCHAR:
+ Result := WideToAnsiString(dbv.szVal.w, hppCodepage);
+ end;
+ DBFreeVariant(@dbv);
+ end;
+ except
+ end;
+ end;
+ end;
+end;
+
+function TranslateAnsiW(const S: AnsiString): WideString;
+begin
+ Result := AnsiToWideString(Translate(PAnsiChar(S)),hppCodepage);
+end;
+
+function GetMyContactDisplayName(Proto: AnsiString): String;
+var
+ ci: TContactInfo;
+ RetPWideChar, UW: PChar;
+begin
+ ci.cbSize := SizeOf(ci);
+ ci.hContact := 0;
+ ci.szProto := PAnsiChar(Proto);
+ ci.dwFlag := CNF_DISPLAY + CNF_UNICODE;
+ if CallService(MS_CONTACT_GETCONTACTINFO, 0, LPARAM(@ci)) = 0 then
+ begin
+ RetPWideChar := ci.retval.szVal.w;
+ UW := TranslateW('Unknown Contact');
+ if WideCompareText(RetPWideChar, UW) = 0 then
+ Result := TranslateW('Unknown Contact')
+ else
+ Result := RetPWideChar;
+ end
+ else
+ Result := TranslateW('Unknown Contact');
+end;
+
+function GetMyContactID(Proto: AnsiString): String;
+var
+ ci: TContactInfo;
+ RetPWideChar, UW: PChar;
+ TmpContactID: AnsiString;
+begin
+ ci.cbSize := SizeOf(ci);
+ ci.hContact := 0;
+ ci.szProto := PAnsiChar(Proto);
+ ci.dwFlag := CNF_DISPLAY + CNF_UNICODE;
+ if CallService(MS_CONTACT_GETCONTACTINFO, 0, LPARAM(@ci)) = 0 then
+ begin
+ RetPWideChar := ci.retval.szVal.w;
+ UW := TranslateW('Unknown Contact');
+ if WideCompareText(RetPWideChar, UW) = 0 then
+ Result := TranslateW('Unknown Contact')
+ else
+ begin
+ TmpContactID := GetContactID(ci.hContact, Proto);
+ if TmpContactID <> '' then
+ Result := TmpContactID
+ else
+ Result := TranslateW('Unknown Contact');
+ end;
+ end
+ else
+ Result := TranslateW('Unknown Contact');
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/Database.pas b/plugins/MirandaNGHistoryToDB/Database.pas
new file mode 100644
index 0000000000..ba58a7295a
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/Database.pas
@@ -0,0 +1,421 @@
+{ ################################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ################################################################################ }
+
+{ ################################################################################ }
+{ # # }
+{ # History++ plugin for Miranda IM: the free IM client for Microsoft* Windows* # }
+{ # # }
+{ # Copyright (C) 2006-2009 theMIROn, 2003-2006 Art Fedorov. # }
+{ # History+ parts (C) 2001 Christian Kastner # }
+{ # # }
+{ # This program is free software; you can redistribute it and/or modify # }
+{ # it under the terms of the GNU General Public License as published by # }
+{ # the Free Software Foundation; either version 2 of the License, or # }
+{ # (at your option) any later version. # }
+{ # # }
+{ # This program is distributed in the hope that it will be useful, # }
+{ # but WITHOUT ANY WARRANTY; without even the implied warranty of # }
+{ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # }
+{ # GNU General Public License for more details. # }
+{ # # }
+{ # You should have received a copy of the GNU General Public License # }
+{ # along with this program; if not, write to the Free Software # }
+{ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # }
+{ # # }
+{ ################################################################################ }
+
+unit Database;
+
+interface
+
+uses m_api, windows, global;
+
+procedure SetSafetyMode(Safe: Boolean);
+
+function DBGetContactSettingString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PAnsiChar): AnsiString;
+function DBGetContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PWideChar): WideString;
+function DBWriteContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; const val: PWideChar): Integer;
+
+function DBDelete(const Module, Param: AnsiString): Boolean; overload;
+function DBDelete(const hContact: THandle; const Module, Param: AnsiString): Boolean; overload;
+function DBExists(const Module, Param: AnsiString): Boolean; overload;
+function DBExists(const hContact: THandle; const Module, Param: AnsiString): Boolean; overload;
+
+function GetDBBlob(const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean; overload;
+function GetDBBlob(const hContact: THandle; const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean; overload;
+function GetDBStr(const Module,Param: AnsiString; Default: AnsiString): AnsiString; overload;
+function GetDBStr(const hContact: THandle; const Module,Param: AnsiString; Default: AnsiString): AnsiString; overload;
+function GetDBWideStr(const Module,Param: AnsiString; Default: WideString): WideString; overload;
+function GetDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Default: WideString): WideString; overload;
+function GetDBInt(const Module,Param: AnsiString; Default: Integer): Integer; overload;
+function GetDBInt(const hContact: THandle; const Module,Param: AnsiString; Default: Integer): Integer; overload;
+function GetDBWord(const Module,Param: AnsiString; Default: Word): Word; overload;
+function GetDBWord(const hContact: THandle; const Module,Param: AnsiString; Default: Word): Word; overload;
+function GetDBDWord(const Module,Param: AnsiString; Default: DWord): DWord; overload;
+function GetDBDWord(const hContact: THandle; const Module,Param: AnsiString; Default: DWord): DWord; overload;
+function GetDBByte(const Module,Param: AnsiString; Default: Byte): Byte; overload;
+function GetDBByte(const hContact: THandle; const Module,Param: AnsiString; Default: Byte): Byte; overload;
+function GetDBBool(const Module,Param: AnsiString; Default: Boolean): Boolean; overload;
+function GetDBBool(const hContact: THandle; const Module,Param: AnsiString; Default: Boolean): Boolean; overload;
+function GetDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload;
+function GetDBDateTime(const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload;
+
+function WriteDBBlob(const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer; overload;
+function WriteDBBlob(const hContact: THandle; const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer; overload;
+function WriteDBByte(const Module,Param: AnsiString; Value: Byte): Integer; overload;
+function WriteDBByte(const hContact: THandle; const Module,Param: AnsiString; Value: Byte): Integer; overload;
+function WriteDBWord(const Module,Param: AnsiString; Value: Word): Integer; overload;
+function WriteDBWord(const hContact: THandle; const Module,Param: AnsiString; Value: Word): Integer; overload;
+function WriteDBDWord(const Module,Param: AnsiString; Value: DWord): Integer; overload;
+function WriteDBDWord(const hContact: THandle; const Module,Param: AnsiString; Value: DWord): Integer; overload;
+function WriteDBInt(const Module,Param: AnsiString; Value: Integer): Integer; overload;
+function WriteDBInt(const hContact: THandle; const Module,Param: AnsiString; Value: Integer): Integer; overload;
+function WriteDBStr(const Module,Param: AnsiString; Value: AnsiString): Integer; overload;
+function WriteDBStr(const hContact: THandle; const Module,Param: AnsiString; Value: AnsiString): Integer; overload;
+function WriteDBWideStr(const Module,Param: AnsiString; Value: WideString): Integer; overload;
+function WriteDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Value: WideString): Integer; overload;
+function WriteDBBool(const Module,Param: AnsiString; Value: Boolean): Integer; overload;
+function WriteDBBool(const hContact: THandle; const Module,Param: AnsiString; Value: Boolean): Integer; overload;
+function WriteDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Value: TDateTime): Integer; overload;
+function WriteDBDateTime(const Module,Param: AnsiString; Value: TDateTime): Integer; overload;
+
+implementation
+
+procedure SetSafetyMode(Safe: Boolean);
+begin
+ CallService(MS_DB_SETSAFETYMODE,WPARAM(Safe),0);
+end;
+
+function DBExists(const Module, Param: AnsiString): Boolean;
+begin
+ Result := DBExists(0,Module,Param);
+end;
+
+function DBExists(const hContact: THandle; const Module, Param: AnsiString): Boolean;
+var
+ dbv: TDBVARIANT;
+ cgs: TDBCONTACTGETSETTING;
+begin
+ cgs.szModule := PAnsiChar(Module);
+ cgs.szSetting := PAnsiChar(Param);
+ cgs.pValue := @dbv;
+ Result := (CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) = 0);
+ if Result then
+ DBFreeVariant(@dbv);
+end;
+
+function GetDBBlob(const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean;
+begin
+ Result := GetDBBlob(0,Module,Param,Value,Size);
+end;
+
+function GetDBBlob(const hContact: THandle; const Module,Param: AnsiString; var Value: Pointer; var Size: Integer): Boolean;
+var
+ cgs: TDBContactGetSetting;
+ dbv: TDBVARIANT;
+begin
+ Result := False;
+ ZeroMemory(@cgs,SizeOf(cgs));
+ cgs.szModule := PAnsiChar(Module);
+ cgs.szSetting := PAnsiChar(Param);
+ cgs.pValue := @dbv;
+ if CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then exit;
+ Size := dbv.cpbVal;
+ Value := nil;
+ if dbv.cpbVal = 0 then exit;
+ GetMem(Value,dbv.cpbVal);
+ Move(dbv.pbVal^,PByte(Value)^,dbv.cpbVal);
+ DBFreeVariant(@dbv);
+ Result := True;
+end;
+
+function GetDBBool(const Module,Param: AnsiString; Default: Boolean): Boolean;
+begin
+ Result := GetDBBool(0,Module,Param,Default);
+end;
+
+function GetDBBool(const hContact: THandle; const Module,Param: AnsiString; Default: Boolean): Boolean;
+begin
+ Result := Boolean(GetDBByte(hContact,Module,Param,Byte(Default)));
+end;
+
+function GetDBByte(const Module,Param: AnsiString; Default: Byte): Byte;
+begin
+ Result := GetDBByte(0,Module,Param,Default);
+end;
+
+function GetDBByte(const hContact: THandle; const Module,Param: AnsiString; Default: Byte): Byte;
+begin
+ Result := DBGetContactSettingByte(hContact,PAnsiChar(Module),PAnsiChar(Param),Default);
+end;
+
+function GetDBWord(const Module,Param: AnsiString; Default: Word): Word;
+begin
+ Result := GetDBWord(0,Module,Param,Default);
+end;
+
+function GetDBWord(const hContact: THandle; const Module,Param: AnsiString; Default: Word): Word;
+begin
+ Result := DBGetContactSettingWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Default);
+end;
+
+function GetDBDWord(const Module,Param: AnsiString; Default: DWord): DWord;
+begin
+ Result := GetDBDWord(0,Module,Param,Default);
+end;
+
+function GetDBDWord(const hContact: THandle; const Module,Param: AnsiString; Default: DWord): DWord;
+begin
+ Result := DBGetContactSettingDWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Default);
+end;
+
+function GetDBInt(const Module,Param: AnsiString; Default: Integer): Integer;
+begin
+ Result := GetDBInt(0,Module,Param,Default);
+end;
+
+function GetDBInt(const hContact: THandle; const Module,Param: AnsiString; Default: Integer): Integer;
+var
+ cws:TDBCONTACTGETSETTING;
+ dbv:TDBVariant;
+begin
+ dbv._type := DBVT_DWORD;
+ dbv.dVal:=Default;
+ cws.szModule:=PAnsiChar(Module);
+ cws.szSetting:=PAnsiChar(Param);
+ cws.pValue:=@dbv;
+ if CallService(MS_DB_CONTACT_GETSETTING,hContact,LPARAM(@cws))<>0 then
+ Result:=default
+ else
+ Result:=dbv.dval;
+end;
+
+function GetDBStr(const Module,Param: AnsiString; Default: AnsiString): AnsiString;
+begin
+ Result := GetDBStr(0,Module,Param,Default);
+end;
+
+function GetDBStr(const hContact: THandle; const Module,Param: AnsiString; Default: AnsiString): AnsiString;
+begin
+ Result := DBGetContactSettingString(hContact,PAnsiChar(Module),PAnsiChar(Param),PAnsiChar(Default));
+end;
+
+function DBGetContactSettingString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PAnsiChar): AnsiString;
+var
+ dbv: TDBVARIANT;
+ cgs: TDBCONTACTGETSETTING;
+ tmp: WideString;
+begin
+ cgs.szModule := szModule;
+ cgs.szSetting := szSetting;
+ cgs.pValue := @dbv;
+ if CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then
+ Result := ErrorValue
+ else begin
+ case dbv._type of
+ DBVT_ASCIIZ:
+ Result := AnsiString(dbv.szVal.a);
+ DBVT_UTF8: begin
+ tmp := AnsiToWideString(dbv.szVal.a,CP_UTF8);
+ Result := WideToAnsiString(tmp,hppCodepage);
+ end;
+ DBVT_WCHAR:
+ Result := WideToAnsiString(dbv.szVal.w,hppCodepage);
+ end;
+ // free variant
+ DBFreeVariant(@dbv);
+ end;
+end;
+
+function GetDBWideStr(const Module,Param: AnsiString; Default: WideString): WideString;
+begin
+ Result := GetDBWideStr(0,Module,Param,Default);
+end;
+
+function GetDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Default: WideString): WideString;
+begin
+ Result := DBGetContactSettingWideString(hContact,PAnsiChar(Module),PAnsiChar(Param),PWideChar(Default));
+end;
+
+function DBGetContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; ErrorValue: PWideChar): WideString;
+var
+ dbv: TDBVARIANT;
+ cgs: TDBCONTACTGETSETTING;
+begin
+ cgs.szModule := szModule;
+ cgs.szSetting := szSetting;
+ cgs.pValue := @dbv;
+ if CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then
+ Result := ErrorValue
+ else begin
+ case dbv._type of
+ DBVT_ASCIIZ:
+ Result := AnsiToWideString(dbv.szVal.a,hppCodepage);
+ DBVT_UTF8:
+ Result := AnsiToWideString(dbv.szVal.a,CP_UTF8);
+ DBVT_WCHAR:
+ Result := WideString(dbv.szVal.w);
+ end;
+ // free variant
+ DBFreeVariant(@dbv);
+ end;
+end;
+
+function GetDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload;
+var
+ p: Pointer;
+ s: Integer;
+begin
+ Result := Default;
+ if not GetDBBlob(hContact,Module,Param,p,s) then exit;
+ if s <> SizeOf(TDateTime) then begin
+ FreeMem(p,s);
+ exit;
+ end;
+ Result := PDateTime(p)^;
+ FreeMem(p,s);
+end;
+
+function GetDBDateTime(const Module,Param: AnsiString; Default: TDateTime): TDateTime; overload;
+begin
+ Result := GetDBDateTime(0,Module,Param,Default);
+end;
+
+function DBDelete(const Module, Param: AnsiString): Boolean;
+begin
+ Result := DBDelete(0,Module,Param);
+end;
+
+function DBDelete(const hContact: THandle; const Module, Param: AnsiString): Boolean;
+begin
+ Result := (DBDeleteContactSetting(hContact,PAnsiChar(Module),PAnsiChar(Param)) = 0);
+end;
+
+function WriteDBBool(const Module,Param: AnsiString; Value: Boolean): Integer;
+begin
+ Result := WriteDBBool(0,Module,Param,Value);
+end;
+
+function WriteDBBool(const hContact: THandle; const Module,Param: AnsiString; Value: Boolean): Integer;
+begin
+ Result := WriteDBByte(hContact,Module,Param,Byte(Value));
+end;
+
+function WriteDBByte(const Module,Param: AnsiString; Value: Byte): Integer;
+begin
+ Result := WriteDBByte(0,Module,Param,Value);
+end;
+
+function WriteDBByte(const hContact: THandle; const Module,Param: AnsiString; Value: Byte): Integer;
+begin
+ Result := DBWriteContactSettingByte(hContact,PAnsiChar(Module), PAnsiChar(Param), Value);
+end;
+
+function WriteDBWord(const Module,Param: AnsiString; Value: Word): Integer;
+begin
+ Result := WriteDBWord(0,Module,Param,Value);
+end;
+
+function WriteDBWord(const hContact: THandle; const Module,Param: AnsiString; Value: Word): Integer;
+begin
+ Result := DBWriteContactSettingWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Value);
+end;
+
+function WriteDBDWord(const Module,Param: AnsiString; Value: DWord): Integer;
+begin
+ Result := WriteDBWord(0,Module,Param,Value);
+end;
+
+function WriteDBDWord(const hContact: THandle; const Module,Param: AnsiString; Value: DWord): Integer;
+begin
+ Result := DBWriteContactSettingDWord(hContact,PAnsiChar(Module),PAnsiChar(Param),Value);
+end;
+
+function WriteDBInt(const Module,Param: AnsiString; Value: Integer): Integer;
+begin
+ Result := WriteDBInt(0,Module,Param,Value);
+end;
+
+function WriteDBInt(const hContact: THandle; const Module,Param: AnsiString; Value: Integer): Integer;
+var
+ cws: TDBCONTACTWRITESETTING;
+begin
+ cws.szModule := PAnsiChar(Module);
+ cws.szSetting := PAnsiChar(Param);
+ cws.value._type := DBVT_DWORD;
+ cws.value.dVal := Value;
+ Result := CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws));
+end;
+
+function WriteDBStr(const Module,Param: AnsiString; Value: AnsiString): Integer;
+begin
+ Result := WriteDBStr(0,Module,Param,Value);
+end;
+
+function WriteDBStr(const hContact: THandle; const Module,Param: AnsiString; Value: AnsiString): Integer;
+begin
+ Result := DBWriteContactSettingString(hContact,PAnsiChar(Module),PAnsiChar(Param),PAnsiChar(Value));
+end;
+
+function WriteDBWideStr(const Module,Param: AnsiString; Value: WideString): Integer;
+begin
+ Result := WriteDBWideStr(0,Module,Param,Value);
+end;
+
+function WriteDBWideStr(const hContact: THandle; const Module,Param: AnsiString; Value: WideString): Integer;
+begin
+ Result := DBWriteContactSettingWideString(hContact,PAnsiChar(Module),PAnsiChar(Param),PWideChar(Value));
+end;
+
+function DBWriteContactSettingWideString(hContact: THandle; const szModule: PAnsiChar; const szSetting: PAnsiChar; const val: PWideChar): Integer;
+var
+ cws: TDBCONTACTWRITESETTING;
+begin
+ cws.szModule := szModule;
+ cws.szSetting := szSetting;
+ cws.value._type := DBVT_WCHAR;
+ cws.value.szVal.w := val;
+ Result := CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws));
+end;
+
+function WriteDBBlob(const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer;
+begin
+ Result := WriteDBBlob(0,Module,Param,Value,Size);
+end;
+
+function WriteDBBlob(const hContact: THandle; const Module,Param: AnsiString; Value: Pointer; Size: Integer): Integer;
+var
+ cws: TDBContactWriteSetting;
+begin
+ ZeroMemory(@cws,SizeOf(cws));
+ cws.szModule := PAnsiChar(Module);
+ cws.szSetting := PAnsiChar(Param);
+ cws.value._type := DBVT_BLOB;
+ cws.value.pbVal := Value;
+ cws.value.cpbVal := Word(Size);
+ Result := CallService(MS_DB_CONTACT_WRITESETTING,hContact,lParam(@cws));
+end;
+
+function WriteDBDateTime(const hContact: THandle; const Module,Param: AnsiString; Value: TDateTime): Integer; overload;
+var
+ p: PDateTime;
+begin
+ GetMem(p,SizeOf(TDateTime));
+ p^ := Value;
+ Result := WriteDBBlob(hContact,Module,Param,p,SizeOf(TDateTime));
+ FreeMem(p,SizeOf(TDateTime));
+end;
+
+function WriteDBDateTime(const Module,Param: AnsiString; Value: TDateTime): Integer; overload;
+begin
+ Result := WriteDBDateTime(0,Module,Param,Value);
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/FSMonitor.pas b/plugins/MirandaNGHistoryToDB/FSMonitor.pas
new file mode 100644
index 0000000000..b19cde322f
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/FSMonitor.pas
@@ -0,0 +1,222 @@
+{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+unit FSMonitor;
+
+{$I jedi.inc}
+
+interface
+
+type
+ // ( callback )
+ PInfoCallBack = ^TInfoCallBack;
+ TInfoCallBack = record
+ FAction : Integer; // ( FILE_ACTION_XXX)
+ FDrive : String; // ,
+ FOldFileName : String; //
+ FNewFileName : String; //
+ end;
+
+ // callback ,
+ TWatchFileSystemCallBack = procedure (pInfo: TInfoCallBack);
+
+ {
+ :
+ pName -
+ pFilter - FILE_NOTIFY_XXX
+ pSubTree -
+ pInfoCallBack - callback , }
+ procedure StartWatch(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack);
+ //
+ procedure StopWatch;
+
+implementation
+
+uses
+ Classes, Windows, SysUtils, IniFiles;
+
+const
+ FILE_LIST_DIRECTORY = $0001;
+
+type
+ PFileNotifyInformation = ^TFileNotifyInformation;
+ TFileNotifyInformation = record
+ NextEntryOffset : DWORD;
+ Action : DWORD;
+ FileNameLength : DWORD;
+ FileName : Array[0..0] of WideChar;
+ end;
+
+ WFSError = class(Exception);
+
+ TWFS = class(TThread)
+ private
+ FName : String;
+ FFilter : Cardinal;
+ FSubTree : Boolean;
+ FInfoCallBack : TWatchFileSystemCallBack;
+ FWatchHandle : THandle;
+ FWatchBuf : Array[0..4096] of Byte;
+ FOverLapp : TOverlapped;
+ FPOverLapp : POverlapped;
+ FBytesWritte : DWORD;
+ FCompletionPort : THandle;
+ FNumBytes : Cardinal;
+ FOldFileName : String;
+ function CreateDirHandle(aDir: string): THandle;
+ procedure WatchEvent;
+ //procedure HandleEvent;
+ protected
+ procedure Execute; override;
+ public
+ constructor Create(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack);
+ destructor Destroy; override;
+ end;
+
+
+var
+ WFS : TWFS;
+
+procedure StartWatch(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack);
+begin
+ WFS := TWFS.Create(pName, pFilter, pSubTree, pInfoCallBack);
+end;
+
+procedure StopWatch;
+begin
+ if Assigned(WFS) then
+ begin
+ PostQueuedCompletionStatus(WFS.FCompletionPort, 0, 0, nil);
+ WFS.Terminate;
+ WFS.WaitFor;
+ WFS.Free;
+ WFS := nil;
+ end;
+end;
+
+constructor TWFS.Create(pName: String; pFilter: Cardinal; pSubTree: Boolean; pInfoCallBack: TWatchFileSystemCallBack);
+begin
+ inherited Create(True);
+ FreeOnTerminate := False;
+ FName := IncludeTrailingBackslash(pName);
+ FFilter := pFilter;
+ FSubTree := pSubTree;
+ FOldFileName := EmptyStr;
+ ZeroMemory(@FOverLapp, SizeOf(TOverLapped));
+ FPOverLapp := @FOverLapp;
+ ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
+ FInfoCallBack := pInfoCallBack;
+ Resume;
+end;
+
+
+destructor TWFS.Destroy;
+begin
+ PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);
+ CloseHandle(FWatchHandle);
+ FWatchHandle := 0;
+ CloseHandle(FCompletionPort);
+ FCompletionPort := 0;
+ inherited Destroy;
+end;
+
+function TWFS.CreateDirHandle(aDir: String): THandle;
+begin
+ Result := CreateFile(PChar(aDir), FILE_LIST_DIRECTORY, FILE_SHARE_READ+FILE_SHARE_DELETE+FILE_SHARE_WRITE,
+ nil,OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
+end;
+
+procedure TWFS.Execute;
+begin
+ FWatchHandle := CreateDirHandle(FName);
+ WatchEvent;
+end;
+
+{procedure TWFS.HandleEvent;
+var
+ FileNotifyInfo : PFileNotifyInformation;
+ InfoCallBack : TInfoCallBack;
+ Offset : Longint;
+begin
+ Pointer(FileNotifyInfo) := @FWatchBuf[0];
+ repeat
+ Offset := FileNotifyInfo^.NextEntryOffset;
+ InfoCallBack.FAction := FileNotifyInfo^.Action;
+ InfoCallBack.FDrive := FName;
+ SetString(InfoCallBack.FNewFileName,FileNotifyInfo^.FileName,FileNotifyInfo^.FileNameLength );
+ InfoCallBack.FNewFileName := Trim(InfoCallBack.FNewFileName);
+ case FileNotifyInfo^.Action of
+ FILE_ACTION_RENAMED_OLD_NAME: FOldFileName := Trim(WideCharToString(@(FileNotifyInfo^.FileName[0])));
+ FILE_ACTION_RENAMED_NEW_NAME: InfoCallBack.FOldFileName := FOldFileName;
+ end;
+ FInfoCallBack(InfoCallBack);
+ PChar(FileNotifyInfo) := PChar(FileNotifyInfo)+Offset;
+ until (Offset=0) or Terminated;
+end;}
+
+procedure TWFS.WatchEvent;
+var
+ {$ifdef DELPHIXE_UP}
+ CompletionKey: DWORD_PTR;
+ {$ELSE}
+ CompletionKey: Cardinal;
+ {$endif}
+ // HandleEvent
+ FileNotifyInfo : PFileNotifyInformation;
+ InfoCallBack : TInfoCallBack;
+ Offset : Longint;
+ // End
+begin
+ FCompletionPort := CreateIoCompletionPort(FWatchHandle, 0, Longint(pointer(self)), 0);
+ ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
+ if not ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree,
+ FFilter, @FBytesWritte, @FOverLapp, 0) then
+ begin
+ raise WFSError.Create(SysErrorMessage(GetLastError));
+ Terminate;
+ end
+ else
+ begin
+ while not Terminated do
+ begin
+ GetQueuedCompletionStatus(FCompletionPort, FNumBytes, CompletionKey, FPOverLapp, INFINITE);
+ if CompletionKey <> 0 then
+ begin
+ //Synchronize(HandleEvent);
+ { .. Synchronize(HandleEvent)
+ ,
+ -> http://forum.qip.ru/showthread.php?t=25200 }
+ Pointer(FileNotifyInfo) := @FWatchBuf[0];
+ repeat
+ Offset := FileNotifyInfo^.NextEntryOffset;
+ InfoCallBack.FAction := FileNotifyInfo^.Action;
+ InfoCallBack.FDrive := FName;
+ SetString(InfoCallBack.FNewFileName,FileNotifyInfo^.FileName,FileNotifyInfo^.FileNameLength );
+ InfoCallBack.FNewFileName := Trim(InfoCallBack.FNewFileName);
+ case FileNotifyInfo^.Action of
+ FILE_ACTION_RENAMED_OLD_NAME: FOldFileName := Trim(WideCharToString(@(FileNotifyInfo^.FileName[0])));
+ FILE_ACTION_RENAMED_NEW_NAME: InfoCallBack.FOldFileName := FOldFileName;
+ end;
+ FInfoCallBack(InfoCallBack);
+ PChar(FileNotifyInfo) := PChar(FileNotifyInfo)+Offset;
+ until (Offset=0) or Terminated;
+ // End synchronize
+ ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
+ FBytesWritte := 0;
+ ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree, FFilter,
+ @FBytesWritte, @FOverLapp, 0);
+ end
+ else
+ Terminate;
+ end
+ end
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/Global.inc b/plugins/MirandaNGHistoryToDB/Global.inc
new file mode 100644
index 0000000000..cdbc123caa
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/Global.inc
@@ -0,0 +1,2 @@
+// Replace Default Miranda History Module
+{$DEFINE REPLDEFHISTMOD}
diff --git a/plugins/MirandaNGHistoryToDB/Global.pas b/plugins/MirandaNGHistoryToDB/Global.pas
new file mode 100644
index 0000000000..fc4cc4c4bb
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/Global.pas
@@ -0,0 +1,1250 @@
+{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+unit Global;
+
+interface
+
+uses
+ Windows, SysUtils, IniFiles, Messages, XMLIntf, XMLDoc,
+ FSMonitor, DCPcrypt2, DCPblockciphers, DCPsha1, DCPdes, DCPmd5, ActiveX, MapStream;
+
+type
+ TCopyDataType = (cdtString = 0, cdtImage = 1, cdtRecord = 2);
+ TCopyDataStruct = packed record
+ dwData: DWORD;
+ cbData: DWORD;
+ lpData: Pointer;
+ end;
+ //TByteArr = Array of Byte;
+ TArrayOfString = Array of String;
+
+const
+ htdPluginShortName = 'MirandaNGHistoryToDB';
+ htdDescription_RU = ' .';
+ htdDescription_EN = 'Storing the history in the database.';
+ htdAuthor_EN = 'Michael Grigorev';
+ htdAuthor_RU = 'Michael Grigorev';
+ htdAuthorEmail = 'sleuthhound@gmail.com';
+ htdCopyright_EN = '(c) 2011-2013 Michael Grigorev';
+ htdCopyright_RU = '(c) 2011-2013 Michael Grigorev';
+ htdHomePageURL = 'http://www.im-history.ru/';
+ htdVerMajor = {MAJOR_VER}2{/MAJOR_VER};
+ htdVerMinor = {MINOR_VER}5{/MINOR_VER};
+ htdVerRelease = {SUB_VER}0{/SUB_VER};
+ htdVerBuild = {BUILD}0{/BUILD};
+ htdVersion = htdVerMajor shl 24 + htdVerMinor shl 16 + htdVerRelease shl 8 + htdVerBuild;
+ {$IFDEF WIN32}
+ htdPlatform = 'x86';
+ {$ELSE}
+ htdPlatform = 'x64';
+ {$ENDIF}
+ htdDBName = 'MirandaNGHistoryToDB';
+ htdIMClientName = 'MirandaNG';
+ {htdFLUpdateURL = 'http://addons.miranda-im.org/feed.php?dlfile=0';
+ htdFLVersionURL = 'http://addons.miranda-im.org/details.php?action=viewfile&id=0';
+ htdFLVersionPrefix= '<span class="fileNameHeader">'+htdPluginShortName+' ';
+ htdUpdateURL = 'http://www.im-history.ru/get.php?file=MirandaNGHistoryToDB';
+ htdVersionURL = 'http://www.im-history.ru/get.php?file=MirandaNGHistoryToDB-Version';
+ htdVersionPrefix = htdPluginShortName+' version ';
+ htdChangelogURL = 'http://www.im-history.ru/changelog/miranda.html';}
+
+ // Generate your own unique id for your plugin.
+ // Do not use this UUID!
+ // Use Shift+Ctrl+G or uuidgen.exe to generate the uuuid
+ MIID_HISTORYTODBDLL:TGUID = '{1F83C057-C59F-483B-B82E-1AE5CA6138EB}';
+
+ MS_MHTD_SHOWHISTORY: PAnsiChar = 'MirandaNGHistoryToDB/ShowHistory';
+ MS_MHTD_GETVERSION: PAnsiChar = 'MirandaNGHistoryToDB/GetVersion';
+ MS_MHTD_SHOWCONTACTHISTORY: PAnsiChar = 'MirandaNGHistoryToDB/ShowContactHistory';
+
+ DefaultDBAddres = 'db01.im-history.ru';
+ DefaultDBName = 'imhistory';
+ ININame = 'HistoryToDB.ini';
+ DefININame = 'DefaultUser.ini';
+ MesLogName = 'HistoryToDBMes.sql';
+ ErrLogName = 'HistoryToDBErr.log';
+ ImportLogName = 'HistoryToDBImport.sql';
+ ContactListName = 'ContactList.csv';
+ ProtoListName = 'ProtoList.csv';
+ DebugLogName = 'HistoryToDBDebug.log';
+ MSG_LOG : WideString = 'insert into uin_%s values (null, %s, ''%s'', ''%s'', ''%s'', ''%s'', %s, ''%s'', ''%s'', ''%s'', null);';
+ MSG_LOG_ORACLE : WideString = 'insert into uin_%s values (null, %s, ''%s'', ''%s'', ''%s'', ''%s'', %s, %s, ''%s'', ''%s'', null)';
+ CHAT_MSG_LOG : WideString = 'insert into uin_chat_%s values (null, %s, ''%s'', ''%s'', ''%s'', ''%s'', %s, %s, %s, ''%s'', ''%s'', null);';
+ CHAT_MSG_LOG_ORACLE : WideString = 'insert into uin_chat_%s values (null, %s, %s, ''%s'', ''%s'', ''%s'', %s, %s, %s, ''%s'', ''%s'', null)';
+ // (01/01/1970) Unix Timestamp
+ UnixStartDate: TDateTime = 25569.0;
+ // HistoryToDBSync HistoryToDBViewer
+ EncryptKey = 'jsU6s2msoxghsKsn7';
+ //
+ WM_LANGUAGECHANGED = WM_USER + 1;
+ dirLangs = 'langs\';
+ defaultLangFile = 'English.xml';
+ ThankYouText_Rus = ' .' + #13#10 +
+ ' (UksusoFF) .' + #13#10 +
+ ' .' + #13#10 +
+ ' . (HDHMETRO) .' + #13#10 +
+ 'Providence .' + #13#10 +
+ 'Cy6 RnQ.';
+ ThankYouText_Eng = 'Anna Nikiforova for active testing of plug-in.' + #13#10 +
+ 'Kirill Uksusov (UksusoFF) for active testing of plug-in and new ideas.' + #13#10 +
+ 'Igor Guryanov for active testing of plug-in.' + #13#10 +
+ 'Vyacheslav S. (HDHMETRO) for active testing of plug-in.' + #13#10 +
+ 'Providence for active testing of plug-in and new ideas.' + #13#10 +
+ 'Cy6 for help in implementing the import history RnQ.';
+
+var
+ hppCodepage: Cardinal;
+ hppVersionStr: AnsiString;
+ MetaContactsEnabled: Boolean;
+ MetaContactsProto: AnsiString;
+ WriteErrLog, AniEvents, EnableHistoryEncryption, ShowPluginButton, AddSpecialContact, BlockSpamMsg: Boolean;
+ EnableDebug, EnableCallBackDebug, ExPrivateChatName, GetContactList: Boolean;
+ SyncMethod, SyncInterval, SyncMessageCount, MaxErrLogSize: Integer;
+ DBType, DBName, DBUserName, DefaultLanguage: String;
+ //Global_AccountUIN: WideString;
+ //Global_AccountName: WideString;
+ //Global_CurrentAccountUIN: WideString;
+ //Global_CurrentAccountName: WideString;
+ Global_CurrentAccountProtoID: Integer;
+ Global_CurrentAccountProtoName, Global_CurrentAccountProtoAccount: WideString;
+ Glogal_History_Type: Integer;
+ //Global_ChatName: WideString;
+ Global_AboutForm_Showing: Boolean;
+ DllPath, DllName, ProfilePath, MyAccount: String;
+ MessageCount: Integer;
+ //
+ CoreLanguage: String;
+ AboutFormHandle: HWND;
+ ExportFormHandle: HWND;
+ LangDoc: IXMLDocument;
+ PluginPath: String = '';
+ //
+ Cipher: TDCP_3des;
+ Digest: Array[0..19] of Byte;
+ Hash: TDCP_sha1;
+ // -
+ TFMsgLog: TextFile;
+ MsgLogOpened: Boolean;
+ TFErrLog: TextFile;
+ ErrLogOpened: Boolean;
+ TFDebugLog: TextFile;
+ DebugLogOpened: Boolean;
+ TFContactListLog: TextFile;
+ ContactListLogOpened: Boolean;
+ TFProtoListLog: TextFile;
+ ProtoListLogOpened: Boolean;
+ TFImportLog: TextFile;
+ ImportLogOpened: Boolean;
+ ExportFormDestroy: Boolean;
+ // MMF
+ FMap: TMapStream;
+
+function BoolToIntStr(Bool: Boolean): String;
+function UnixToDateTime(USec: Longint): TDateTime;
+function PrepareString(const Source : PWideChar) : WideString;
+function MatchStrings(Source, Pattern: String): Boolean;
+function ReadCustomINI(INIPath, CustomParams, DefaultParamsStr: String): String;
+function EncryptMD5(Str: String): String;
+function EncryptStr(const Str: String): String;
+function SearchMainWindow(MainWindowName: pWideChar): Boolean;
+function OpenLogFile(LogPath: String; LogType: Integer): Boolean;
+function GetMyFileSize(const Path: String): Integer;
+function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String;
+function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
+function AnsiToWideString(const S: AnsiString; CodePage: Cardinal; InLength: Integer = -1): WideString;
+function WideToAnsiString(const WS: WideString; CodePage: Cardinal; InLength: Integer = -1): AnsiString;
+function Utf8ToWideChar(Dest: PWideChar; MaxDestChars: Integer; Source: PAnsiChar; SourceBytes: Integer; CodePage: Cardinal = CP_ACP): Integer;
+function StrContactProtoToInt(Proto: AnsiString): Integer;
+function UnixToLocalTime(tUnix :Longint): TDateTime;
+function GetUserTempPath: WideString;
+procedure IMDelay(Value: Cardinal);
+procedure EncryptInit;
+procedure EncryptFree;
+procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer);
+procedure CloseLogFile(LogType: Integer);
+procedure LoadINI(INIPath: String);
+procedure OnSendMessageToAllComponent(Msg: String);
+procedure OnSendMessageToOneComponent(WinName, Msg: String);
+procedure WriteCustomINI(INIPath, CustomParams, ParamsStr: String);
+procedure ProfileDirChangeCallBack(pInfo: TInfoCallBack);
+//
+procedure CoreLanguageChanged;
+procedure MsgDie(Caption, Msg: WideString);
+procedure MsgInf(Caption, Msg: WideString);
+function GetLangStr(StrID: String): WideString;
+
+implementation
+
+uses Menu;
+
+function BoolToIntStr(Bool: Boolean): String;
+begin
+ if Bool then
+ Result := '1'
+ else
+ Result := '0'
+end;
+
+// Unix Timestamp DateTime
+function UnixToDateTime(USec: Longint): TDateTime;
+begin
+ Result := (Usec / 86400) + UnixStartDate;
+end;
+
+//
+function PrepareString(const Source : PWideChar) : WideString;
+var
+ SLen,i : Cardinal;
+ WSTmp : WideString;
+ WChar : WideChar;
+begin
+ Result := '';
+ SLen := Length(WideString(Source));
+ if (SLen>0) then
+ begin
+ for i:=1 to SLen do
+ begin
+ WChar:=WideString(Source)[i];
+ case WChar of
+ #$09 :{tab} WSTmp:=WSTmp+'\t';
+ #$0A :{line feed} WSTmp:=WSTmp+'\n';
+ #$0D :{carriage return} WSTmp:=WSTmp+'\r';
+ #$27 :{single quote mark aka apostrophe?} WSTmp:=WSTmp+WChar+WChar;
+ #$22, {double quote mark aka inch sign?}
+ #$5C, {backslash itself}
+ #$60 :{another single quote mark} WSTmp:=WSTmp+'\'+WChar;
+ else WSTmp := WSTmp + WChar;
+ end;
+ end;
+ Result := WSTmp;
+ end;
+end;
+
+// LogType = 0 - MesLogName
+// LogType = 1 - ErrLogName
+// LogType = 2 - DebugLogName
+// LogType = 3 - ContactListName
+// LogType = 4 - ProtoListName
+// LogType = 5 - ImportLogName
+function OpenLogFile(LogPath: String; LogType: Integer): Boolean;
+var
+ Path: WideString;
+begin
+ if LogType = 0 then
+ Path := LogPath + MesLogName
+ else if LogType = 1 then
+ begin
+ Path := LogPath + ErrLogName;
+ if (LogType > 0) and (GetMyFileSize(Path) > MaxErrLogSize*1024) then
+ DeleteFile(Path);
+ end
+ else if LogType = 2 then
+ Path := LogPath + DebugLogName
+ else if LogType = 3 then
+ begin
+ Path := LogPath + ContactListName;
+ if FileExists(Path) then
+ begin
+ try
+ DeleteFile(Path);
+ except
+ end;
+ end;
+ end
+ else if LogType = 4 then
+ begin
+ Path := LogPath + ProtoListName;
+ if FileExists(Path) then
+ begin
+ try
+ DeleteFile(Path);
+ except
+ end;
+ end;
+ end
+ else
+ Path := LogPath + ImportLogName;
+ {$I-}
+ try
+ if LogType = 0 then
+ Assign(TFMsgLog, Path)
+ else if LogType = 1 then
+ Assign(TFErrLog, Path)
+ else if LogType = 2 then
+ Assign(TFDebugLog, Path)
+ else if LogType = 3 then
+ Assign(TFContactListLog, Path)
+ else if LogType = 4 then
+ Assign(TFProtoListLog, Path)
+ else
+ Assign(TFImportLog, Path);
+ if FileExists(Path) then
+ begin
+ if LogType = 0 then
+ Append(TFMsgLog)
+ else if LogType = 1 then
+ Append(TFErrLog)
+ else if LogType = 2 then
+ Append(TFDebugLog)
+ else if LogType = 3 then
+ Append(TFContactListLog)
+ else if LogType = 4 then
+ Append(TFProtoListLog)
+ else
+ Append(TFImportLog);
+ end
+ else
+ begin
+ if LogType = 0 then
+ Rewrite(TFMsgLog)
+ else if LogType = 1 then
+ Rewrite(TFErrLog)
+ else if LogType = 2 then
+ Rewrite(TFDebugLog)
+ else if LogType = 3 then
+ Rewrite(TFContactListLog)
+ else if LogType = 4 then
+ Rewrite(TFProtoListLog)
+ else
+ Rewrite(TFImportLog);
+ end;
+ Result := True;
+ except
+ on e :
+ Exception do
+ begin
+ CloseLogFile(LogType);
+ Result := False;
+ Exit;
+ end;
+ end;
+ {$I+}
+end;
+
+// LogType = 0 - MesLogName
+// LogType = 1 - ErrLogName
+// LogType = 2 - DebugLogName
+// LogType = 3 - ContactListName
+// LogType = 4 - ProtoListName
+procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer);
+var
+ Path: WideString;
+begin
+ if LogType = 0 then
+ begin
+ if not MsgLogOpened then
+ MsgLogOpened := OpenLogFile(LogPath, 0);
+ Path := LogPath + MesLogName
+ end
+ else if LogType = 1 then
+ begin
+ if not ErrLogOpened then
+ ErrLogOpened := OpenLogFile(LogPath, 1);
+ Path := LogPath + ErrLogName;
+ if (LogType > 0) and (GetMyFileSize(Path) > MaxErrLogSize*1024) then
+ begin
+ CloseLogFile(LogType);
+ DeleteFile(Path);
+ if not OpenLogFile(LogPath, LogType) then
+ Exit;
+ end;
+ end
+ else if LogType = 2 then
+ begin
+ if not DebugLogOpened then
+ DebugLogOpened := OpenLogFile(LogPath, 2);
+ Path := LogPath + DebugLogName;
+ end
+ else if LogType = 3 then
+ begin
+ if not ContactListLogOpened then
+ ContactListLogOpened := OpenLogFile(LogPath, 3);
+ Path := LogPath + ContactListName;
+ end
+ else if LogType = 4 then
+ begin
+ if not ProtoListLogOpened then
+ ProtoListLogOpened := OpenLogFile(LogPath, 4);
+ Path := LogPath + ProtoListName;
+ end
+ else
+ begin
+ if not ImportLogOpened then
+ ImportLogOpened := OpenLogFile(LogPath, 5);
+ Path := LogPath + ImportLogName;
+ end;
+ {$I-}
+ try
+ if LogType = 0 then
+ WriteLn(TFMsgLog, TextString)
+ else if LogType = 1 then
+ WriteLn(TFErrLog, TextString)
+ else if LogType = 2 then
+ WriteLn(TFDebugLog, TextString)
+ else if LogType = 3 then
+ WriteLn(TFContactListLog, TextString)
+ else if LogType = 4 then
+ WriteLn(TFProtoListLog, TextString)
+ else
+ WriteLn(TFImportLog, TextString);
+ except
+ on e :
+ Exception do
+ begin
+ CloseLogFile(LogType);
+ Exit;
+ end;
+ end;
+ if MsgLogOpened then
+ CloseLogFile(0);
+ {$I+}
+end;
+
+procedure CloseLogFile(LogType: Integer);
+begin
+ {$I-}
+ if LogType = 0 then
+ begin
+ CloseFile(TFMsgLog);
+ MsgLogOpened := False;
+ end
+ else if LogType = 1 then
+ begin
+ CloseFile(TFErrLog);
+ ErrLogOpened := False;
+ end
+ else if LogType = 2 then
+ begin
+ CloseFile(TFDebugLog);
+ DebugLogOpened := False;
+ end
+ else if LogType = 3 then
+ begin
+ CloseFile(TFContactListLog);
+ ContactListLogOpened := False;
+ end
+ else if LogType = 4 then
+ begin
+ CloseFile(TFProtoListLog);
+ ProtoListLogOpened := False;
+ end
+ else
+ begin
+ CloseFile(TFImportLog);
+ ImportLogOpened := False;
+ end;
+ {$I+}
+end;
+
+// , -1
+function GetMyFileSize(const Path: String): Integer;
+var
+ FD: TWin32FindData;
+ FH: THandle;
+begin
+ FH := FindFirstFile(PChar(Path), FD);
+ Result := 0;
+ if FH = INVALID_HANDLE_VALUE then
+ Exit;
+ Result := FD.nFileSizeLow;
+ if ((FD.nFileSizeLow and $80000000) <> 0) or
+ (FD.nFileSizeHigh <> 0) then
+ Result := -1;
+ //FindClose(FH);
+end;
+
+//
+procedure LoadINI(INIPath: String);
+var
+ Path: WideString;
+ Temp: String;
+ INI: TIniFile;
+begin
+ //
+ if not DirectoryExists(INIPath) then
+ CreateDir(INIPath);
+ Path := INIPath + ININame;
+ if FileExists(Path) then
+ begin
+ Ini := TIniFile.Create(Path);
+ DBType := INI.ReadString('Main', 'DBType', 'mysql'); // mysql postgresql
+ DBUserName := INI.ReadString('Main', 'DBUserName', 'username');
+ SyncMethod := INI.ReadInteger('Main', 'SyncMethod', 1);
+ SyncInterval := INI.ReadInteger('Main', 'SyncInterval', 0);
+
+ Temp := INI.ReadString('Main', 'WriteErrLog', '1');
+ if Temp = '1' then WriteErrLog := True
+ else WriteErrLog := False;
+
+ Temp := INI.ReadString('Main', 'ShowAnimation', '1');
+ if Temp = '1' then AniEvents := True
+ else AniEvents := False;
+
+ Temp := INI.ReadString('Main', 'EnableHistoryEncryption', '0');
+ if Temp = '1' then EnableHistoryEncryption := True
+ else EnableHistoryEncryption := False;
+
+ Temp := INI.ReadString('Main', 'AddSpecialContact', '1');
+ if Temp = '1' then AddSpecialContact := True
+ else AddSpecialContact := False;
+
+ DefaultLanguage := INI.ReadString('Main', 'DefaultLanguage', 'Russian');
+ SyncMessageCount := INI.ReadInteger('Main', 'SyncMessageCount', 50);
+
+ Temp := INI.ReadString('Main', 'ShowPluginButton', '1');
+ if Temp = '1' then ShowPluginButton := True
+ else ShowPluginButton := False;
+
+ Temp := INI.ReadString('Main', 'BlockSpamMsg', '0');
+ if Temp = '1' then BlockSpamMsg := True
+ else BlockSpamMsg := False;
+
+ Temp := INI.ReadString('Main', 'EnableExPrivateChatName', '0');
+ if Temp = '1' then ExPrivateChatName := True
+ else ExPrivateChatName := False;
+
+ Temp := INI.ReadString('Main', 'EnableDebug', '0');
+ if Temp = '1' then EnableDebug := True
+ else EnableDebug := False;
+
+ Temp := INI.ReadString('Main', 'EnableCallBackDebug', '0');
+ if Temp = '1' then EnableCallBackDebug := True
+ else EnableCallBackDebug := False;
+
+ MaxErrLogSize := INI.ReadInteger('Main', 'MaxErrLogSize', 20);
+ end
+ else
+ begin
+ INI := TIniFile.Create(path);
+ // -
+ DBType := 'mysql';
+ DBName := DefaultDBName;
+ DBUserName := 'username';
+ SyncMethod := 1;
+ SyncInterval := 0;
+ SyncMessageCount := 50;
+ WriteErrLog := True;
+ AniEvents := True;
+ ShowPluginButton := True;
+ EnableHistoryEncryption := False;
+ AddSpecialContact := True;
+ BlockSpamMsg := False;
+ EnableDebug := False;
+ EnableCallBackDebug := False;
+ MaxErrLogSize := 20;
+ //
+ INI.WriteString('Main', 'DBType', DBType);
+ INI.WriteString('Main', 'DBAddress', DefaultDBAddres);
+ INI.WriteString('Main', 'DBSchema', 'username');
+ INI.WriteString('Main', 'DBPort', '3306');
+ INI.WriteString('Main', 'DBName', DefaultDBName);
+ INI.WriteString('Main', 'DBUserName', DBUserName);
+ INI.WriteString('Main', 'DBPasswd', 'skGvQNyWUHcHohJS2+2r4A==');
+ INI.WriteInteger('Main', 'SyncMethod', SyncMethod);
+ INI.WriteInteger('Main', 'SyncInterval', SyncInterval);
+ INI.WriteInteger('Main', 'SyncTimeCount', 40);
+ INI.WriteInteger('Main', 'SyncMessageCount', SyncMessageCount);
+ INI.WriteInteger('Main', 'NumLastHistoryMsg', 6);
+ INI.WriteString('Main', 'WriteErrLog', BoolToIntStr(WriteErrLog));
+ INI.WriteString('Main', 'ShowAnimation', BoolToIntStr(AniEvents));
+ INI.WriteString('Main', 'EnableHistoryEncryption', BoolToIntStr(EnableHistoryEncryption));
+ INI.WriteString('Main', 'DefaultLanguage', CoreLanguage);
+ INI.WriteString('Main', 'HideHistorySyncIcon', '0');
+ INI.WriteString('Main', 'ShowPluginButton', BoolToIntStr(ShowPluginButton));
+ INI.WriteString('Main', 'AddSpecialContact', BoolToIntStr(AddSpecialContact));
+ INI.WriteString('Main', 'BlockSpamMsg', BoolToIntStr(BlockSpamMsg));
+ INI.WriteInteger('Main', 'MaxErrLogSize', MaxErrLogSize);
+ INI.WriteString('Main', 'AlphaBlend', '0');
+ INI.WriteString('Main', 'AlphaBlendValue', '255');
+ INI.WriteString('Main', 'EnableDebug', '0');
+ INI.WriteString('Main', 'EnableCallBackDebug', '0');
+ INI.WriteString('Fonts', 'FontInTitle', '183|-11|Verdana|0|96|8|Y|N|N|N|');
+ INI.WriteString('Fonts', 'FontOutTitle', '8404992|-11|Verdana|0|96|8|Y|N|N|N|');
+ INI.WriteString('Fonts', 'FontInBody', '-16777208|-11|Verdana|0|96|8|N|N|N|N|');
+ INI.WriteString('Fonts', 'FontOutBody', '-16777208|-11|Verdana|0|96|8|N|N|N|N|');
+ INI.WriteString('Fonts', 'FontService', '16711680|-11|Verdana|0|96|8|Y|N|N|N|');
+ INI.WriteString('Fonts', 'TitleParagraph', '4|4|');
+ INI.WriteString('Fonts', 'MessagesParagraph', '2|2|');
+ INI.WriteString('HotKey', 'GlobalHotKey', '0');
+ INI.WriteString('HotKey', 'SyncHotKey', 'Ctrl+Alt+F12');
+ INI.WriteString('HotKey', 'ExSearchHotKey', 'Ctrl+F3');
+ INI.WriteString('HotKey', 'ExSearchNextHotKey', 'F3');
+ end;
+ INI.Free;
+end;
+
+{ }
+procedure WriteCustomINI(INIPath, CustomParams, ParamsStr: String);
+var
+ Path: String;
+ INI: TIniFile;
+begin
+ Path := INIPath + ININame;
+ if FileExists(Path) then
+ begin
+ INI := TIniFile.Create(Path);
+ try
+ INI.WriteString('Main', CustomParams, ParamsStr);
+ finally
+ INI.Free;
+ end;
+ end
+ else
+ begin
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - WriteCustomINI: ' + GetLangStr('SettingsErrSave'), 2);
+ MsgDie(htdPluginShortName, GetLangStr('SettingsErrSave'));
+ end;
+end;
+
+{ }
+function ReadCustomINI(INIPath, CustomParams, DefaultParamsStr: String): String;
+var
+ Path: String;
+ INI: TIniFile;
+begin
+ Path := INIPath + ININame;
+ if FileExists(Path) then
+ begin
+ INI := TIniFile.Create(Path);
+ try
+ Result := INI.ReadString('Main', CustomParams, DefaultParamsStr);
+ finally
+ INI.Free;
+ end;
+ end
+ else
+ begin
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ReadCustomINI: ' + GetLangStr('SettingsErrRead'), 2);
+ MsgDie(htdPluginShortName, GetLangStr('SettingsErrRead'));
+ end;
+end;
+
+{ }
+{ :
+ 001 - HistoryToDB.ini
+ 002 -
+ 003 -
+ 0040 - ( AntiBoss)
+ 0041 - ( AntiBoss)
+ 005 -
+ 0050 - MD5-
+ 0051 - MD5-
+ 0060 -
+ 0061 -
+ 007 - -
+ 008 - /
+ :
+ :
+ 008|0|UserID|UserName|ProtocolType
+ :
+ 008|2|ChatName
+ 009 - .
+ 010 - SQL-insert
+}
+procedure OnSendMessageToAllComponent(Msg: String);
+var
+ HToDB: HWND;
+ copyDataStruct : TCopyDataStruct;
+ EncryptMsg, WinName: String;
+begin
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" .', 2);
+ EncryptMsg := EncryptStr(Msg);
+ // HistoryToDBViewer
+ WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')';
+ HToDB := FindWindow(nil, pWideChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);;
+ copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);;
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2);
+ end;
+ // HistoryToDBSync
+ WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')';
+ HToDB := FindWindow(nil, pWideChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);;
+ copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);;
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2);
+ end;
+ // HistoryToDBImport
+ WinName := 'HistoryToDBImport for ' + htdIMClientName + ' ('+MyAccount+')';
+ HToDB := FindWindow(nil, pWideChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);;
+ copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);;
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2);
+ end;
+ // HistoryToDBUpdater
+ WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')';
+ HToDB := FindWindow(nil, pWideChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);;
+ copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);;
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToAllComponent: "' + Msg + '" ' + WinName, 2);
+ end;
+end;
+
+procedure OnSendMessageToOneComponent(WinName, Msg: String);
+var
+ HToDB: HWND;
+ copyDataStruct : TCopyDataStruct;
+ AppNameStr, EncryptMsg: String;
+begin
+ // WinName
+ HToDB := FindWindow(nil, pWideChar(WinName));
+ if HToDB <> 0 then
+ begin
+ EncryptMsg := EncryptStr(Msg);
+ copyDataStruct.dwData := {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(cdtString);
+ copyDataStruct.cbData := Length(EncryptMsg) * SizeOf(Char);
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, {$IFDEF WIN32}Integer{$ELSE}LongInt{$ENDIF}(@copyDataStruct));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnSendMessageToOneComponent: "' + Msg + '" ' + WinName, 2);
+ end;
+end;
+
+{ }
+function SearchMainWindow(MainWindowName: pWideChar): Boolean;
+var
+ HToDB: HWND;
+begin
+ //
+ HToDB := FindWindow(nil, MainWindowName);
+ if HToDB <> 0 then
+ Result := True
+ else
+ Result := False
+end;
+
+{ .
+ , (* ?).
+ ( ) .
+ : MatchStrings('David Stidolph','*St*') True.
+ C- Sean Stanley
+ Delphi David Stidolph}
+function MatchStrings(Source, Pattern: String): Boolean;
+var
+ pSource: array[0..255] of Char;
+ pPattern: array[0..255] of Char;
+
+ function MatchPattern(element, pattern: PChar): Boolean;
+
+ function IsPatternWild(pattern: PChar): Boolean;
+ begin
+ Result := StrScan(pattern, '*') <> nil;
+ if not Result then
+ Result := StrScan(pattern, '?') <> nil;
+ end;
+
+ begin
+ if 0 = StrComp(pattern, '*') then
+ Result := True
+ else if (element^ = Chr(0)) and (pattern^ <> Chr(0)) then
+ Result := False
+ else if element^ = Chr(0) then
+ Result := True
+ else
+ begin
+ case pattern^ of
+ '*': if MatchPattern(element, @pattern[1]) then
+ Result := True
+ else
+ Result := MatchPattern(@element[1], pattern);
+ '?': Result := MatchPattern(@element[1], @pattern[1]);
+ else
+ if element^ = pattern^ then
+ Result := MatchPattern(@element[1], @pattern[1])
+ else
+ Result := False;
+ end;
+ end;
+ end;
+begin
+ StrPCopy(pSource, source);
+ StrPCopy(pPattern, pattern);
+ Result := MatchPattern(pSource, pPattern);
+end;
+
+//
+procedure MsgDie(Caption, Msg: WideString);
+begin
+ //{$IFDEF UNICODE}
+ //MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONERROR);
+ //{$ELSE}
+ //MessageBoxA(GetForegroundWindow, PAnsiChar(Msg), PAnsiChar(Caption), MB_ICONERROR);
+ //{$ENDIF}
+ MessageBox(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONERROR);
+end;
+
+//
+procedure MsgInf(Caption, Msg: WideString);
+begin
+ //{$IFDEF UNICODE}
+ //MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONINFORMATION);
+ //{$ELSE}
+ //MessageBoxA(GetForegroundWindow, PAnsiChar(Msg), PAnsiChar(Caption), MB_ICONINFORMATION);
+ //{$ENDIF}
+ MessageBox(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONINFORMATION);
+end;
+
+//
+function GetLangStr(StrID: String): WideString;
+begin
+ if (not Assigned(LangDoc)) or (not LangDoc.Active) then
+ begin
+ Result := '';
+ Exit;
+ end;
+ if LangDoc.ChildNodes['strings'].ChildNodes.FindNode(StrID) <> nil then
+ Result := LangDoc.ChildNodes['strings'].ChildNodes[StrID].Text
+ else
+ Result := 'String not found.';
+end;
+
+{ }
+procedure ProfileDirChangeCallBack(pInfo: TInfoCallBack);
+var
+ SettingsFormRequest: String;
+begin
+ SettingsFormRequest := ReadCustomINI(ProfilePath, 'SettingsFormRequestSend', '0');
+ if EnableCallBackDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ProfileDirChangeCallBack: SettingsFormRequestSend = ' + SettingsFormRequest + ' | FAction = ' + IntToStr(pInfo.FAction) + ' | FOldFileName = ' + pInfo.FOldFileName + ' | FNewFileName = ' + Trim(pInfo.FNewFileName), 2);
+ if (pInfo.FAction = 3) and (Trim(pInfo.FNewFileName) = 'HistoryToDB.ini') and (SettingsFormRequest = '0') then
+ begin
+ IMDelay(500);
+ LoadINI(ProfilePath);
+ CoreLanguage := DefaultLanguage;
+ if EnableCallBackDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ProfileDirChangeCallBack: HistoryToDB.ini . | = ' + CoreLanguage, 2);
+ // COM
+ // , , CoreLanguageChanged
+ // " CoInitialize"
+ // CoInitialize ActiveX
+ CoInitializeEx(nil, COINIT_MULTITHREADED);
+ //
+ CoreLanguageChanged;
+ // COM ()
+ CoUninitialize();
+ CoUninitialize();
+ //
+ RebuildMainMenu;
+ // MMF
+ if SyncMethod = 0 then
+ begin
+ if not Assigned(FMap) then
+ begin
+ if EnableCallBackDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ProfileDirChangeCallBack: TMapStream', 2);
+ FMap := TMapStream.CreateEx('HistoryToDB for QIP ('+MyAccount+')',MAXDWORD,2000);
+ end;
+ end
+ else
+ begin
+ if Assigned(FMap) then
+ begin
+ FMap.Free;
+ FMap := nil;
+ end;
+ end;
+ end;
+end;
+
+// MD5
+function EncryptMD5(Str: String): String;
+var
+ Hash: TDCP_md5;
+ Digest: Array[0..15] of Byte;
+ I: Integer;
+ P: String;
+begin
+ if Str <> '' then
+ begin
+ Hash:= TDCP_md5.Create(nil);
+ try
+ Hash.HashSize := 128;
+ Hash.Init;
+ Hash.UpdateStr(Str);
+ Hash.Final(Digest);
+ P := '';
+ for I:= 0 to 15 do
+ P:= P + IntToHex(Digest[I], 2);
+ finally
+ Hash.Free;
+ end;
+ Result := P;
+ end
+ else
+ Result := 'MD5';
+end;
+
+//
+procedure EncryptInit;
+begin
+ Hash:= TDCP_sha1.Create(nil);
+ try
+ Hash.Init;
+ Hash.UpdateStr(EncryptKey);
+ Hash.Final(Digest);
+ finally
+ Hash.Free;
+ end;
+ Cipher := TDCP_3des.Create(nil);
+ try
+ Cipher.Init(Digest,Sizeof(Digest)*8,nil);
+ except
+ on E: Exception do
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - EncryptInit: ' + E.Message, 2);
+ end;
+end;
+
+//
+procedure EncryptFree;
+begin
+ if Assigned(Cipher) then
+ begin
+ Cipher.Burn;
+ Cipher.Free;
+ end;
+end;
+
+//
+function EncryptStr(const Str: String): String;
+begin
+ Result := '';
+ if Str <> '' then
+ begin
+ Cipher.Reset;
+ Result := Cipher.EncryptString(Str);
+ end;
+end;
+
+{ .
+ , .
+ :
+ FileName - ,
+ ShowExtension - TRUE,
+ ( ), , ,
+ , . }
+function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String;
+var
+ I: Integer;
+ S, S1: string;
+begin
+ I := Length(FileName);
+ if I <> 0 then
+ begin
+ while (FileName[i] <> '\') and (i > 0) do
+ i := i - 1;
+ S := Copy(FileName, i + 1, Length(FileName) - i);
+ i := Length(S);
+ if i = 0 then
+ begin
+ Result := '';
+ Exit;
+ end;
+ while (S[i] <> '.') and (i > 0) do
+ i := i - 1;
+ S1 := Copy(S, 1, i - 1);
+ if s1 = '' then
+ s1 := s;
+ if ShowExtension = True then
+ Result := s
+ else
+ Result := s1;
+ end
+ else
+ Result := '';
+end;
+
+function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
+var
+ l: integer;
+begin
+ if ws = '' then
+ Result := ''
+ else
+ begin
+ l := WideCharToMultiByte(codePage,
+ WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
+ @ws[1], -1, nil, 0, nil, nil);
+ SetLength(Result, l - 1);
+ if l > 1 then
+ WideCharToMultiByte(codePage,
+ WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
+ @ws[1], -1, @Result[1], l - 1, nil, nil);
+ end;
+end;
+
+function AnsiToWideString(const S: AnsiString; CodePage: Cardinal; InLength: Integer = -1): WideString;
+var
+ InputLength,
+ OutputLength: Integer;
+begin
+ Result := '';
+ if S = '' then
+ exit;
+ if Codepage = CP_UTF8 then
+ begin
+ Result := UTF8ToWideString(S); // CP_UTF8 not supported on Windows 95
+ end
+ else
+ begin
+ if InLength < 0 then
+ InputLength := Length(S)
+ else
+ InputLength := InLength;
+ OutputLength := MultiByteToWideChar(Codepage, 0, PAnsiChar(S), InputLength, nil, 0);
+ SetLength(Result, OutputLength);
+ MultiByteToWideChar(Codepage, MB_PRECOMPOSED, PAnsiChar(S), InputLength, PWideChar(Result),
+ OutputLength);
+ end;
+end;
+
+function WideToAnsiString(const WS: WideString; CodePage: Cardinal; InLength: Integer = -1): AnsiString;
+var
+ InputLength,
+ OutputLength: Integer;
+begin
+ Result := '';
+ if WS = '' then
+ exit;
+ if Codepage = CP_UTF8 then
+ Result := UTF8Encode(WS) // CP_UTF8 not supported on Windows 95
+ else
+ begin
+ if InLength < 0 then
+ InputLength := Length(WS)
+ else
+ InputLength := InLength;
+ OutputLength := WideCharToMultiByte(Codepage, 0, PWideChar(WS), InputLength, nil, 0,
+ nil, nil);
+ SetLength(Result, OutputLength);
+ WideCharToMultiByte(Codepage, 0, PWideChar(WS), InputLength, PAnsiChar(Result),
+ OutputLength, nil, nil);
+ end;
+end;
+
+function StrContactProtoToInt(Proto: AnsiString): Integer;
+var
+ ProtoType: Integer;
+begin
+ {
+ 0 - ICQ
+ 1 - Google Talk
+ 2 - MRA
+ 3 - Jabber
+ 4 - QIP.Ru
+ 5 - Facebook
+ 6 - VKontacte
+ 7 - Twitter
+ 8 - Social (LiveJournal)
+ 9 - AIM
+ 10 - IRC
+ 11 - MSN
+ 12 - YAHOO
+ 13 - GADU
+ 14 - SKYPE
+ 15 - MetaContacts
+ 16 - Unknown
+ }
+ if MatchStrings(LowerCase(Proto), 'icq*') then
+ ProtoType := 0
+ else if MatchStrings(LowerCase(Proto), 'google talk*') then
+ ProtoType := 1
+ else if MatchStrings(LowerCase(Proto), 'mrad*') then
+ ProtoType := 15
+ else if MatchStrings(LowerCase(Proto), 'mra*') then
+ ProtoType := 2
+ else if MatchStrings(LowerCase(Proto), 'jabber*') then
+ ProtoType := 3
+ else if (LowerCase(Proto) = 'qip.ru') then
+ ProtoType := 4
+ else if MatchStrings(LowerCase(Proto), 'facebook*') then
+ ProtoType := 5
+ else if MatchStrings(LowerCase(Proto), 'vkontakte*') then
+ ProtoType := 6
+ else if MatchStrings(LowerCase(Proto), '*') then
+ ProtoType := 6
+ else if MatchStrings(LowerCase(Proto), 'twitter*') then
+ ProtoType := 7
+ else if MatchStrings(LowerCase(Proto), 'livejournal*') then
+ ProtoType := 8
+ else if MatchStrings(LowerCase(Proto), 'aim*') then
+ ProtoType := 9
+ else if MatchStrings(LowerCase(Proto), 'irc*') then
+ ProtoType := 10
+ else if MatchStrings(LowerCase(Proto), 'msn*') then
+ ProtoType := 11
+ else if MatchStrings(LowerCase(Proto), 'yahoo*') then
+ ProtoType := 12
+ else if MatchStrings(LowerCase(Proto), 'gadu*') then
+ ProtoType := 13
+ else if MatchStrings(LowerCase(Proto), 'skype*') then
+ ProtoType := 14
+ else if MatchStrings(LowerCase(Proto), 'metacontacts*') then
+ ProtoType := 15
+ else
+ ProtoType := 16;
+ Result := ProtoType;
+end;
+
+{ }
+procedure IMDelay(Value: Cardinal);
+var
+ F, N: Cardinal;
+begin
+ N := 0;
+ while N <= (Value div 10) do
+ begin
+ SleepEx(1, True);
+ //Application.ProcessMessages;
+ Inc(N);
+ end;
+ F := GetTickCount;
+ repeat
+ //Application.ProcessMessages;
+ N := GetTickCount;
+ until (N - F >= (Value mod 10)) or (N < F);
+end;
+
+function Utf8ToWideChar(Dest: PWideChar; MaxDestChars: Integer; Source: PAnsiChar; SourceBytes: Integer; CodePage: Cardinal = CP_ACP): Integer;
+const
+ MB_ERR_INVALID_CHARS = 8;
+var
+ Src,SrcEnd: PAnsiChar;
+ Dst,DstEnd: PWideChar;
+begin
+ if (Source = nil) or (SourceBytes <= 0) then
+ begin
+ Result := 0;
+ end
+ else if (Dest = nil) or (MaxDestChars <= 0) then
+ begin
+ Result := -1;
+ end
+ else
+ begin
+ Src := Source;
+ SrcEnd := Source + SourceBytes;
+ Dst := Dest;
+ DstEnd := Dst + MaxDestChars;
+ while (PAnsiChar(Src) < PAnsiChar(SrcEnd)) and (Dst < DstEnd) do
+ begin
+ if (Byte(Src[0]) and $80) = 0 then
+ begin
+ Dst[0] := WideChar(Src[0]);
+ Inc(Src);
+ end
+ else if (Byte(Src[0]) and $E0) = $E0 then
+ begin
+ if Src + 2 >= SrcEnd then
+ break;
+ if (Src[1] = #0) or ((Byte(Src[1]) and $C0) <> $80) then
+ break;
+ if (Src[2] = #0) or ((Byte(Src[2]) and $C0) <> $80) then
+ break;
+ Dst[0] := WideChar(((Byte(Src[0]) and $0F) shl 12) + ((Byte(Src[1]) and $3F) shl 6) +
+ ((Byte(Src[2]) and $3F)));
+ Inc(Src, 3);
+ end
+ else if (Byte(Src[0]) and $E0) = $C0 then
+ begin
+ if Src + 1 >= SrcEnd then
+ break;
+ if (Src[1] = #0) or ((Byte(Src[1]) and $C0) <> $80) then
+ break;
+ Dst[0] := WideChar(((Byte(Src[0]) and $1F) shl 6) + ((Byte(Src[1]) and $3F)));
+ Inc(Src, 2);
+ end
+ else
+ begin
+ if MultiByteToWideChar(CodePage, MB_ERR_INVALID_CHARS, Src, 1, Dst, 1) = 0 then
+ Dst[0] := '?';
+ Inc(Src);
+ end;
+ Inc(Dst);
+ end;
+ Dst[0] := #0;
+ Inc(Dst);
+ Result := Dst - Dest;
+ end;
+end;
+
+// Unix Timestamp
+function UnixToLocalTime(tUnix :Longint): TDateTime;
+var
+ TimeZone :TTimeZoneInformation;
+ Bias :Integer;
+begin
+ if (GetTimeZoneInformation(TimeZone) = TIME_ZONE_ID_DAYLIGHT) then
+ Bias := TimeZone.Bias + TimeZone.DaylightBias
+ else
+ Bias := TimeZone.Bias + TimeZone.StandardBias;
+ Result := EncodeDate(1970,1,1) - Bias / 1440 + tUnix / 86400;
+end;
+
+{ }
+procedure CoreLanguageChanged;
+var
+ LangFile: String;
+begin
+ if CoreLanguage = '' then
+ Exit;
+ try
+ LangFile := PluginPath + dirLangs + CoreLanguage + '.xml';
+ if FileExists(LangFile) then
+ LangDoc.LoadFromFile(LangFile)
+ else
+ begin
+ if FileExists(PluginPath + dirLangs + defaultLangFile) then
+ LangDoc.LoadFromFile(PluginPath + dirLangs + defaultLangFile)
+ else
+ begin
+ MsgDie(htdPluginShortName, 'Not found any language file!');
+ Exit;
+ end;
+ end;
+ SendMessage(AboutFormHandle, WM_LANGUAGECHANGED, 0, 0);
+ SendMessage(ExportFormHandle, WM_LANGUAGECHANGED, 0, 0);
+ except
+ on E: Exception do
+ begin
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - Error on CoreLanguageChanged: ' + Trim(E.Message) + ' | CoreLanguage: ' + CoreLanguage, 2);
+ MsgDie(htdPluginShortName, 'Error on CoreLanguageChanged: ' + E.Message + sLineBreak +
+ 'CoreLanguage: ' + CoreLanguage);
+ end;
+ end;
+end;
+
+{ }
+function GetUserTempPath: WideString;
+var
+ UserPath: WideString;
+begin
+ Result := '';
+ SetLength(UserPath, MAX_PATH);
+ GetTempPath(MAX_PATH, PChar(UserPath));
+ GetLongPathName(PChar(UserPath), PChar(UserPath), MAX_PATH);
+ SetLength(UserPath, StrLen(PChar(UserPath)));
+ Result := UserPath;
+end;
+
+begin
+ hppVersionStr := AnsiString(Format('%d.%d.%d.%d',[htdVerMajor,htdVerMinor,htdVerRelease,htdVerBuild]));
+end.
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas
new file mode 100644
index 0000000000..6747ee346d
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Global.pas
@@ -0,0 +1,1583 @@
+{ ################################################################################ }
+{ # # }
+{ # IM-History - HistoryToDBUpdater v1.0 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ################################################################################ }
+
+unit Global;
+
+{$I jedi.inc}
+
+interface
+
+uses
+ Windows, Forms, Classes, SysUtils, IniFiles, DCPcrypt2, DCPblockciphers, DCPsha1,
+ DCPdes, DCPmd5, TypInfo, Messages, XMLIntf, XMLDoc, StrUtils, Types, TLHELP32, PsAPI, NTNative;
+
+type
+ TWinVersion = (wvUnknown,wv95,wv98,wvME,wvNT3,wvNT4,wvW2K,wvXP,wv2003,wvVista,wv7,wv2008,wv8);
+ TCopyDataType = (cdtString = 0, cdtImage = 1, cdtRecord = 2);
+ TDelim = set of Char;
+ TArrayOfString = Array of String;
+ TArrayOfCardinal = Array of Cardinal;
+ TProcessInfo = packed record
+ ProcessName: String;
+ PID: DWord;
+ ProcessFullCmd: String;
+ ProcessPath: String;
+ ProcessParamCmd: String;
+ end;
+ TProcessInfoArray = Array of TProcessInfo;
+
+const
+ ProgramsName = 'HistoryToDBUpdater';
+ ProgramsVer : WideString = '2.5.0.0';
+ DefaultDBAddres = 'db01.im-history.ru';
+ DefaultDBName = 'imhistory';
+ ININame = 'HistoryToDB.ini';
+ ErrLogName = 'HistoryToDBUpdaterErr.log';
+ DebugLogName = 'HistoryToDBUpdaterDebug.log';
+ // (01/01/1970) Unix Timestamp
+ UnixStartDate: TDateTime = 25569.0;
+ // DBPasswd
+ EncryptKey = 'jsU6s2msoxghsKsn7';
+ //
+ WM_LANGUAGECHANGED = WM_USER + 1;
+ dirLangs = 'langs\';
+ dirSQLUpdate = 'update\';
+ defaultLangFile = 'English.xml';
+ // End
+ WM_MSGBOX = WM_USER + 2;
+ uURL = 'http://im-history.ru/update/get.php?file=HistoryToDB-Update';
+ {$IFDEF WIN32}
+ PlatformType = 'x86';
+ {$ELSE}
+ PlatformType = 'x64';
+ {$ENDIF}
+var
+ WriteErrLog: Boolean;
+ EnableDebug, AlphaBlendEnable: Boolean;
+ MaxErrLogSize, AlphaBlendEnableValue: Integer;
+ DBType, DefaultLanguage, IMClientType: String;
+ PluginPath, ProfilePath: WideString;
+ Global_MainForm_Showing, Global_AboutForm_Showing: Boolean;
+ Global_IMProcessPID: DWORD;
+ //
+ IMUseProxy, IMProxyAuth: Boolean;
+ IMProxyAddress, IMProxyPort, IMProxyUser, IMProxyUserPagsswd: String;
+ DBUserName, MyAccount: String;
+ IMClientPlatformType: String;
+ UpdateServer: String;
+ //
+ Cipher: TDCP_3des;
+ Digest: Array[0..19] of Byte;
+ Hash: TDCP_sha1;
+ //
+ CoreLanguage: String;
+ MainFormHandle: HWND;
+ AboutFormHandle: HWND;
+ LangDoc: IXMLDocument;
+
+function BoolToIntStr(Bool: Boolean): String;
+function IsNumber(const S: String): Boolean;
+function DateTimeToUnix(ConvDate: TDateTime): Longint;
+function UnixToDateTime(USec: Longint): TDateTime;
+function PrepareString(const Source : PWideChar) : AnsiString;
+function EncryptStr(const Str: String): String;
+function DecryptStr(const Str: String): String;
+function EncryptMD5(Str: String): String;
+function MatchStrings(source, pattern: String): Boolean;
+function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String;
+function ReadCustomINI(INIPath, CustomSection, CustomParams, DefaultParamsStr: String): String;
+function GetSystemDefaultUILanguage: UINT; stdcall; external kernel32 name 'GetSystemDefaultUILanguage';
+function GetSysLang: AnsiString;
+function Tok(Sep: String; var S: String): String;
+function GetMyFileSize(const Path: String): Integer;
+function SearchMainWindow(MainWindowName: pWideChar): Boolean;
+function StrContactProtoToInt(Proto: AnsiString): Integer;
+function IsProcessRun(ProcessName: String): Boolean; overload;
+function IsProcessRun(ProcessName, WinCaption: String): Boolean; overload;
+function GetProcessID(ExeFileName: String): Cardinal;
+//function GetProcessIDMulti(ExeFileName: String): TArrayOfString;
+function GetProcessIDMulti2(ExeFileName: String): TArrayOfCardinal;
+function GetThreadsOfProcess(APID: Cardinal): TIntegerDynArray;
+function KillTask(ExeFileName: String): Integer; overload;
+function KillTask(ExeFileName, WinCaption: String): Integer; overload;
+function ProcessTerminate(dwPID: Cardinal): Boolean;
+function ProcCloseEnum(hwnd: THandle; data: Pointer):BOOL;stdcall;
+function ProcQuitEnum(hwnd: THandle; data: Pointer):BOOL;stdcall;
+function GetProcessFileName(PID: DWord; FullPath: Boolean=True): String;
+function GetProcessCmdLine(dwProcessId : DWORD): String;
+function SetProcessDebugPrivelege: Boolean;
+function EndProcess(IMClientExeName: String; EndType: Integer; EndProcess: Boolean): TProcessInfoArray;
+function GetUserTempPath: WideString;
+//function ProcGetCaptionForHandleEnum(hwnd: THandle; data: Pointer):BOOL;stdcall;
+function EnumThreadWndProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
+function StringToParts(sString:String; tdDelim:TDelim): TArrayOfString;
+function ExtractWord(const AString: string; const ADelimiter: Char; const ANumber: integer): string;
+procedure EncryptInit;
+procedure EncryptFree;
+procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer);
+procedure LoadINI(INIPath: String; NotSettingsForm: Boolean);
+procedure WriteCustomINI(INIPath, CustomSection, CustomParams, ParamsStr: String);
+procedure MakeTransp(winHWND: HWND);
+procedure OnSendMessageToAllComponent(Msg: String);
+procedure IMDelay(Value: Cardinal);
+procedure OnSendMessageToOneComponent(WinName, Msg: String);
+function DetectWinVersion: TWinVersion;
+function DetectWinVersionStr: String;
+//
+procedure MsgDie(Caption, Msg: WideString);
+procedure MsgInf(Caption, Msg: WideString);
+function GetLangStr(StrID: String): WideString;
+
+implementation
+
+function BoolToIntStr(Bool: Boolean): String;
+begin
+ if Bool then
+ Result := '1'
+ else
+ Result := '0'
+end;
+
+function IsNumber(const S: string): Boolean;
+begin
+ Result := True;
+ try
+ StrToInt(S);
+ except
+ Result := False;
+ end;
+end;
+
+// DateTime Unix Timestamp
+function DateTimeToUnix(ConvDate: TDateTime): Longint;
+begin
+ Result := Round((ConvDate - UnixStartDate) * 86400);
+end;
+
+// Unix Timestamp DateTime
+function UnixToDateTime(USec: Longint): TDateTime;
+begin
+ Result := (Usec / 86400) + UnixStartDate;
+end;
+
+//
+function PrepareString(const Source : PWideChar) : AnsiString;
+var
+ SLen,i : Cardinal;
+ WSTmp : WideString;
+ WChar : WideChar;
+begin
+ Result := '';
+ SLen := Length(WideString(Source));
+ if (SLen>0) then
+ begin
+ for i:=1 to SLen do
+ begin
+ WChar:=WideString(Source)[i];
+ case WChar of
+ #$09 :{tab} WSTmp:=WSTmp+'\t';
+ #$0A :{line feed} WSTmp:=WSTmp+'\n';
+ #$0D :{carriage return} WSTmp:=WSTmp+'\r';
+ #$27 :{single quote mark aka apostrophe?} WSTmp:=WSTmp+WChar+WChar;
+ #$22, {double quote mark aka inch sign?}
+ #$5C, {backslash itself}
+ #$60 :{another single quote mark} WSTmp:=WSTmp+'\'+WChar;
+ else WSTmp := WSTmp + WChar;
+ end;
+ end;
+ Result := AnsiString(WSTmp);
+ end;
+end;
+
+//
+procedure EncryptInit;
+begin
+ Hash:= TDCP_sha1.Create(nil);
+ try
+ Hash.Init;
+ Hash.UpdateStr(EncryptKey);
+ Hash.Final(Digest);
+ finally
+ Hash.Free;
+ end;
+ Cipher := TDCP_3des.Create(nil);
+ Cipher.Init(Digest,Sizeof(Digest)*8,nil);
+end;
+
+//
+procedure EncryptFree;
+begin
+ if Assigned(Cipher) then
+ begin
+ Cipher.Burn;
+ Cipher.Free;
+ end;
+end;
+
+//
+function EncryptStr(const Str: String): String;
+begin
+ Result := '';
+ if Str <> '' then
+ begin
+ Cipher.Reset;
+ Result := Cipher.EncryptString(Str);
+ end;
+end;
+
+//
+function DecryptStr(const Str: String): String;
+begin
+ Result := '';
+ if Str <> '' then
+ begin
+ Cipher.Reset;
+ Result := Cipher.DecryptString(Str);;
+ end;
+end;
+
+// MD5
+function EncryptMD5(Str: String): String;
+var
+ Hash: TDCP_md5;
+ Digest: Array[0..15] of Byte;
+ I: Integer;
+ P: String;
+begin
+ if Str <> '' then
+ begin
+ Hash:= TDCP_md5.Create(nil);
+ try
+ Hash.HashSize := 128;
+ Hash.Init;
+ Hash.UpdateStr(Str);
+ Hash.Final(Digest);
+ P := '';
+ for I:= 0 to 15 do
+ P:= P + IntToHex(Digest[I], 2);
+ finally
+ Hash.Free;
+ end;
+ Result := P;
+ end
+ else
+ Result := 'MD5';
+end;
+
+// LogType = 0 - ErrLogName
+// LogType = 1 - DebugLogName
+procedure WriteInLog(LogPath: String; TextString: String; LogType: Integer);
+var
+ Path: WideString;
+ TF: TextFile;
+begin
+ if LogType = 0 then
+ begin
+ Path := LogPath + ErrLogName;
+ if (GetMyFileSize(Path) > MaxErrLogSize*1024) then
+ DeleteFile(Path);
+ end
+ else
+ Path := LogPath + DebugLogName;
+ {$I-}
+ try
+ Assign(TF,Path);
+ if FileExists(Path) then
+ Append(TF)
+ else
+ Rewrite(TF);
+ Writeln(TF,TextString);
+ CloseFile(TF);
+ except
+ on e :
+ Exception do
+ begin
+ CloseFile(TF);
+ Exit;
+ end;
+ end;
+ {$I+}
+end;
+
+//
+procedure LoadINI(INIPath: String; NotSettingsForm: Boolean);
+var
+ Path: WideString;
+ Temp: String;
+ INI: TIniFile;
+begin
+ //
+ if not DirectoryExists(INIPath) then
+ CreateDir(INIPath);
+ Path := INIPath + ININame;
+ if FileExists(Path) then
+ begin
+ INI := TIniFile.Create(Path);
+ try
+ DBType := INI.ReadString('Main', 'DBType', 'Unknown');
+ DBUserName := INI.ReadString('Main', 'DBUserName', 'username');
+ DefaultLanguage := INI.ReadString('Main', 'DefaultLanguage', 'English');
+ IMClientType := INI.ReadString('Main', 'IMClientType', 'Unknown');
+ MyAccount := INI.ReadString('Main', 'MyAccount', DBUserName);
+
+ Temp := INI.ReadString('Main', 'WriteErrLog', '0');
+ if Temp = '1' then WriteErrLog := True
+ else WriteErrLog := False;
+
+ MaxErrLogSize := INI.ReadInteger('Main', 'MaxErrLogSize', 20);
+
+ Temp := INI.ReadString('Main', 'EnableDebug', '0');
+ if Temp = '1' then EnableDebug := True
+ else EnableDebug := False;
+
+ Temp := INI.ReadString('Main', 'AlphaBlend', '0');
+ if Temp = '1' then AlphaBlendEnable := True
+ else AlphaBlendEnable := False;
+ AlphaBlendEnableValue := INI.ReadInteger('Main', 'AlphaBlendValue', 255);
+
+ Temp := INI.ReadString('Proxy', 'UseProxy', '0');
+ if Temp = '1' then IMUseProxy := True
+ else IMUseProxy := False;
+
+ IMProxyAddress := INI.ReadString('Proxy', 'ProxyAddress', '127.0.0.1');
+ IMProxyPort := INI.ReadString('Proxy', 'ProxyPort', '3128');
+
+ Temp := INI.ReadString('Proxy', 'ProxyAuth', '0');
+ if Temp = '1' then IMProxyAuth := True
+ else IMProxyAuth := False;
+
+ IMProxyUser := INI.ReadString('Proxy', 'ProxyUser', '');
+ IMProxyUserPagsswd := INI.ReadString('Proxy', 'ProxyUserPasswd', '');
+ if IMProxyUserPagsswd <> '' then
+ IMProxyUserPagsswd := DecryptStr(IMProxyUserPagsswd);
+
+ IMClientPlatformType := INI.ReadString('Main', 'IMClientPlatformType', PlatformType);
+ UpdateServer := INI.ReadString('Updater', 'UpdateServer', uURL);
+ finally
+ INI.Free;
+ end;
+ end
+ else
+ begin
+ INI := TIniFile.Create(path);
+ try
+ // -
+ DBType := 'Unknown';
+ DefaultLanguage := 'English';
+ IMClientType := 'Unknown';
+ WriteErrLog := True;
+ MaxErrLogSize := 20;
+ EnableDebug := False;
+ AlphaBlendEnable := False;
+ AlphaBlendEnableValue := 255;
+ IMUseProxy := False;
+ IMProxyAddress := '127.0.0.1';
+ IMProxyPort := '3128';
+ IMProxyAuth := False;
+ IMProxyUser := '';
+ IMProxyUserPagsswd := '';
+ //
+ INI.WriteString('Main', 'DBType', DBType);
+ INI.WriteString('Main', 'DefaultLanguage', DefaultLanguage);
+ INI.WriteString('Main', 'IMClientType', IMClientType);
+ INI.WriteString('Main', 'WriteErrLog', BoolToIntStr(WriteErrLog));
+ INI.WriteInteger('Main', 'MaxErrLogSize', MaxErrLogSize);
+ INI.WriteString('Main', 'EnableDebug', BoolToIntStr(EnableDebug));
+ INI.WriteString('Main', 'AlphaBlend', BoolToIntStr(AlphaBlendEnable));
+ INI.WriteInteger('Main', 'AlphaBlendValue', AlphaBlendEnableValue);
+ INI.WriteString('Proxy', 'UseProxy', BoolToIntStr(IMUseProxy));
+ INI.WriteString('Proxy', 'ProxyAddress', IMProxyAddress);
+ INI.WriteString('Proxy', 'ProxyPort', IMProxyPort);
+ INI.WriteString('Proxy', 'ProxyAuth', BoolToIntStr(IMProxyAuth));
+ INI.WriteString('Proxy', 'ProxyUser', IMProxyUser);
+ INI.WriteString('Proxy', 'ProxyUserPasswd', IMProxyUserPagsswd);
+ INI.WriteString('Updater', 'UpdateServer', uURL);
+ finally
+ INI.Free;
+ end;
+ end;
+end;
+
+{ .
+ , (* ?).
+ ( ) .
+ : MatchStrings('David Stidolph','*St*') True.
+ C- Sean Stanley
+ Delphi David Stidolph}
+function MatchStrings(source, pattern: String): Boolean;
+var
+ pSource: array[0..255] of Char;
+ pPattern: array[0..255] of Char;
+
+ function MatchPattern(element, pattern: PChar): Boolean;
+
+ function IsPatternWild(pattern: PChar): Boolean;
+ begin
+ Result := StrScan(pattern, '*') <> nil;
+ if not Result then
+ Result := StrScan(pattern, '?') <> nil;
+ end;
+
+ begin
+ if 0 = StrComp(pattern, '*') then
+ Result := True
+ else if (element^ = Chr(0)) and (pattern^ <> Chr(0)) then
+ Result := False
+ else if element^ = Chr(0) then
+ Result := True
+ else
+ begin
+ case pattern^ of
+ '*': if MatchPattern(element, @pattern[1]) then
+ Result := True
+ else
+ Result := MatchPattern(@element[1], pattern);
+ '?': Result := MatchPattern(@element[1], @pattern[1]);
+ else
+ if element^ = pattern^ then
+ Result := MatchPattern(@element[1], @pattern[1])
+ else
+ Result := False;
+ end;
+ end;
+ end;
+begin
+ StrPCopy(pSource, source);
+ StrPCopy(pPattern, pattern);
+ Result := MatchPattern(pSource, pPattern);
+end;
+
+{ .
+ , .
+ :
+ FileName - ,
+ ShowExtension - TRUE,
+ ( ), , ,
+ , . }
+function ExtractFileNameEx(FileName: String; ShowExtension: Boolean): String;
+var
+ I: Integer;
+ S, S1: string;
+begin
+ I := Length(FileName);
+ if I <> 0 then
+ begin
+ while (FileName[i] <> '\') and (i > 0) do
+ i := i - 1;
+ S := Copy(FileName, i + 1, Length(FileName) - i);
+ i := Length(S);
+ if i = 0 then
+ begin
+ Result := '';
+ Exit;
+ end;
+ while (S[i] <> '.') and (i > 0) do
+ i := i - 1;
+ S1 := Copy(S, 1, i - 1);
+ if s1 = '' then
+ s1 := s;
+ if ShowExtension = True then
+ Result := s
+ else
+ Result := s1;
+ end
+ else
+ Result := '';
+end;
+
+{ MessageBox }
+procedure MakeTransp(winHWND: HWND);
+var
+ exStyle: Longint;
+begin
+ exStyle := GetWindowLong(winHWND, GWL_EXSTYLE);
+ if (exStyle and WS_EX_LAYERED = 0) then
+ begin
+ exStyle := exStyle or WS_EX_LAYERED;
+ SetwindowLong(winHWND, GWL_EXSTYLE, exStyle);
+ end;
+ SetLayeredWindowAttributes(winHWND, 0, AlphaBlendEnableValue, LWA_ALPHA);
+end;
+
+//
+procedure MsgDie(Caption, Msg: WideString);
+begin
+ if AlphaBlendEnable then
+ PostMessage(GetForegroundWindow, WM_USER + 2, 0, 0);
+ MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONERROR);
+end;
+
+//
+procedure MsgInf(Caption, Msg: WideString);
+begin
+ if AlphaBlendEnable then
+ PostMessage(GetForegroundWindow, WM_USER + 2, 0, 0);
+ MessageBoxW(GetForegroundWindow, PWideChar(Msg), PWideChar(Caption), MB_ICONINFORMATION);
+end;
+
+//
+function GetLangStr(StrID: String): WideString;
+begin
+ if (not Assigned(LangDoc)) or (not LangDoc.Active) then
+ begin
+ Result := '';
+ Exit;
+ end;
+ if LangDoc.ChildNodes['strings'].ChildNodes.FindNode(StrID) <> nil then
+ Result := LangDoc.ChildNodes['strings'].ChildNodes[StrID].Text
+ else
+ Result := 'String not found.';
+end;
+
+function GetSysLang: AnsiString;
+var
+ WinLanguage: Array [0..50] of Char;
+begin
+ //Result := Lo(GetSystemDefaultUILanguage);
+ VerLanguageName(GetSystemDefaultLangID, WinLanguage, 50);
+ Result := StrPas(WinLanguage);
+end;
+
+{ S , -,
+ Sep. ,
+ S }
+function Tok(Sep: String; var S: String): String;
+
+ function isoneof(c, s: string): Boolean;
+ var
+ iTmp: integer;
+ begin
+ Result := False;
+ for iTmp := 1 to Length(s) do
+ begin
+ if c = Copy(s, iTmp, 1) then
+ begin
+ Result := True;
+ Exit;
+ end;
+ end;
+ end;
+
+var
+ c, t: String;
+begin
+ if s = '' then
+ begin
+ Result := s;
+ Exit;
+ end;
+ c := Copy(s, 1, 1);
+ while isoneof(c, sep) do
+ begin
+ s := Copy(s, 2, Length(s) - 1);
+ c := Copy(s, 1, 1);
+ end;
+ t := '';
+ while (not isoneof(c, sep)) and (s <> '') do
+ begin
+ t := t + c;
+ s := Copy(s, 2, length(s) - 1);
+ c := Copy(s, 1, 1);
+ end;
+ Result := t;
+end;
+
+{ }
+procedure WriteCustomINI(INIPath, CustomSection, CustomParams, ParamsStr: String);
+var
+ Path: String;
+ IsFileClosed: Boolean;
+ sFile: DWORD;
+ INI: TIniFile;
+begin
+ Path := INIPath + ININame;
+ if FileExists(Path) then
+ begin
+ // -
+ IsFileClosed := False;
+ repeat
+ sFile := CreateFile(PChar(Path),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
+ if (sFile <> INVALID_HANDLE_VALUE) then
+ begin
+ CloseHandle(sFile);
+ IsFileClosed := True;
+ end;
+ until IsFileClosed;
+ // End
+ INI := TIniFile.Create(Path);
+ try
+ INI.WriteString(CustomSection, CustomParams, ParamsStr);
+ finally
+ INI.Free;
+ end;
+ end
+ else
+ MsgDie(ProgramsName, GetLangStr('SettingsErrSave'));
+end;
+
+{ }
+function ReadCustomINI(INIPath, CustomSection, CustomParams, DefaultParamsStr: String): String;
+var
+ Path: String;
+ INI: TIniFile;
+begin
+ Path := INIPath + ININame;
+ INI := TIniFile.Create(Path);
+ if FileExists(Path) then
+ begin
+ try
+ Result := INI.ReadString(CustomSection, CustomParams, DefaultParamsStr);
+ finally
+ INI.Free;
+ end;
+ end
+ else
+ MsgDie(ProgramsName, GetLangStr('SettingsErrRead'));
+end;
+
+// , -1
+function GetMyFileSize(const Path: String): Integer;
+var
+ FD: TWin32FindData;
+ FH: THandle;
+begin
+ FH := FindFirstFile(PChar(Path), FD);
+ Result := 0;
+ if FH = INVALID_HANDLE_VALUE then
+ Exit;
+ Result := FD.nFileSizeLow;
+ if ((FD.nFileSizeLow and $80000000) <> 0) or
+ (FD.nFileSizeHigh <> 0) then
+ Result := -1;
+ //FindClose(FH);
+end;
+
+{ }
+function SearchMainWindow(MainWindowName: pWideChar): Boolean;
+var
+ HToDB: HWND;
+begin
+ //
+ HToDB := FindWindow(nil, MainWindowName);
+ if HToDB <> 0 then
+ Result := True
+ else
+ Result := False
+end;
+
+{ }
+{ :
+ 001 - HistoryToDB.ini
+ 002 -
+ 003 -
+ 0040 - ( AntiBoss)
+ 0041 - ( AntiBoss)
+ 0050 - MD5-
+ 0051 - MD5-
+ 0060 -
+ 0061 -
+ 007 - -
+ 008 - /
+ :
+ :
+ 008|0|UserID|UserName|ProtocolType
+ :
+ 008|2|ChatName
+ 009 - .
+}
+procedure OnSendMessageToAllComponent(Msg: String);
+var
+ HToDB: HWND;
+ copyDataStruct : TCopyDataStruct;
+ EncryptMsg, WinName: String;
+begin
+ EncryptMsg := EncryptStr(Msg);
+ WinName := 'HistoryToDBViewer for ' + IMClientType;
+ // HistoryToDBViewer
+ HToDB := FindWindow(nil, pChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := Integer(cdtString);
+ copyDataStruct.cbData := 2*Length(EncryptMsg);
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct));
+ end;
+ WinName := 'HistoryToDBSync for ' + IMClientType;
+ // HistoryToDBSync
+ HToDB := FindWindow(nil, pChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := Integer(cdtString);
+ copyDataStruct.cbData := 2*Length(EncryptMsg);
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct));
+ end;
+ WinName := 'HistoryToDBImport for ' + IMClientType;
+ // HistoryToDBImport
+ HToDB := FindWindow(nil, pChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := Integer(cdtString);
+ copyDataStruct.cbData := 2*Length(EncryptMsg);
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct));
+ end;
+end;
+
+procedure OnSendMessageToOneComponent(WinName, Msg: String);
+var
+ HToDB: HWND;
+ copyDataStruct : TCopyDataStruct;
+ EncryptMsg: String;
+begin
+ EncryptMsg := EncryptStr(Msg);
+ // HistoryToDBViewer
+ HToDB := FindWindow(nil, pChar(WinName));
+ if HToDB <> 0 then
+ begin
+ copyDataStruct.dwData := Integer(cdtString);
+ copyDataStruct.cbData := 2*Length(EncryptMsg);
+ copyDataStruct.lpData := PChar(EncryptMsg);
+ SendMessage(HToDB, WM_COPYDATA, 0, Integer(@copyDataStruct));
+ end;
+end;
+
+function StrContactProtoToInt(Proto: AnsiString): Integer;
+var
+ ProtoType: Integer;
+begin
+ {
+ 0 - ICQ
+ 1 - Google Talk
+ 2 - MRA
+ 3 - Jabber
+ 4 - QIP.Ru
+ 5 - Facebook
+ 6 - VKontacte
+ 7 - Twitter
+ 8 - Social (LiveJournal)
+ 9 - AIM
+ 10 - IRC
+ 11 - MSN
+ 12 - YAHOO
+ 13 - GADU
+ 14 - SKYPE
+ 15 - Unknown
+ }
+ if MatchStrings(LowerCase(Proto), 'icq*') then
+ ProtoType := 0
+ else if MatchStrings(LowerCase(Proto), 'google talk*') then
+ ProtoType := 1
+ else if MatchStrings(LowerCase(Proto), 'mra*') then
+ ProtoType := 2
+ else if MatchStrings(LowerCase(Proto), 'jabber*') then
+ ProtoType := 3
+ else if (LowerCase(Proto) = 'qip.ru') then
+ ProtoType := 4
+ else if MatchStrings(LowerCase(Proto), 'facebook*') then
+ ProtoType := 5
+ else if MatchStrings(LowerCase(Proto), 'vkontakte*') then
+ ProtoType := 6
+ else if MatchStrings(Proto, '*') then
+ ProtoType := 6
+ else if MatchStrings(Proto, '*') then
+ ProtoType := 6
+ else if MatchStrings(LowerCase(Proto), 'twitter*') then
+ ProtoType := 7
+ else if MatchStrings(LowerCase(Proto), 'livejournal*') then
+ ProtoType := 8
+ else if MatchStrings(LowerCase(Proto), 'aim*') then
+ ProtoType := 9
+ else if MatchStrings(LowerCase(Proto), 'irc*') then
+ ProtoType := 10
+ else if MatchStrings(LowerCase(Proto), 'msn*') then
+ ProtoType := 11
+ else if MatchStrings(LowerCase(Proto), 'yahoo*') then
+ ProtoType := 12
+ else if MatchStrings(LowerCase(Proto), 'gadu*') then
+ ProtoType := 13
+ else if MatchStrings(LowerCase(Proto), 'skype*') then
+ ProtoType := 14
+ else
+ ProtoType := 15;
+ Result := ProtoType;
+end;
+
+{ }
+procedure IMDelay(Value: Cardinal);
+var
+ F, N: Cardinal;
+begin
+ N := 0;
+ while N <= (Value div 10) do
+ begin
+ SleepEx(1, True);
+ Application.ProcessMessages;
+ Inc(N);
+ end;
+ F := GetTickCount;
+ repeat
+ Application.ProcessMessages;
+ N := GetTickCount;
+ until (N - F >= (Value mod 10)) or (N < F);
+end;
+
+{ WM_CLOSE PID }
+function ProcCloseEnum(hwnd: THandle; data: Pointer):BOOL;stdcall;
+var
+ Pid: DWORD;
+begin
+ Result := True;
+ GetWindowThreadProcessId(hwnd, pid);
+ if Pid = DWORD(data) then
+ begin
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ end;
+end;
+
+{ WM_QUIT PID }
+function ProcQuitEnum(hwnd: THandle; data: Pointer):BOOL;stdcall;
+var
+ Pid: DWORD;
+begin
+ Result := True;
+ GetWindowThreadProcessId(hwnd, pid);
+ if Pid = DWORD(data) then
+ begin
+ PostMessage(hwnd, WM_QUIT, 0, 0);
+ end;
+end;
+
+{function ProcGetCaptionForHandleEnum(hwnd: THandle; data: Pointer):BOOL;stdcall;
+var
+ Pid: DWORD;
+ WinCaption: Array [0 .. 255] of Char;
+begin
+ Result := True;
+ GetWindowThreadProcessId(hwnd, pid);
+ if Pid = DWORD(data) then
+ begin
+ //PostMessage(hwnd, WM_QUIT, 0, 0);
+ GetWindowText(hwnd, WinCaption, SizeOf(WinCaption));
+ if WinCaption <> '' then
+ MsgInf('ProcGetCaptionForHandleEnum', WinCaption);
+ end;
+end;}
+
+{ WM_QUIT
+ TArrayOfString +
+
+ EndType = 0 - WM_CLOSE
+ EndType = 1 - WM_QUIT
+ }
+function EndProcess(IMClientExeName: String; EndType: Integer; EndProcess: Boolean): TProcessInfoArray;
+var
+ I: Integer;
+ ProcessPIDListArray: TArrayOfCardinal;
+ MyFullCMD, MyCMD, ProcessCmdLine: String;
+begin
+ SetLength(Result, 0);
+ SetLength(ProcessPIDListArray, 0);
+ ProcessPIDListArray := GetProcessIDMulti2(IMClientExeName);
+ for I := 0 to High(ProcessPIDListArray) do
+ begin
+ SetLength(Result, Length(Result)+1);
+ Result[Length(Result)-1].ProcessName := IMClientExeName;
+ Result[Length(Result)-1].PID := ProcessPIDListArray[I];
+ ProcessCmdLine := GetProcessCmdLine(ProcessPIDListArray[I]);
+ if ProcessCmdLine = '' then
+ begin
+
+ if (IMClientExeName = 'qip.exe') and (DetectWinVersionStr = 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\QIP 2012\qip.exe"'
+ else if (IMClientExeName = 'qip.exe') and (DetectWinVersionStr <> 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files (x86)\QIP 2012\qip.exe"'
+
+ else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr = 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\Miranda IM\miranda32.exe"'
+ else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr <> 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files (x86)\Miranda IM\miranda32.exe"'
+ else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr = 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\Miranda IM\miranda32.exe"'
+ else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'Miranda') and (DetectWinVersionStr <> 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\Miranda IM\miranda32.exe"'
+
+ else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr = 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\Miranda NG\miranda32.exe"'
+ else if (IMClientExeName = 'miranda32.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr <> 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files (x86)\Miranda NG\miranda32.exe"'
+ else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr = 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\Miranda NG\miranda32.exe"'
+ else if (IMClientExeName = 'miranda64.exe') and (IMClientType = 'MirandaNG') and (DetectWinVersionStr <> 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\Miranda NG\miranda32.exe"'
+
+ else if (IMClientExeName = 'skype.exe') and (DetectWinVersionStr = 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files (x86)\Skype\Phone\skype.exe"'
+ else if (IMClientExeName = 'skype.exe') and (DetectWinVersionStr <> 'Windows 7') then
+ ProcessCmdLine := '"C:\Program Files\Skype\Phone\skype.exe"'
+ else
+ ProcessCmdLine := IMClientExeName;
+ end;
+ Result[Length(Result)-1].ProcessFullCmd := ProcessCmdLine;
+ //MsgInf('EndProcess', 'ProcessName: ' + Result[Length(Result)-1].ProcessName + #13 + 'PID: ' + IntToStr(Result[Length(Result)-1].PID) + #13 + 'ProcessFullCmd: ' + Result[Length(Result)-1].ProcessFullCmd);
+ //Result[Length(Result)-1] := GetProcessFileName(StrToInt(ProcessListArray[I]), True);
+ // CMD
+ // "C:/Program Files/PostgreSQL/9.1/bin/postgres.exe" "--forklog" "244" "248"
+ //
+ // "C:\Program Files\Microsoft Firewall Client 2004\FwcAgent.exe"
+ if Result[Length(Result)-1].ProcessFullCmd[1] = '"' then
+ begin
+ MyFullCMD := Result[Length(Result)-1].ProcessFullCmd;
+ Delete(MyFullCMD, 1, 1);
+ MyCMD := Copy(MyFullCMD, 1, Pos('"', MyFullCMD)-1);
+ Delete(MyFullCMD, 1, Pos('"', MyFullCMD)+1);
+ Result[Length(Result)-1].ProcessPath := MyCMD;
+ Result[Length(Result)-1].ProcessParamCmd := MyFullCMD;
+ end
+ else
+ begin
+ MyFullCMD := Result[Length(Result)-1].ProcessFullCmd;
+ // CMD
+ // C:\WINDOWS\system32\svchost -k DcomLaunch
+ if Pos(' ', MyFullCMD) > 0 then
+ begin
+ MyCMD := Copy(MyFullCMD, 1, Pos(' ', MyFullCMD)-1);
+ Delete(MyFullCMD, 1, Pos(' ', MyFullCMD));
+ Result[Length(Result)-1].ProcessPath := MyCMD;
+ Result[Length(Result)-1].ProcessParamCmd := MyFullCMD;
+ end
+ // CMD
+ // C:\WINDOWS\system32\lsass.exe
+ else
+ begin
+ Result[Length(Result)-1].ProcessPath := MyFullCMD;
+ Result[Length(Result)-1].ProcessParamCmd := '';
+ end;
+ end;
+ //
+ if EndProcess then
+ begin
+ if EndType = 0 then //WM_CLOSE
+ EnumWindows(@ProcCloseEnum, ProcessPIDListArray[I])
+ else //WM_QUIT
+ EnumWindows(@ProcQuitEnum, ProcessPIDListArray[I]);
+ end;
+ end;
+end;
+
+function EnumThreadWndProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
+var
+ WindowClassName: String;
+ WindowClassNameLength: Integer;
+ WinCaption: Array [0 .. 255] of Char;
+ ThreadProcessWinCaption: String;
+ PID: DWORD;
+begin
+ Result := True;
+ ThreadProcessWinCaption := String(LPARAM);
+ GetWindowThreadProcessId(hwnd, pid);
+ SetLength(WindowClassName, MAX_PATH);
+ WindowClassNameLength := GetClassName(hwnd, PChar(WindowClassName), MAX_PATH);
+ GetWindowText(hwnd, WinCaption, SizeOf(WinCaption));
+ if MatchStrings(LeftStr(WindowClassName, WindowClassNameLength), 'TMain*') and (WinCaption = ThreadProcessWinCaption) then
+ begin
+ Global_IMProcessPID := PID;
+ //MsgInf('EnumThreadWndProc', 'PID : ' + IntToStr(PID) + #10#13 + ': ' + LeftStr(WindowClassName, WindowClassNameLength) + #10#13 + ' : ' + WinCaption);
+ end;
+ // .
+ //EnumChildWindows(hwnd, @EnumThreadWndProc, lParam);
+end;
+
+{ ID }
+function GetThreadsOfProcess(APID: Cardinal): TIntegerDynArray;
+var
+ lSnap: DWord;
+ lThread: TThreadEntry32;
+begin
+ Result := nil;
+ if APID <> INVALID_HANDLE_VALUE then
+ begin
+ lSnap := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+ if (lSnap <> INVALID_HANDLE_VALUE) then
+ begin
+ lThread.dwSize := SizeOf(TThreadEntry32);
+ if Thread32First(lSnap, lThread) then
+ repeat
+ if lThread.th32OwnerProcessID = APID then
+ begin
+ SetLength(Result, Length(Result) + 1);
+ Result[High(Result)] := lThread.th32ThreadID;
+ end;
+ until not Thread32Next(lSnap, lThread);
+ CloseHandle(lSnap);
+ end;
+ end;
+end;
+
+{ }
+function IsProcessRun(ProcessName: String): Boolean; overload;
+var
+ Snapshot: THandle;
+ Proc: TProcessEntry32;
+begin
+ Result := False;
+ Snapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if Snapshot = INVALID_HANDLE_VALUE then
+ Exit;
+ Proc.dwSize := SizeOf(TProcessEntry32);
+ if Process32First(Snapshot, Proc) then
+ repeat
+ if Proc.szExeFile = ProcessName then
+ begin
+ Result := True;
+ Break;
+ end;
+ until not Process32Next(Snapshot, Proc);
+ CloseHandle(Snapshot);
+end;
+
+function IsProcessRun(ProcessName, WinCaption: String): Boolean; overload;
+var
+ Snapshot: THandle;
+ Proc: TProcessEntry32;
+ lThreads: TIntegerDynArray;
+ J: Integer;
+begin
+ Result := False;
+ Snapshot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if Snapshot = INVALID_HANDLE_VALUE then
+ Exit;
+ Proc.dwSize := SizeOf(TProcessEntry32);
+ if Process32First(Snapshot, Proc) then
+ repeat
+ if ((UpperCase(ExtractFileName(Proc.szExeFile)) = UpperCase(ProcessName))
+ or (UpperCase(Proc.szExeFile) = UpperCase(ProcessName))) then
+ begin
+ //
+ //EnumWindows(@ProcGetCaptionForHandleEnum, FProcessEntry32.th32ProcessID);
+ // ClassName
+ Global_IMProcessPID := 0;
+ lThreads := GetThreadsOfProcess(Proc.th32ProcessID);
+ for J := Low(lThreads) to High(lThreads) do
+ EnumThreadWindows(lThreads[J], @EnumThreadWndProc, LPARAM(WinCaption));
+ if Global_IMProcessPID = Proc.th32ProcessID then
+ //MsgInf('IsProcessRun', ' ');
+ Result := True;
+ // Ends
+ end;
+ until not Process32Next(Snapshot, Proc);
+ CloseHandle(Snapshot);
+end;
+
+{ }
+function KillTask(ExeFileName: String): Integer;
+const
+ PROCESS_TERMINATE=$0001;
+var
+ ContinueLoop: BOOL;
+ FSnapshotHandle: THandle;
+ FProcessEntry32: TProcessEntry32;
+begin
+ Result := 0;
+ FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
+ ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
+ while Integer(ContinueLoop) <> 0 do
+ begin
+ if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
+ or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
+ Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0),
+ FProcessEntry32.th32ProcessID), 0));
+ ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
+ end;
+ CloseHandle(FSnapshotHandle);
+end;
+
+{ }
+function KillTask(ExeFileName, WinCaption: String): Integer; overload;
+const
+ PROCESS_TERMINATE=$0001;
+var
+ ContinueLoop: BOOL;
+ FSnapshotHandle: THandle;
+ FProcessEntry32: TProcessEntry32;
+ lThreads: TIntegerDynArray;
+ J: Integer;
+begin
+ Result := 0;
+ FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
+ ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
+ while Integer(ContinueLoop) <> 0 do
+ begin
+ if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
+ or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
+ begin
+ //
+ //EnumWindows(@ProcGetCaptionForHandleEnum, FProcessEntry32.th32ProcessID);
+ // ClassName
+ Global_IMProcessPID := 0;
+ lThreads := GetThreadsOfProcess(FProcessEntry32.th32ProcessID);
+ for J := Low(lThreads) to High(lThreads) do
+ EnumThreadWindows(lThreads[J], @EnumThreadWndProc, LPARAM(WinCaption));
+ if Global_IMProcessPID = FProcessEntry32.th32ProcessID then
+ //MsgInf('KillTask', ' ');
+ Result := Integer(TerminateProcess(OpenProcess(PROCESS_TERMINATE, BOOL(0), FProcessEntry32.th32ProcessID), 0));
+ // Ends
+ end;
+ ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
+ end;
+ CloseHandle(FSnapshotHandle);
+end;
+
+{ PID }
+function GetProcessID(ExeFileName: String): Cardinal;
+var
+ ContinueLoop: BOOL;
+ FSnapshotHandle: THandle;
+ FProcessEntry32: TProcessEntry32;
+begin
+ Result := 0;
+ FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
+ ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
+ repeat
+ if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
+ or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
+ begin
+ Result := FProcessEntry32.th32ProcessID;
+ Break;
+ end;
+ ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
+ until not ContinueLoop;
+ CloseHandle(FSnapshotHandle);
+end;
+
+{ PID }
+{function GetProcessIDMulti(ExeFileName: String): TArrayOfString;
+var
+ ContinueLoop: BOOL;
+ FSnapshotHandle: THandle;
+ FProcessEntry32: TProcessEntry32;
+begin
+ SetLength(Result, 0);
+ //Result := 0;
+ FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
+ ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
+ repeat
+ if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
+ or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
+ begin
+ SetLength(Result, Length(Result)+1);
+ Result[Length(Result)-1] := IntToStr(FProcessEntry32.th32ProcessID);
+ end;
+ ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
+ until not ContinueLoop;
+ CloseHandle(FSnapshotHandle);
+end;}
+
+{ PID }
+function GetProcessIDMulti2(ExeFileName: String): TArrayOfCardinal;
+var
+ ContinueLoop: BOOL;
+ FSnapshotHandle: THandle;
+ FProcessEntry32: TProcessEntry32;
+begin
+ SetLength(Result, 0);
+ //Result := 0;
+ FSnapshotHandle := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
+ ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
+ repeat
+ if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(ExeFileName))
+ or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(ExeFileName))) then
+ begin
+ SetLength(Result, Length(Result)+1);
+ Result[Length(Result)-1] := FProcessEntry32.th32ProcessID;
+ end;
+ ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
+ until not ContinueLoop;
+ CloseHandle(FSnapshotHandle);
+end;
+
+{ PID }
+function GetProcessFileName(PID: DWord; FullPath: Boolean=True): String;
+var
+ Handle: THandle;
+begin
+ Result := '';
+ Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
+ try
+ if Handle <> 0 then
+ begin
+ SetLength(Result, MAX_PATH);
+ if FullPath then
+ begin
+ if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
+ SetLength(Result, StrLen(PChar(Result)))
+ else
+ Result := '';
+ end
+ else
+ begin
+ if GetModuleBaseNameA(Handle, 0, PAnsiChar(Result), MAX_PATH) > 0 then
+ SetLength(Result, StrLen(PChar(Result)))
+ else
+ Result := '';
+ end;
+ end;
+ finally
+ CloseHandle(Handle);
+ end;
+end;
+
+{ PID }
+function GetProcessCmdLine(dwProcessId : DWORD): String;
+const
+ STATUS_SUCCESS = $00000000;
+ SE_DEBUG_NAME = 'SeDebugPrivilege';
+ ProcessWow64Information = 26;
+var
+ ProcessHandle : THandle;
+ ProcessBasicInfo : PROCESS_BASIC_INFORMATION;
+ ReturnLength : DWORD;
+ lpNumberOfBytesRead : ULONG_PTR;
+ TokenHandle : THandle;
+ lpLuid : TOKEN_PRIVILEGES;
+ OldlpLuid : TOKEN_PRIVILEGES;
+ Rtl : RTL_USER_PROCESS_PARAMETERS;
+ Peb : _PEB;
+ IsProcessx64 : Boolean;
+ {$IFDEF CPUX64}
+ PEBBaseAddress32 : Pointer;
+ Peb32 : _PEB32;
+ Rtl32 : RTL_USER_PROCESS_PARAMETERS32;
+ {$ENDIF}
+ Ws: WideString;
+begin
+ Result:='';
+ if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle) then
+ begin
+ try
+ if not LookupPrivilegeValue(nil, SE_DEBUG_NAME, lpLuid.Privileges[0].Luid) then
+ RaiseLastOSError
+ else
+ begin
+ lpLuid.PrivilegeCount := 1;
+ lpLuid.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
+ ReturnLength := 0;
+ OldlpLuid := lpLuid;
+ // SeDebugPrivilege
+ if not AdjustTokenPrivileges(TokenHandle, False, lpLuid, SizeOf(OldlpLuid), OldlpLuid, ReturnLength) then RaiseLastOSError;
+ end;
+
+ ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, false, dwProcessId);
+ if ProcessHandle = 0 then RaiseLastOSError
+ else
+ try
+ IsProcessx64 := ProcessIsX64(ProcessHandle);
+
+ {$IFNDEF CPUX64}
+ if IsProcessx64 then
+ raise Exception.Create('Only 32 bits processes are supported');
+ {$ENDIF}
+
+ {$IFDEF CPUX64}
+ if IsProcessx64 then
+ begin
+ {$ENDIF}
+ // PROCESS_BASIC_INFORMATION PEB
+ if (NtQueryInformationProcess(ProcessHandle,0{=>ProcessBasicInformation},@ProcessBasicInfo, SizeOf(ProcessBasicInfo), @ReturnLength)=STATUS_SUCCESS) and (ReturnLength=SizeOf(ProcessBasicInfo)) then
+ begin
+ // PEB
+ if not ReadProcessMemory(ProcessHandle, ProcessBasicInfo.PEBBaseAddress, @Peb, sizeof(Peb), lpNumberOfBytesRead) then
+ RaiseLastOSError
+ else
+ begin
+ // RTL_USER_PROCESS_PARAMETERS
+ if not ReadProcessMemory(ProcessHandle, Peb.ProcessParameters, @Rtl, SizeOf(Rtl), lpNumberOfBytesRead) then
+ RaiseLastOSError
+ else
+ begin
+ SetLength(ws,(Rtl.CommandLine.Length div 2));
+ if not ReadProcessMemory(ProcessHandle,Rtl.CommandLine.Buffer,PWideChar(ws),Rtl.CommandLine.Length,lpNumberOfBytesRead) then
+ RaiseLastOSError
+ else
+ Result := String(ws);
+ end;
+ end;
+ end
+ else
+ RaiseLastOSError;
+ {$IFDEF CPUX64}
+ end
+ else
+ begin
+ // PEB
+ if NtQueryInformationProcess(ProcessHandle, ProcessWow64Information, @PEBBaseAddress32, SizeOf(PEBBaseAddress32), nil)=STATUS_SUCCESS then
+ begin
+ // PEB
+ if not ReadProcessMemory(ProcessHandle, PEBBaseAddress32, @Peb32, sizeof(Peb32), lpNumberOfBytesRead) then
+ RaiseLastOSError
+ else
+ begin
+ // RTL_USER_PROCESS_PARAMETERS
+ if not ReadProcessMemory(ProcessHandle, Pointer(Peb32.ProcessParameters), @Rtl32, SizeOf(Rtl32), lpNumberOfBytesRead) then
+ RaiseLastOSError
+ else
+ begin
+ SetLength(ws,(Rtl32.CommandLine.Length div 2));
+ if not ReadProcessMemory(ProcessHandle, Pointer(Rtl32.CommandLine.Buffer), PWideChar(ws), Rtl32.CommandLine.Length, lpNumberOfBytesRead) then
+ RaiseLastOSError
+ else
+ Result := String(Ws);
+ end;
+ end;
+ end
+ else
+ RaiseLastOSError;
+ end;
+ {$ENDIF}
+ finally
+ CloseHandle(ProcessHandle);
+ end;
+ finally
+ CloseHandle(TokenHandle);
+ end;
+ end
+ else
+ RaiseLastOSError;
+end;
+
+{ SeDebugPrivilege }
+function SetProcessDebugPrivelege: Boolean;
+var
+ hToken: THandle;
+ tp: TTokenPrivileges;
+ rl: Cardinal;
+begin
+ Result := False;
+ if not OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES,hToken) then
+ Exit;
+ try
+ if not LookupPrivilegeValue(nil,'SeDebugPrivilege', tp.Privileges[0].Luid) then
+ Exit;
+ tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
+ tp.PrivilegeCount := 1;
+ Result := AdjustTokenPrivileges(hToken,false,tp,0,nil,rl) and (GetLastError=0);
+ finally
+ CloseHandle(hToken);
+ end
+end;
+
+// .
+// , .
+// 'SeDebugPrivilege'
+// (
+// .
+// / .
+// . ,
+// - .
+// , .
+function ProcessTerminate(dwPID: Cardinal): Boolean;
+var
+ hToken:THandle;
+ SeDebugNameValue:Int64;
+ tkp:TOKEN_PRIVILEGES;
+ ReturnLength:Cardinal;
+ hProcess:THandle;
+begin
+ Result := False;
+ // SeDebugPrivilege
+ //
+ if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken ) then
+ Exit;
+ // LUID
+ if not LookupPrivilegeValue(nil, 'SeDebugPrivilege', SeDebugNameValue) then
+ begin
+ CloseHandle(hToken);
+ Exit;
+ end;
+ tkp.PrivilegeCount := 1;
+ tkp.Privileges[0].Luid := SeDebugNameValue;
+ tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
+ //
+ AdjustTokenPrivileges(hToken, False, tkp, SizeOf(tkp), tkp, ReturnLength);
+ if GetLastError() <> ERROR_SUCCESS then
+ Exit;
+ // . SeDebugPrivilege,
+ //
+ //
+ hProcess := OpenProcess(PROCESS_TERMINATE, FALSE, dwPID);
+ if hProcess = 0 then
+ Exit;
+ //
+ if not TerminateProcess(hProcess, DWORD(-1)) then
+ Exit;
+ CloseHandle( hProcess );
+ //
+ tkp.Privileges[0].Attributes := 0;
+ AdjustTokenPrivileges(hToken, FALSE, tkp, SizeOf(tkp), tkp, ReturnLength);
+ if GetLastError() <> ERROR_SUCCESS then
+ Exit;
+ Result := True;
+end;
+
+function StringToParts(sString: String; tdDelim: TDelim): TArrayOfString;
+var
+ iCounter,iBegin:Integer;
+begin
+ if length(sString)>0 then
+ begin
+ include(tdDelim, #0);
+ iBegin:=1;
+ SetLength(Result, 0);
+ for iCounter:=1 to Length(sString)+1 do
+ begin
+ if(sString[iCounter] in tdDelim) then
+ begin
+ SetLength(Result, Length(Result)+1);
+ Result[Length(Result)-1] := Copy(sString, iBegin, iCounter-iBegin);
+ iBegin := iCounter+1;
+ end;
+ end;
+ end;
+end;
+
+{ Edit1.Text := ExtractWord(ExtractWord('admin:login:password', ':', 3)); //'password' }
+function ExtractWord(const AString: string; const ADelimiter: Char; const ANumber: integer): string;
+var
+ i, j, k: integer;
+begin
+ i := 1;
+ k := 1;
+ while k <> ANumber do
+ begin
+ if AString[i] = ADelimiter then
+ begin
+ Inc(k);
+ end;
+ Inc(i);
+ end;
+ j := i + 1;
+ while (j <= Length(AString)) and (AString[j] <> ADelimiter) do
+ Inc(j);
+ Result := Copy(AString, i, j - i);
+end;
+
+{ }
+function GetUserTempPath: WideString;
+var
+ UserPath: WideString;
+begin
+ Result := '';
+ SetLength(UserPath, MAX_PATH);
+ GetTempPath(MAX_PATH, PChar(UserPath));
+ GetLongPathName(PChar(UserPath), PChar(UserPath), MAX_PATH);
+ SetLength(UserPath, StrLen(PChar(UserPath)));
+ Result := UserPath;
+end;
+
+{
+DwMajorVersion:DWORD - Windows
+
+ Windows 95 - 4
+ Windows 98 - 4
+ Windows Me - 4
+ Windows NT 3.51 - 3
+ Windows NT 4.0 - 4
+ Windows 2000 - 5
+ Windows XP - 5
+
+DwMinorVersion: DWORD -
+
+ Windows 95 - 0
+ Windows 98 - 10
+ Windows Me - 90
+ Windows NT 3.51 - 51
+ Windows NT 4.0 - 0
+ Windows 2000 - 0
+ Windows XP - 1
+
+
+DwBuildNumber: DWORD
+ Win NT 4 -
+ Win 9x - - / -
+
+
+dwPlatformId: DWORD
+
+ VER_PLATFORM_WIN32s Win32s on Windows 3.1.
+ VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 9x
+ VER_PLATFORM_WIN32_NT Win32 on Windows NT, 2000
+
+
+SzCSDVersion:DWORD
+ NT - Phar ServicePack
+ 9x - . ,
+}
+function DetectWinVersion: TWinVersion;
+var
+ OSVersionInfo : TOSVersionInfo;
+begin
+ Result := wvUnknown; //
+ OSVersionInfo.dwOSVersionInfoSize := sizeof(TOSVersionInfo);
+ if GetVersionEx(OSVersionInfo)
+ then
+ begin
+ case OSVersionInfo.DwMajorVersion of
+ 3: Result := wvNT3; // Windows NT 3
+ 4: case OSVersionInfo.DwMinorVersion of
+ 0: if OSVersionInfo.dwPlatformId = VER_PLATFORM_WIN32_NT
+ then Result := wvNT4 // Windows NT 4
+ else Result := wv95; // Windows 95
+ 10: Result := wv98; // Windows 98
+ 90: Result := wvME; // Windows ME
+ end;
+ 5: case OSVersionInfo.DwMinorVersion of
+ 0: Result := wvW2K; // Windows 2000
+ 1: Result := wvXP; // Windows XP
+ 2: Result := wv2003; // Windows 2003
+ 3: Result := wvVista; // Windows Vista
+ end;
+ 6: case OSVersionInfo.DwMinorVersion of
+ 0: Result := wv2008; // Windows 2008
+ 1: Result := wv7; // Windows 7
+ end;
+ 7: case OSVersionInfo.DwMinorVersion of
+ 1: Result := wv8; // Windows 8
+ end;
+ end;
+ end;
+end;
+
+function DetectWinVersionStr: String;
+const
+ VersStr : Array[TWinVersion] of String = (
+ 'Unknown OS',
+ 'Windows 95',
+ 'Windows 98',
+ 'Windows ME',
+ 'Windows NT 3',
+ 'Windows NT 4',
+ 'Windows 2000',
+ 'Windows XP',
+ 'Windows Server 2003',
+ 'Windows Vista',
+ 'Windows 7',
+ 'Windows Server 2008',
+ 'Windows 8');
+begin
+ Result := VersStr[DetectWinVersion];
+end;
+
+begin
+end.
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr
new file mode 100644
index 0000000000..62b3039fd9
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dpr
@@ -0,0 +1,32 @@
+{ ################################################################################ }
+{ # # }
+{ # IM-History - HistoryToDBUpdater v1.0 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ################################################################################ }
+
+program HistoryToDBUpdater;
+
+uses
+ madExcept,
+ madLinkDisAsm,
+ madListHardware,
+ madListProcesses,
+ madListModules,
+ Forms,
+ Main in 'Main.pas' {MainForm},
+ Global in 'Global.pas';
+
+{$R *.res}
+
+begin
+ Application.Initialize;
+ Application.MainFormOnTaskbar := True;
+ Application.Title := 'HistoryToDBUpdater';
+ Application.CreateForm(TMainForm, MainForm);
+ if MainForm.RunAppDone then
+ Application.Run;
+end.
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj
new file mode 100644
index 0000000000..72aa3a5ce1
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.dproj
@@ -0,0 +1,197 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{939BF92A-9B69-4A14-B992-518631C54279}</ProjectGuid>
+ <MainSource>HistoryToDBUpdater.dpr</MainSource>
+ <Base>True</Base>
+ <Config Condition="'$(Config)'==''">Release</Config>
+ <TargetedPlatforms>3</TargetedPlatforms>
+ <AppType>Application</AppType>
+ <FrameworkType>VCL</FrameworkType>
+ <ProjectVersion>14.4</ProjectVersion>
+ <Platform Condition="'$(Platform)'==''">Win32</Platform>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
+ <Base_Win32>true</Base_Win32>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
+ <Base_Win64>true</Base_Win64>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+ <Cfg_1>true</Cfg_1>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
+ <Cfg_1_Win32>true</Cfg_1_Win32>
+ <CfgParent>Cfg_1</CfgParent>
+ <Cfg_1>true</Cfg_1>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
+ <Cfg_1_Win64>true</Cfg_1_Win64>
+ <CfgParent>Cfg_1</CfgParent>
+ <Cfg_1>true</Cfg_1>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+ <Cfg_2>true</Cfg_2>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base)'!=''">
+ <DCC_S>false</DCC_S>
+ <DCC_K>false</DCC_K>
+ <VerInfo_Locale>1049</VerInfo_Locale>
+ <DCC_N>false</DCC_N>
+ <DCC_ImageBase>00400000</DCC_ImageBase>
+ <DCC_E>false</DCC_E>
+ <DCC_F>false</DCC_F>
+ <DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=;CFBundleName=;CFBundleDisplayName=;CFBundleIdentifier=;CFBundleVersion=;CFBundlePackageType=;CFBundleSignature=;CFBundleAllowMixedLocalizations=;CFBundleExecutable=</VerInfo_Keys>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_Win32)'!=''">
+ <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <Icon_MainIcon>HistoryToDBUpdater_Icon1.ico</Icon_MainIcon>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_Win64)'!=''">
+ <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <Icon_MainIcon>HistoryToDBUpdater_Icon1.ico</Icon_MainIcon>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1)'!=''">
+ <DCC_DebugInformation>false</DCC_DebugInformation>
+ <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+ <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+ <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
+ <VerInfo_AutoGenVersion>true</VerInfo_AutoGenVersion>
+ <DCC_DebugInformation>true</DCC_DebugInformation>
+ <DCC_Define>madExcept;$(DCC_Define)</DCC_Define>
+ <DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols>
+ <DCC_MapFile>3</DCC_MapFile>
+ <Icon_MainIcon>HistoryToDBUpdater_Icon.ico</Icon_MainIcon>
+ <DCC_BplOutput>..\..\..\bin10\Release\Plugins\</DCC_BplOutput>
+ <DCC_ExeOutput>..\..\..\bin10\Release\Plugins\</DCC_ExeOutput>
+ <DCC_DcpOutput>..\..\..\bin10\Release\Obj\hpp\</DCC_DcpOutput>
+ <DCC_DcuOutput>..\..\..\bin10\Release\Obj\hpp\</DCC_DcuOutput>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <VerInfo_MinorVer>5</VerInfo_MinorVer>
+ <VerInfo_Keys>CompanyName=http://www.im-history.ru;FileDescription=HistoryToDBUpdater;FileVersion=2.5.0.0;InternalName=HistoryToDBUpdater;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=HistoryToDBUpdater.exe;ProductName=HistoryToDBUpdater;ProductVersion=1.0.0.0;Comments=http://www.im-history.ru</VerInfo_Keys>
+ <VerInfo_MajorVer>2</VerInfo_MajorVer>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
+ <VerInfo_AutoGenVersion>true</VerInfo_AutoGenVersion>
+ <VerInfo_MajorVer>2</VerInfo_MajorVer>
+ <DCC_Define>madExcept;$(DCC_Define)</DCC_Define>
+ <DCC_DebugInformation>true</DCC_DebugInformation>
+ <VerInfo_MinorVer>5</VerInfo_MinorVer>
+ <DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols>
+ <Icon_MainIcon>HistoryToDBUpdater_Icon.ico</Icon_MainIcon>
+ <DCC_MapFile>3</DCC_MapFile>
+ <DCC_ExeOutput>..\..\..\bin10\Release64\Plugins\</DCC_ExeOutput>
+ <DCC_BplOutput>..\..\..\bin10\Release64\Plugins\</DCC_BplOutput>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <DCC_DcpOutput>..\..\..\bin10\Release64\Obj\hpp\</DCC_DcpOutput>
+ <VerInfo_Keys>CompanyName=http://www.im-history.ru;FileDescription=HistoryToDBUpdater;FileVersion=2.5.0.0;InternalName=HistoryToDBUpdater;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=HistoryToDBUpdater.exe;ProductName=HistoryToDBUpdater;ProductVersion=1.0.0.0;Comments=http://www.im-history.ru</VerInfo_Keys>
+ <DCC_DcuOutput>..\..\..\bin10\Release64\Obj\hpp\</DCC_DcuOutput>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2)'!=''">
+ <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+ <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+ <DCC_Optimize>false</DCC_Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <DelphiCompile Include="$(MainSource)">
+ <MainSource>MainSource</MainSource>
+ </DelphiCompile>
+ <DCCReference Include="Main.pas">
+ <Form>MainForm</Form>
+ </DCCReference>
+ <DCCReference Include="Global.pas"/>
+ <BuildConfiguration Include="Debug">
+ <Key>Cfg_2</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Base">
+ <Key>Base</Key>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Release">
+ <Key>Cfg_1</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ </ItemGroup>
+ <ProjectExtensions>
+ <Borland.Personality>Delphi.Personality.12</Borland.Personality>
+ <Borland.ProjectType/>
+ <BorlandProject>
+ <Delphi.Personality>
+ <Source>
+ <Source Name="MainSource">HistoryToDBUpdater.dpr</Source>
+ </Source>
+ <VersionInfo>
+ <VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+ <VersionInfo Name="AutoIncBuild">False</VersionInfo>
+ <VersionInfo Name="MajorVer">1</VersionInfo>
+ <VersionInfo Name="MinorVer">0</VersionInfo>
+ <VersionInfo Name="Release">0</VersionInfo>
+ <VersionInfo Name="Build">0</VersionInfo>
+ <VersionInfo Name="Debug">False</VersionInfo>
+ <VersionInfo Name="PreRelease">False</VersionInfo>
+ <VersionInfo Name="Special">False</VersionInfo>
+ <VersionInfo Name="Private">False</VersionInfo>
+ <VersionInfo Name="DLL">False</VersionInfo>
+ <VersionInfo Name="Locale">1049</VersionInfo>
+ <VersionInfo Name="CodePage">1251</VersionInfo>
+ </VersionInfo>
+ <VersionInfoKeys>
+ <VersionInfoKeys Name="CompanyName"/>
+ <VersionInfoKeys Name="FileDescription"/>
+ <VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="InternalName"/>
+ <VersionInfoKeys Name="LegalCopyright"/>
+ <VersionInfoKeys Name="LegalTrademarks"/>
+ <VersionInfoKeys Name="OriginalFilename"/>
+ <VersionInfoKeys Name="ProductName"/>
+ <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="Comments"/>
+ <VersionInfoKeys Name="CFBundleName"/>
+ <VersionInfoKeys Name="CFBundleDisplayName"/>
+ <VersionInfoKeys Name="CFBundleIdentifier"/>
+ <VersionInfoKeys Name="CFBundleVersion"/>
+ <VersionInfoKeys Name="CFBundlePackageType"/>
+ <VersionInfoKeys Name="CFBundleSignature"/>
+ <VersionInfoKeys Name="CFBundleAllowMixedLocalizations"/>
+ <VersionInfoKeys Name="CFBundleExecutable"/>
+ </VersionInfoKeys>
+ <Excluded_Packages>
+ <Excluded_Packages Name="$(BDSBIN)\dcloffice2k170.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
+ <Excluded_Packages Name="$(BDSBIN)\dclofficexp170.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
+ </Excluded_Packages>
+ </Delphi.Personality>
+ <Platforms>
+ <Platform value="Win32">True</Platform>
+ <Platform value="Win64">True</Platform>
+ </Platforms>
+ </BorlandProject>
+ <ProjectFileVersion>12</ProjectFileVersion>
+ </ProjectExtensions>
+ <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
+ <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
+</Project>
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest
new file mode 100644
index 0000000000..812068c2ab
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.manifest
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ name="Microsoft.Windows.Shell.explorer"
+ processorArchitecture="x86"
+ version="5.1.0.0"
+ type="win32"/>
+<description>HistoryToDBUpdater</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="x86"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+</assembly>
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes
new file mode 100644
index 0000000000..1fcb334c1d
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.mes
@@ -0,0 +1,163 @@
+[GeneralSettings]
+MesVersion=4
+HandleExceptions=1
+LinkInCode=1
+AppendMapFileToBinary=1
+NoOwnMadExceptSettings=0
+CheckFileCrc=1
+CheckForFrozenMainThread=0
+FreezeTimeout=60000
+ReportLeaks=0
+WindowsLogo=0
+CrashOnBuffer=0
+CrashOnUnderrun=0
+AutomaticallySaveBugReport=1
+AutoSaveBugReportIfNotSent=1
+AutomaticallyMailBugReport=0
+AutoMailProgressBox=0
+CopyBugReportToClipboard=0
+SuspendAllRunningThreads=0
+ShowPleaseWaitBox=1
+PleaseWaitIcon=plwait1
+AutomaticallyContinueApplication=0
+AutomaticallyRestartApplication=0
+AutomaticallyCloseApplication=0
+SendInBackground=1
+SendHelper=196608
+Send32Icon=send321
+UploadViaHttp=0
+HttpServer=
+HttpSsl=0
+HttpPort=0
+HttpAccount=
+HttpPassword=
+UploadToFogBugz=0
+UploadToBugZilla=0
+UploadToMantis=0
+BugTrackerAccount=
+BugTrackerPassword=
+BugTrackerProject=
+BugTrackerArea=
+BugTrackerAssignTo=
+MailAsSmtpServer=0
+MailAsSmtpClient=0
+SmtpServer=
+SmtpSsl=0
+SmtpTls=0
+SmtpPort=0
+SmtpAccount=
+SmtpPassword=
+MailViaMapi=1
+MailViaMailto=1
+MailAddress=sleuthhound@gmail.com
+BugReportFile=bugreport.txt
+AttachBugReport=1
+AttachBugReportFile=1
+DeleteBugReportFile=1
+BugReportSendAs=bugreport.txt
+BugReportZip=
+ScreenShotDepth=8
+ScreenShotAppOnly=0
+ScreenShotSendAs=screenshot.png
+ScreenShotZip=
+AdditionalAttachments=
+AppendBugReports=1
+BugReportFileSize=100000
+DontSaveDuplicateExceptions=1
+DontSaveDuplicateFreezings=1
+DuplicateExceptionDefinition=1
+DuplicateFreezeDefinition=2
+ShowExceptionBox=1
+OkBtnText=&OK
+DetailsBtnText=&Details
+PleaseWaitTitle=Information
+PleaseWaitText=Please wait a moment...
+BugTrackerTitle=%25appname%25, %25exceptMsg%25
+BugTrackerDescr=error details: %0d%0a%25errorDetails%25
+MailSubject=bug report
+MailBody=please find the bug report attached
+SendBoxTitle=Sending bug report...
+PrepareAttachMsg=Preparing attachments...
+MxLookupMsg=Searching for mail server...
+ConnectMsg=Connecting to server...
+SendMailMsg=Sending mail...
+FieldsMsg=Setting fields...
+SendAttachMsg=Sending attachments...
+SendFinalizeMsg=Finalizing...
+MailFailureMsg=Sorry, sending the bug report didn't work.
+VersionVariable=
+[ExceptionBox]
+ShowButtonMailBugReport=1
+ShowButtonSaveBugReport=0
+ShowButtonPrintBugReport=0
+ShowButtonShowBugReport=1
+ShowButtonContinueApplication=1
+ShowButtonRestartApplication=1
+ShowButtonCloseApplication=1
+IconButtonSendBugReport=send1
+IconButtonSaveBugReport=save1
+IconButtonPrintBugReport=print1
+IconButtonShowBugReport=show1
+IconButtonContinueApplication=continue1
+IconButtonCantContinueApplication=cantContinue1
+IconButtonRestartApplication=restart1
+IconButtonCloseApplication=close1
+FocusedButton=0
+SendAssistant=SendAssistant
+SaveAssistant=SaveAssistant
+PrintAssistant=PrintAssistant
+AutomaticallyShowBugReport=0
+NoOwnerDrawButtons=0
+BigExceptionIcon=big1
+TitleBar=%25appname%25
+ExceptionMessage=An error occurred in the application.
+FrozenMessage=The application seems to be frozen.
+BitFaultMsg=The file "%25modname%25" seems to be corrupt!
+MailBugReportText=send bug report
+SaveBugReportText=save bug report
+PrintBugReportText=print bug report
+ShowBugReportText=show bug report
+ContinueApplicationText=continue application
+RestartApplicationText=restart application
+CloseApplicationText=close application
+[BugReport]
+ListThreads=1
+ListModules=1
+ListHardware=1
+ShowCpuRegisters=1
+ShowStackDump=1
+Disassembly=1
+HideUglyItems=0
+ShowRelativeAddrs=1
+ShowRelativeLines=1
+FormatDisassembly=0
+LimitDisassembly=5
+EnabledPlugins=modules|processes|hardware
+[Filters]
+Filter1ExceptionClasses=EDBEditError
+Filter1DontCreateBugReport=1
+Filter1DontCreateScreenshot=1
+Filter1DontSuspendThreads=1
+Filter1DontCallHandlers=1
+Filter1ShowBox=3
+Filter1Assis=
+Filter2ExceptionClasses=
+Filter2DontCreateBugReport=0
+Filter2DontCreateScreenshot=0
+Filter2DontSuspendThreads=0
+Filter2DontCallHandlers=0
+Filter2ShowBox=0
+Filter2Assis=
+GeneralDontCreateBugReport=0
+GeneralDontCreateScreenshot=0
+GeneralDontSuspendThreads=0
+GeneralDontCallHandlers=0
+GeneralShowBox=0
+GeneralAssis=
+[Assistants]
+Assistant1=SendAssistant|Send Assistant|ContactForm|DetailsForm|ScrShotForm
+Assistant2=SaveAssistant|Save Assistant|ContactForm|DetailsForm
+Assistant3=PrintAssistant|Print Assistant|ContactForm|DetailsForm
+Forms1=TPF0%0eTMEContactForm%0bContactForm%07Message%0c%13%00%00%00Contact Information%08MinWidth%04%00%00%00%00%08OnAction%0c%1b%00%00%00madExcept.HandleContactForm%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c%0a%00%00%00your name:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%08NameEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%09%0aOutputName%0c%0c%00%00%00contact name%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%08INVLabel%06Label2%07Caption%0c%0b%00%00%00your email:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%09EmailEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00contact email%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%0bINVCheckBox%08MemCheck%07Caption%0c%0b%00%00%00remember me%07Checked%08%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%00
+Forms2=TPF0%0eTMEDetailsForm%0bDetailsForm%07Message%0c%0d%00%00%00Error Details%08MinWidth%04%00%00%00%00%08OnAction%0c%00%00%00%00%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c'%00%00%00in which situation did the error occur?%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%0bDetailsMemo%07Colored%09%07Enabled%09%05Lines%04%09%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00error details%0aOutputType%07%0dnvoOwnSection%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%00
+Forms3=TPF0%0eTMEScrShotForm%0bScrShotForm%0dActiveControl%07%0bContinueBtn%07Message%0c%18%00%00%00Screenshot Configuration%08MinWidth%04%00%00%00%00%08OnAction%0c%1e%00%00%00madExcept.HandleScreenshotForm%05Timer%04%fa%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%0bINVCheckBox%0bAttachCheck%07Caption%0c%25%00%00%00attach a screenshot to the bug report%07Checked%09%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%08INVImage%0aScrShotImg%06Border%09%09Clickable%09%07Enabled%09%04File%0c%00%00%00%00%06Height%04%00%00%00%00%07Spacing%04%00%00%00%00%05Width%04%00%00%00%00%00%00%08INVLabel%06Label1%07Caption%0c%15%00%00%00(click to edit image)%07Enabled%09%07Spacing%04%00%00%00%00%00%00%00
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otares b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otares
new file mode 100644
index 0000000000..93e7e944f2
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.otares
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.res b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.res
new file mode 100644
index 0000000000..f283649744
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater.res
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico
new file mode 100644
index 0000000000..244fcd4ddd
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/HistoryToDBUpdater_Icon.ico
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm
new file mode 100644
index 0000000000..623f7ef672
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.dfm
@@ -0,0 +1,530 @@
+object MainForm: TMainForm
+ Left = 0
+ Top = 0
+ BorderIcons = [biSystemMenu, biMinimize]
+ Caption = 'HistoryToDBUpdater'
+ ClientHeight = 357
+ ClientWidth = 486
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Icon.Data = {
+ 0000010001001010000001000000680400001600000028000000100000002000
+ 0000010020000000000000040000000000000000000000000000000000000000
+ 0000000000000000000000000000FF1F2A000000000000000000000000000000
+ 00000000000000000000FF1F2A00000000000000000000000000000000000000
+ 000000000000D0CDC500FF1F2A00FEEFA900FF1F2A00CDCDCD00CDCDCD00CDCD
+ CD00CDCDCD00FF1F2A00FEEFA900FF1F2A000000000000000000000000000000
+ 0000D0CDC500FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F
+ 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A00D0CDC500000000000000
+ 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FECF4D00FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A0000000000FF1F
+ 2A00FEEFA900FFE55F00FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FFE55F00FF1F2A00FF1F2A000000
+ 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A00000000000000
+ 0000C1BDB600FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F
+ 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A00CFC7BF00000000000000
+ 0000C1BDB600F9F3ED00FF1F2A00FEEFA900FF1F2A00D2D2D200D2D2D200D2D2
+ D200D2D2D200FF1F2A00FEEFA900FF1F2A00BAB7AF00CFC7BF00000000000000
+ 0000BAB7AF00A39A8F00BAB2A700FF1F2A00D2D2D200D2D2D200D2D2D200D2D2
+ D200D2D2D200D2D2D200FF1F2A00CFC7BF00A39A8F00BAB7AF00000000000000
+ 0000B1AB9F00C9C2B900CFC7BF00D5CCC400DCD3CA00E4D9D200E8DDD500E4D6
+ CF00E4D6CF00E4D6CF00D5CCC400CFC7BF00C9C2B900B1AB9F00000000000000
+ 0000B0AB9E00C7C0B600CCC4BB00D3C9C100DAD0C700E1D7CF00EBE1DA00E4D9
+ D100E4D9D100DDD2CA00DBCDC500DDCAC400DBC4BF00C1ADA400000000000000
+ 0000AFAA9D00C8C1B700E8E3DB00F5F0E800FDF8F200FCF8F100FBF7F000FCF7
+ F100FCF7F100FDF8F200F7F0EA00ECE3DC00CDC3BB00B2AA9E00000000000000
+ 0000AEA89C00FBF5EF00EEE7DE00E0D8CE00DDD5CC00DDD4CB00DDD4CB00DDD4
+ CB00DDD4CB00DDD5CC00E0D7CE00EDE6DE00FBF6EF00AEA89C00000000000000
+ 0000AFA99D00E1D8CE00E1D7CE00DFD6CC00DFD5CB00DFD5CB00DFD5CB00DFD5
+ CB00DFD5CB00DFD5CB00DFD6CC00E1D7CE00E1D8CE00AFA99D00000000000000
+ 000000000000B6B0A400D6CFC400E6DED500EFE7DD00EEE6DC00EEE6DC00EEE6
+ DC00EEE6DC00EFE7DD00E6DED500D6CFC400B6B0A40000000000000000000000
+ 00000000000000000000C4C0B700AEA99C00AEA89C00AEA89C00AEA89C00AEA8
+ 9C00AEA89C00AEA89C00AEA99C00C4C0B700000000000000000000000000F7EF
+ FFFFC007FFFF8001FFFF8001FFFF0000FFFF8001FFFF8001FFFF8001FFFF8001
+ FFFF8001FFFF8001FFFF8001FFFF8001FFFF8001FFFFC003FFFFE007FFFF}
+ OldCreateOrder = False
+ Position = poScreenCenter
+ OnClose = FormClose
+ OnCreate = FormCreate
+ OnDestroy = FormDestroy
+ OnShow = FormShow
+ DesignSize = (
+ 486
+ 357)
+ PixelsPerInch = 96
+ TextHeight = 13
+ object GBUpdater: TGroupBox
+ Left = 8
+ Top = 8
+ Width = 472
+ Height = 145
+ Anchors = [akLeft, akTop, akRight]
+ Caption = ' '#1054#1073#1085#1086#1074#1083#1077#1085#1080#1077' '
+ TabOrder = 0
+ DesignSize = (
+ 472
+ 145)
+ object LAmountDesc: TLabel
+ Left = 16
+ Top = 56
+ Width = 37
+ Height = 13
+ Caption = #1054#1073#1098#1077#1084':'
+ end
+ object LAmount: TLabel
+ Left = 59
+ Top = 56
+ Width = 30
+ Height = 13
+ Caption = '10000'
+ end
+ object LSpeedDesc: TLabel
+ Left = 16
+ Top = 75
+ Width = 52
+ Height = 13
+ Caption = #1057#1082#1086#1088#1086#1089#1090#1100':'
+ end
+ object LSpeed: TLabel
+ Left = 74
+ Top = 75
+ Width = 49
+ Height = 13
+ Caption = '1000 '#1050#1073'/c'
+ end
+ object LFileDesc: TLabel
+ Left = 210
+ Top = 75
+ Width = 53
+ Height = 13
+ Caption = #1054#1087#1080#1089#1072#1085#1080#1077':'
+ end
+ object LFileDescription: TLabel
+ Left = 269
+ Top = 75
+ Width = 62
+ Height = 13
+ Caption = #1053#1077' '#1080#1079#1074#1077#1089#1090#1085#1086
+ end
+ object LFileMD5Desc: TLabel
+ Left = 210
+ Top = 94
+ Width = 25
+ Height = 13
+ Caption = 'MD5:'
+ end
+ object LFileMD5: TLabel
+ Left = 241
+ Top = 94
+ Width = 62
+ Height = 13
+ Caption = #1053#1077' '#1080#1079#1074#1077#1089#1090#1085#1086
+ end
+ object LFileNameDesc: TLabel
+ Left = 210
+ Top = 56
+ Width = 58
+ Height = 13
+ Caption = #1048#1084#1103' '#1092#1072#1081#1083#1072':'
+ end
+ object LFileName: TLabel
+ Left = 274
+ Top = 56
+ Width = 62
+ Height = 13
+ Caption = #1053#1077' '#1080#1079#1074#1077#1089#1090#1085#1086
+ end
+ object LStatus: TLabel
+ Left = 17
+ Top = 21
+ Width = 322
+ Height = 13
+ Hint = 'UpdateStatus'
+ Caption = #1053#1072#1078#1084#1080#1090#1077' '#1082#1085#1086#1087#1082#1091' "'#1054#1073#1085#1086#1074#1080#1090#1100'" '#1076#1083#1103' '#1085#1072#1095#1072#1083#1072' '#1087#1088#1086#1094#1077#1089#1089#1072' '#1086#1073#1085#1086#1074#1083#1077#1085#1080#1103'.'
+ end
+ object ProgressBarDownloads: TProgressBar
+ Left = 16
+ Top = 40
+ Width = 444
+ Height = 10
+ Anchors = [akLeft, akTop, akRight]
+ TabOrder = 0
+ end
+ object ButtonSettings: TButton
+ Left = 114
+ Top = 109
+ Width = 90
+ Height = 25
+ Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080
+ ImageIndex = 1
+ Images = ImageList_Main
+ TabOrder = 2
+ OnClick = ButtonSettingsClick
+ end
+ object ButtonUpdate: TButton
+ Left = 16
+ Top = 109
+ Width = 95
+ Height = 25
+ Hint = 'UpdateButton'
+ Caption = #1054#1073#1085#1086#1074#1080#1090#1100
+ ImageIndex = 0
+ Images = ImageList_Main
+ TabOrder = 1
+ OnClick = ButtonUpdateStartClick
+ end
+ end
+ object SettingsPageControl: TPageControl
+ Left = 8
+ Top = 159
+ Width = 472
+ Height = 193
+ ActivePage = TabSheetSettings
+ Anchors = [akLeft, akTop, akRight]
+ TabOrder = 1
+ object TabSheetSettings: TTabSheet
+ Caption = #1054#1073#1097#1080#1077' '#1085#1072#1089#1090#1088#1086#1081#1082#1080
+ ImageIndex = 2
+ DesignSize = (
+ 464
+ 165)
+ object GBSettings: TGroupBox
+ Left = 3
+ Top = 0
+ Width = 458
+ Height = 161
+ Anchors = [akLeft, akTop, akRight]
+ Caption = ' '#1054#1073#1097#1080#1077' '#1085#1072#1089#1090#1088#1086#1081#1082#1080
+ TabOrder = 0
+ object LLanguage: TLabel
+ Left = 16
+ Top = 81
+ Width = 88
+ Height = 13
+ Caption = #1071#1079#1099#1082' '#1087#1088#1086#1075#1088#1072#1084#1084#1099':'
+ end
+ object LIMClientType: TLabel
+ Left = 16
+ Top = 27
+ Width = 56
+ Height = 13
+ Caption = 'IM-'#1082#1083#1080#1077#1085#1090':'
+ end
+ object LDBType: TLabel
+ Left = 16
+ Top = 54
+ Width = 39
+ Height = 13
+ Caption = #1058#1080#1087' '#1041#1044':'
+ end
+ object LPlatformType: TLabel
+ Left = 261
+ Top = 27
+ Width = 18
+ Height = 13
+ Caption = 'x86'
+ end
+ object CBLang: TComboBox
+ Left = 110
+ Top = 78
+ Width = 145
+ Height = 21
+ Style = csDropDownList
+ TabOrder = 2
+ OnChange = CBLangChange
+ end
+ object CBIMClientType: TComboBox
+ Left = 110
+ Top = 24
+ Width = 145
+ Height = 21
+ Style = csDropDownList
+ TabOrder = 0
+ OnChange = CBIMClientTypeChange
+ end
+ object CBDBType: TComboBox
+ Left = 110
+ Top = 51
+ Width = 145
+ Height = 21
+ Style = csDropDownList
+ TabOrder = 1
+ OnChange = CBDBTypeChange
+ end
+ end
+ end
+ object TabSheetConnectSettings: TTabSheet
+ Caption = #1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1089#1086#1077#1076#1080#1085#1077#1085#1080#1103
+ DesignSize = (
+ 464
+ 165)
+ object GBConnectSettings: TGroupBox
+ Left = 3
+ Top = 0
+ Width = 458
+ Height = 161
+ Anchors = [akLeft, akTop, akRight]
+ Caption = ' '#1053#1072#1089#1090#1088#1086#1081#1082#1080' '#1089#1086#1077#1076#1080#1085#1077#1085#1080#1103' '
+ TabOrder = 0
+ object LProxyAddress: TLabel
+ Left = 16
+ Top = 47
+ Width = 118
+ Height = 13
+ Caption = #1040#1076#1088#1077#1089' '#1087#1088#1086#1082#1089#1080'-'#1089#1077#1088#1074#1077#1088#1072':'
+ end
+ object LProxyPort: TLabel
+ Left = 267
+ Top = 48
+ Width = 29
+ Height = 13
+ Caption = #1055#1086#1088#1090':'
+ end
+ object LProxyUser: TLabel
+ Left = 16
+ Top = 98
+ Width = 76
+ Height = 13
+ Caption = #1055#1086#1083#1100#1079#1086#1074#1072#1090#1077#1083#1100':'
+ end
+ object LProxyUserPasswd: TLabel
+ Left = 16
+ Top = 125
+ Width = 41
+ Height = 13
+ Caption = #1055#1072#1088#1086#1083#1100':'
+ end
+ object CBUseProxy: TCheckBox
+ Left = 16
+ Top = 24
+ Width = 193
+ Height = 17
+ Caption = #1048#1089#1087#1086#1083#1100#1079#1086#1074#1072#1090#1100' '#1089#1074#1086#1081' '#1087#1088#1086#1082#1089#1080'-'#1089#1077#1088#1074#1077#1088
+ TabOrder = 0
+ OnClick = CBUseProxyClick
+ end
+ object EProxyAddress: TEdit
+ Left = 140
+ Top = 44
+ Width = 121
+ Height = 21
+ TabOrder = 1
+ Text = '127.0.0.1'
+ end
+ object EProxyPort: TEdit
+ Left = 302
+ Top = 44
+ Width = 73
+ Height = 21
+ MaxLength = 5
+ NumbersOnly = True
+ TabOrder = 2
+ Text = '3128'
+ end
+ object EProxyUser: TEdit
+ Left = 98
+ Top = 95
+ Width = 163
+ Height = 21
+ TabOrder = 4
+ end
+ object CBProxyAuth: TCheckBox
+ Left = 16
+ Top = 71
+ Width = 233
+ Height = 17
+ Caption = #1055#1088#1086#1082#1089#1080'-'#1089#1077#1088#1074#1077#1088' '#1090#1088#1077#1073#1091#1077#1090' '#1072#1074#1090#1086#1088#1080#1079#1072#1094#1080#1102
+ TabOrder = 3
+ OnClick = CBProxyAuthClick
+ end
+ object EProxyUserPasswd: TEdit
+ Left = 98
+ Top = 122
+ Width = 163
+ Height = 21
+ PasswordChar = '*'
+ TabOrder = 5
+ end
+ end
+ end
+ object TabSheetLog: TTabSheet
+ Caption = #1051#1086#1075#1080
+ ImageIndex = 1
+ DesignSize = (
+ 464
+ 165)
+ object LogMemo: TMemo
+ Left = 3
+ Top = 3
+ Width = 458
+ Height = 159
+ Anchors = [akLeft, akTop, akRight, akBottom]
+ ReadOnly = True
+ ScrollBars = ssVertical
+ TabOrder = 0
+ end
+ end
+ end
+ object IMDownloader1: TIMDownloader
+ OnError = IMDownloader1Error
+ OnAccepted = IMDownloader1Accepted
+ OnHeaders = IMDownloader1Headers
+ OnMD5Checked = IMDownloader1MD5Checked
+ OnDownloading = IMDownloader1Downloading
+ OnStartDownload = IMDownloader1StartDownload
+ OnBreak = IMDownloader1Break
+ Left = 384
+ Top = 112
+ end
+ object ImageList_Main: TImageList
+ ColorDepth = cd32Bit
+ DrawingStyle = dsTransparent
+ Left = 384
+ Top = 64
+ Bitmap = {
+ 494C010102000400300210001000FFFFFFFF2110FFFFFFFFFFFFFFFF424D3600
+ 0000000000003600000028000000400000001000000001002000000000000010
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000112A1251235A26B72A6E2DE42C732EF52C732EF5286C2CE6027920FA0279
+ 1CFF000200040000000000000000000000000000000000000000000000000000
+ 0000000000000000000029292963414141BF3C3C3CBF1F1F1F63000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000000000000000000000207030D2A65
+ 2EB637873CFB9AC49CFFB2C19CFFBCC09BFFBDC29CFFAFD2B0FF0A8732FF41A0
+ 5DFF06731FF2030C051C00000000000000000000000000000000000000001111
+ 11290505050E01010102767676EABDBDBDFFB2B2B2FF545454EA010101020404
+ 040E0C0C0C290000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000000308030D397E3ED16EB6
+ 85FFADE8C7FFBFD29FFF20964FFF1A9047FF148E41FF0F8A39FF389E5CFF7EC0
+ 95FF44A260FF06781FF8030D051E0000000000000000000000004E4E4E9B6D6D
+ 6DFD5A5A5AE70B0B0B19777777E7CBCBCBFFC7C7C7FF585858E7080808194F4F
+ 4FE74D4D4DFD2B2B2B9B00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000034743BB174BF8CFF98D7
+ B2FF77BF7EFFBBC17CFF279A59FF8FCAA8FF8CC8A4FF89C5A0FF87C49DFF68B5
+ 84FF81C196FF46A464FF057620F500030009000000004F4F4F7BBCBCBCFFDEDE
+ DEFFA6A6A6FF7D7D7DF4848484FEC4C4C4FFC2C2C2FF6C6C6CFE686868F4A6A6
+ A6FFD2D2D2FF808080FF2727277B000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000001631194650AB5AFBB4EAD3FF67BB
+ 72FF6CBC6FFFBDB56BFF2F9E61FF93CDACFF6DB98DFF69B788FF64B584FF5FB2
+ 7EFF65B481FF82C197FF3A9F5AFF007B23FB000000005353537DA5A5A5FED5D5
+ D5FFC5C5C5FFCBCBCBFFD1D1D1FFC9C9C9FFC7C7C7FFCCCCCCFFC5C5C5FFBDBD
+ BDFFCBCBCBFF6D6D6DFE3131317D000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000003D8146B291D7AEFF9FDEB3FF83C5
+ 6EFFA7D07EFFC4A45AFF35A269FF95CEAFFF93CDACFF90CBA9FF8FCBA7FF72BB
+ 8FFF89C7A0FF44A466FF088735FF215A24BF00000000000000005A5A5A85C5C5
+ C5FFC1C1C1FFC5C5C5FFC7C7C7FFAAAAAAFFA7A7A7FFC1C1C1FFBEBEBEFFB5B5
+ B5FFAAAAAAFF3636368500000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000052AA5DE4AFE9CFFF82D48FFFBEDC
+ 89FFC2CB81FFCCA154FF3BA46DFF38A26BFF33A065FF2F9C5FFF53AE7AFF90CB
+ A9FF4DAA72FF168E44FFA0D8BBFF296D2CE8838383CD7F7F7FE3959595EECFCF
+ CFFFC6C6C6FFCCCCCCFF7A7A7AC629292944272727446F6F6FC6C1C1C1FFBCBC
+ BCFFB9B9B9FF5C5C5CEE4E4E4EE3424242CD0000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000005BBB67F6BDEFDDFF71D17BFF8FD1
+ 6AFFBBE09DFFC7A65CFFD3AF5CFFC59851FFC5BB6CFFAED178FF39A162FF58B2
+ 80FF269755FF58A265FFB0E3CEFF2D7832F7BEBEBEFDE2E2E2FFD2D2D2FFC6C6
+ C6FFCDCDCDFFB1B1B1FF27272744000000000000000028282844A8A8A8FFC2C2
+ C2FFB7B7B7FFC0C0C0FFD2D2D2FF5F5F5FFD0000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000005BBB68F5BDF0DCFF80D882FF75DB
+ 6BFFBEE599FFCCDFA6FFCAA75BFFC1BC6AFFB7DA8AFFA5D85EFF3AA666FF2F9E
+ 63FF57BB4EFF61AA6AFFB1E4CEFF317C35F6C2C2C2FDE9E9E9FFD6D6D6FFC9C9
+ C9FFCECECEFFA5A5A5FF23232344000000000000000029292944ACACACFFC4C4
+ C4FFBABABAFFC6C6C6FFDDDDDDFF696969FD0000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 00000000000000000000000000000000000054AD60E2B2ECD2FF9AE2A1FF9CEA
+ 8CFFD4EDB6FFD0EAC7FFCFB86CFFCCB064FFCBC973FF74DB65FF64D94BFF63D7
+ 4BFF6AD35BFF71BA7CFFA4DBC1FF337A36E6A0A0A0CDADADADE3B3B3B3EED8D8
+ D8FFCDCDCDFFBCBCBCFF656565C61F1F1F44222222446F6F6FC6C3C3C3FFC2C2
+ C2FFCDCDCDFF838383EE787878E3696969CD0000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000408449AD97DEB4FFB4EBCCFFB0EF
+ A6FFC9EEA8FFD1EAC9FFD5CF8CFFD9CB8AFFCDB364FFBBBB65FF99D66FFF81DE
+ 71FF78DC6FFF90D0A2FF87C8A3FF2C672FB9000000000000000066666685D4D4
+ D4FFCCCCCCFFC9C9C9FFBABABAFF9C9C9CFFA1A1A1FFC2C2C2FFC6C6C6FFC1C1
+ C1FFB7B7B7FF4747478500000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000162E1A3C5DBF6AFABFF3E2FFB4EF
+ B3FFB4F0ABFFC0EDB6FFD4E3B6FFD9D89BFFDAD394FFCDB46BFFC7B26BFFB4CB
+ 83FF93DF99FFAEE7CDFF43984AFC142D154F000000006363637DC3C3C3FEDCDC
+ DCFFD4D4D4FFD9D9D9FFDBDBDBFFD6D6D6FFD4D4D4FFD9D9D9FFD2D2D2FFCBCB
+ CBFFC8C8C8FF787878FE3636367D000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000000000003D7E46A586D79FFFBFF2
+ DEFFC7F2D6FFD5EFD5FFD0E9CFFFD5DBA5FFDCDEAAFFDBCD8FFFD7C88AFFC9C0
+ 8DFFBCD5AEFF78C790FF33743BB600000000000000006363637BDCDCDCFFEDED
+ EDFFDBDBDBFFB9B9B9F4BDBDBDFED6D6D6FFD4D4D4FFAFAFAFFEA4A4A4F4CBCB
+ CBFFE7E7E7FFB7B7B7FF4343437B000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000001040105499653C48BD8
+ A1FFCDF5E8FFD4EDDAFFCEEDD3FFCFDFAEFFD6DEB4FFD4D4A1FFCED0A0FFC3D0
+ A9FF86C990FF428E4BD1040A040F0000000000000000000000007F7F7F9BCCCC
+ CCFDB7B7B7E713131319AFAFAFE7DEDEDEFFDDDDDDFFA1A1A1E7101010199C9C
+ 9CE7A6A6A6FD6363639B00000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000020302043D7C
+ 45A45DBD69F8A4E1BAFFB9EACCFFC4E0BDFFC4DAB3FFBCD7AFFFA5D7ABFF5ABA
+ 65FB3F8447B60309040C00000000000000000000000000000000000000002121
+ 21290A0A0A0E02020202B6B6B6EAE5E5E5FFE4E4E4FF9E9E9EEA010101020A0A
+ 0A0E1C1C1C290000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000162E193D3F8249AA53AB5EDF5BBA67F45DBD69F857B263E942884BB21B36
+ 1D48000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000004E4E4E63959595BF929292BF4A4A4A63000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000000000000000000000000000424D3E000000000000003E000000
+ 2800000040000000100000000100010000000000800000000000000000000000
+ 000000000000000000000000FFFFFF0000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000
+ 000000000000}
+ end
+end
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas
new file mode 100644
index 0000000000..7579d1834a
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/Main.pas
@@ -0,0 +1,1497 @@
+{ ################################################################################ }
+{ # # }
+{ # IM-History - HistoryToDBUpdater v1.0 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ################################################################################ }
+
+unit Main;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+ Dialogs, StdCtrls, ComCtrls, XMLIntf, XMLDoc, Global, IniFiles, uIMDownloader, ShellApi,
+ ImgList;
+
+type
+ TMainForm = class(TForm)
+ GBUpdater: TGroupBox;
+ ProgressBarDownloads: TProgressBar;
+ LAmountDesc: TLabel;
+ LAmount: TLabel;
+ LSpeedDesc: TLabel;
+ LSpeed: TLabel;
+ ButtonSettings: TButton;
+ ButtonUpdate: TButton;
+ SettingsPageControl: TPageControl;
+ TabSheetConnectSettings: TTabSheet;
+ TabSheetLog: TTabSheet;
+ GBConnectSettings: TGroupBox;
+ LProxyAddress: TLabel;
+ LProxyPort: TLabel;
+ LProxyUser: TLabel;
+ LProxyUserPasswd: TLabel;
+ CBUseProxy: TCheckBox;
+ EProxyAddress: TEdit;
+ EProxyPort: TEdit;
+ EProxyUser: TEdit;
+ CBProxyAuth: TCheckBox;
+ EProxyUserPasswd: TEdit;
+ LogMemo: TMemo;
+ LFileDesc: TLabel;
+ LFileDescription: TLabel;
+ LFileMD5Desc: TLabel;
+ LFileMD5: TLabel;
+ LFileNameDesc: TLabel;
+ LFileName: TLabel;
+ IMDownloader1: TIMDownloader;
+ LStatus: TLabel;
+ TabSheetSettings: TTabSheet;
+ GBSettings: TGroupBox;
+ LLanguage: TLabel;
+ CBLang: TComboBox;
+ LIMClientType: TLabel;
+ CBIMClientType: TComboBox;
+ LDBType: TLabel;
+ CBDBType: TComboBox;
+ ImageList_Main: TImageList;
+ LPlatformType: TLabel;
+ procedure FormCreate(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure FormDestroy(Sender: TObject);
+ procedure ButtonSettingsClick(Sender: TObject);
+ procedure ButtonUpdateStartClick(Sender: TObject);
+ procedure ButtonUpdateStopClick(Sender: TObject);
+ procedure CBUseProxyClick(Sender: TObject);
+ procedure CBProxyAuthClick(Sender: TObject);
+ procedure IMDownloader1StartDownload(Sender: TObject);
+ procedure IMDownloader1Break(Sender: TObject);
+ procedure IMDownloader1Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal);
+ procedure IMDownloader1Error(Sender: TObject; E: TIMDownloadError);
+ procedure IMDownloader1Accepted(Sender: TObject);
+ procedure IMDownloader1Headers(Sender: TObject; Headers: String);
+ procedure IMDownloader1MD5Checked(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: string);
+ procedure CBLangChange(Sender: TObject);
+ procedure CBIMClientTypeChange(Sender: TObject);
+ procedure CBDBTypeChange(Sender: TObject);
+ procedure ButtonUpdateEnableStart;
+ procedure ButtonUpdateEnableStop;
+ procedure FindLangFile;
+ procedure CoreLanguageChanged;
+ procedure InstallUpdate;
+ procedure SetProxySettings;
+ procedure AntiBoss(HideAllForms: Boolean);
+ procedure RunIMClient(IMClientName: String; IMProcessArray: TProcessInfoArray);
+ procedure RunAllIMClients;
+ function StartStepByStepUpdate(CurrStep: Integer; INIFileName: String): Integer;
+ private
+ { Private declarations }
+ FLanguage : WideString;
+ procedure OnControlReq(var Msg : TWMCopyData); message WM_COPYDATA;
+ //
+ procedure OnLanguageChanged(var Msg: TMessage); message WM_LANGUAGECHANGED;
+ procedure LoadLanguageStrings;
+ function EndTask(TaskName, FormName: String): Boolean;
+ public
+ { Public declarations }
+ RunAppDone: Boolean;
+ C1, C2: TLargeInteger;
+ iCounterPerSec: TLargeInteger;
+ TrueHeader: Boolean;
+ CurrentUpdateStep: Integer;
+ HeaderMD5: String;
+ HeaderFileSize: Integer;
+ HeaderFileName: String;
+ MD5InMemory: String;
+ IMMD5Correct: Boolean;
+ IMSizeCorrect: Boolean;
+ INISavePath: String;
+ SavePath: String;
+ SystemLang: String;
+ IMCancelCopy: Boolean;
+ DropboxProcessInfo: TProcessInfoArray;
+ QIPProcessInfo: TProcessInfoArray;
+ RnQProcessInfo: TProcessInfoArray;
+ SkypeProcessInfo: TProcessInfoArray;
+ MirandaProcessInfo: TProcessInfoArray;
+ property CoreLanguage: WideString read FLanguage;
+ end;
+
+function CopyProgressFunc(TotalFileSize: Int64; TotalBytesTransferred: Int64;
+ StreamSize: Int64; StreamBytesTransferred: Int64; dwStreamNumber: DWORD;
+ dwCallbackReason: DWORD; hSourceFile: THandle; hDestinationFile: THandle;
+ lpData: Pointer): DWORD; stdcall;
+
+var
+ MainForm: TMainForm;
+
+
+implementation
+
+{$R *.dfm}
+
+procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
+var
+ INI: TIniFile;
+ Path: WideString;
+ IsFileClosed: Boolean;
+ sFile: DWORD;
+begin
+ // -
+ Global_MainForm_Showing := False;
+ //
+ DBType := CBDBType.Items[CBDBType.ItemIndex];
+ IMClientType := CBIMClientType.Items[CBIMClientType.ItemIndex];
+ DefaultLanguage := CoreLanguage;
+ Path := ProfilePath + ININame;
+ if FileExists(Path) then
+ begin
+ try
+ // -
+ IsFileClosed := False;
+ repeat
+ sFile := CreateFile(PChar(Path),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
+ if (sFile <> INVALID_HANDLE_VALUE) then
+ begin
+ CloseHandle(sFile);
+ IsFileClosed := True;
+ end;
+ until IsFileClosed;
+ // End
+ INI := TIniFile.Create(Path);
+ if ParamCount = 0 then
+ begin
+ INI.WriteString('Main', 'DBType', DBType);
+ INI.WriteString('Main', 'IMClientType', IMClientType);
+ INI.WriteString('Main', 'DefaultLanguage', DefaultLanguage);
+ end;
+ INI.WriteString('Proxy', 'UseProxy', BoolToIntStr(CBUseProxy.Checked));
+ INI.WriteString('Proxy', 'ProxyAddress', EProxyAddress.Text);
+ INI.WriteString('Proxy', 'ProxyPort', EProxyPort.Text);
+ INI.WriteString('Proxy', 'ProxyAuth', BoolToIntStr(CBProxyAuth.Checked));
+ INI.WriteString('Proxy', 'ProxyUser', EProxyUser.Text);
+ INI.WriteString('Proxy', 'ProxyUserPasswd', EncryptStr(EProxyUserPasswd.Text));
+ INI.WriteString('Updater', 'UpdateServer', UpdateServer);
+ finally
+ INI.Free;
+ end;
+ end;
+ if FileExists(INISavePath) then
+ DeleteFile(INISavePath);
+ //
+ if EnableDebug then
+ LogMemo.Lines.SaveToFile(ProfilePath + DebugLogName);
+end;
+
+procedure TMainForm.FormCreate(Sender: TObject);
+var
+ CmdHelpStr: WideString;
+begin
+ RunAppDone := False;
+ TrueHeader := False;
+ IMMD5Correct := False;
+ IMSizeCorrect := False;
+ CurrentUpdateStep := 0;
+ //
+ if MatchStrings(GetSysLang, '*') or MatchStrings(GetSysLang, 'Russian*') then
+ SystemLang := 'Russian'
+ else
+ SystemLang := 'English';
+ //
+ if SystemLang = 'Russian' then
+ begin
+ CmdHelpStr := ' ' + ProgramsName + ' v' + ProgramsVer + ' ' + PlatformType + ':' + #13 +
+ '--------------------------------------------------------------' + #13#13 +
+ 'HistoryToDBUpdater.exe <1>' + #13#13 +
+ '<1> - ( ) - HistoryToDB.ini (: "C:\Program Files\QIP Infium\Profiles\username@qip.ru\Plugins\QIPHistoryToDB\")';
+ end
+ else
+ begin
+ CmdHelpStr := 'Startup options ' + ProgramsName + ' v' + ProgramsVer + ' ' + PlatformType + ':' + #13 +
+ '------------------------------------------------' + #13#13 +
+ 'HistoryToDBUpdater.exe <1>' + #13#13 +
+ '<1> - (Optional) - The path to the configuration file HistoryToDB.ini (Example: "C:\Program Files\QIP Infium\Profiles\username@qip.ru\Plugins\QIPHistoryToDB\")';
+ end;
+ //
+ if (ParamStr(1) = '/?') or (ParamStr(1) = '-?') then
+ begin
+ MsgInf(ProgramsName, CmdHelpStr);
+ Exit;
+ end
+ else
+ begin
+ if ParamCount >= 1 then
+ begin
+ ProfilePath := IncludeTrailingPathDelimiter(ParamStr(1));
+ end
+ else
+ begin
+ ProfilePath := ExtractFilePath(Application.ExeName);
+ end;
+ PluginPath := ExtractFilePath(Application.ExeName);
+ //
+ SavePath := GetUserTempPath + 'IMHistory\';
+ INISavePath := SavePath + 'HistoryToDBUpdate.ini';
+ IMDownloader1.DirPath := PluginPath;
+ //
+ EncryptInit;
+ //
+ LoadINI(ProfilePath, false);
+ //
+ if ParamCount >= 1 then
+ FLanguage := DefaultLanguage
+ else
+ FLanguage := SystemLang;
+ LangDoc := NewXMLDocument();
+ if not DirectoryExists(PluginPath + dirLangs) then
+ CreateDir(PluginPath + dirLangs);
+ if not FileExists(PluginPath + dirLangs + defaultLangFile) then
+ begin
+ if SystemLang = 'Russian' then
+ CmdHelpStr := ' ' + PluginPath + dirLangs + defaultLangFile + ' .'
+ else
+ CmdHelpStr := 'The localization file ' + PluginPath + dirLangs + defaultLangFile + ' is not found.';
+ MsgInf(ProgramsName, CmdHelpStr);
+ //
+ EncryptFree;
+ Exit;
+ end;
+ CoreLanguageChanged;
+ //
+ FindLangFile;
+ //
+ MainFormHandle := Handle;
+ SetWindowLong(Handle, GWL_HWNDPARENT, 0);
+ SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
+ //
+ LoadLanguageStrings;
+ //
+ RunAppDone := True;
+ end;
+end;
+
+procedure TMainForm.FormDestroy(Sender: TObject);
+begin
+ if RunAppDone then
+ begin
+ //
+ EncryptFree;
+ end;
+end;
+
+procedure TMainForm.FormShow(Sender: TObject);
+var
+ I: Integer;
+begin
+ // -
+ Global_MainForm_Showing := True;
+ //
+ AlphaBlend := AlphaBlendEnable;
+ AlphaBlendValue := AlphaBlendEnableValue;
+ // .
+ LAmount.Caption := '0 '+GetLangStr('Kb');
+ LFileName.Caption := GetLangStr('Unknown');
+ LFileDescription.Caption := GetLangStr('Unknown');
+ LFileMD5.Caption := GetLangStr('Unknown');
+ LSpeed.Caption := '0 '+GetLangStr('KbSec');
+ CBUseProxy.Checked := False;
+ EProxyAddress.Enabled := False;
+ EProxyPort.Enabled := False;
+ CBProxyAuth.Enabled := False;
+ SettingsPageControl.ActivePage := TabSheetSettings;
+ SettingsPageControl.Visible := False;
+ MainForm.Height := SettingsPageControl.Height + 5;
+ if (DBType = 'Unknown') or (ParamCount = 0) then
+ begin
+ CBDBType.Enabled := True;
+ CBDBType.Items.Add('Unknown');
+ CBDBType.Items.Add('mysql');
+ CBDBType.Items.Add('postgresql');
+ CBDBType.Items.Add('oracle');
+ CBDBType.Items.Add('sqlite-3');
+ CBDBType.Items.Add('firebird-2.0');
+ CBDBType.Items.Add('firebird-2.5');
+ if ParamCount = 0 then
+ begin
+ for I := 0 to CBDBType.Items.Count-1 do
+ if CBDBType.Items[I] = DBType then
+ CBDBType.ItemIndex := I
+ end
+ else
+ CBDBType.ItemIndex := 0;
+ //
+ ButtonSettingsClick(Self);
+ end
+ else
+ begin
+ CBDBType.Enabled := False;
+ CBDBType.Items.Add(DBType);
+ CBDBType.ItemIndex := 0;
+ end;
+ if (IMClientType = 'Unknown') or (ParamCount = 0) then
+ begin
+ CBIMClientType.Enabled := True;
+ CBIMClientType.Items.Add('Unknown');
+ CBIMClientType.Items.Add('QIP');
+ CBIMClientType.Items.Add('RnQ');
+ CBIMClientType.Items.Add('Skype');
+ CBIMClientType.Items.Add('Miranda');
+ CBIMClientType.Items.Add('MirandaNG');
+ if ParamCount = 0 then
+ begin
+ for I := 0 to CBIMClientType.Items.Count-1 do
+ if CBIMClientType.Items[I] = IMClientType then
+ CBIMClientType.ItemIndex := I
+ end
+ else
+ CBIMClientType.ItemIndex := 0;
+ //
+ if not SettingsPageControl.Visible then
+ ButtonSettingsClick(Self);
+ end
+ else
+ begin
+ CBIMClientType.Enabled := False;
+ CBIMClientType.Items.Add(IMClientType);
+ CBIMClientType.ItemIndex := 0;
+ end;
+ //
+ LPlatformType.Caption := IMClientPlatformType;
+ //
+ CBUseProxy.Checked := IMUseProxy;
+ EProxyAddress.Text := IMProxyAddress;
+ EProxyPort.Text := IMProxyPort;
+ CBProxyAuth.Checked := IMProxyAuth;
+ EProxyUser.Text := IMProxyUser;
+ EProxyUserPasswd.Text := IMProxyUserPagsswd;
+ //
+ LogMemo.Lines.Add(ProgramsName + ' v' + ProgramsVer + ' ' + PlatformType);
+end;
+
+procedure TMainForm.ButtonSettingsClick(Sender: TObject);
+begin
+ if not SettingsPageControl.Visible then
+ begin
+ MainForm.Height := GBUpdater.Height + SettingsPageControl.Height + 55;
+ SettingsPageControl.Visible := True;
+ end
+ else
+ begin
+ SettingsPageControl.Visible := False;
+ MainForm.Height := SettingsPageControl.Height + 5;
+ end;
+end;
+
+procedure TMainForm.ButtonUpdateStartClick(Sender: TObject);
+var
+ AllProcessEndErr: Integer;
+begin
+ IMCancelCopy := False;
+ AllProcessEndErr := 0;
+ if (DBType = 'Unknown') or (IMClientType = 'Unknown') then
+ MsgInf(Caption, GetLangStr('SelectDBTypeAndIMClient'))
+ else
+ begin
+ LogMemo.Clear;
+ // Dropbox
+ {if IsProcessRun('Dropbox.exe') then
+ begin
+ if SystemLang = 'Russian' then
+ MsgString := ' Dropbox.' + #13 +
+ ' IM-, ' + #13 +
+ ' .' + #13 +
+ ' Dropbox?'
+ else
+ MsgString := 'Find the program in the memory of Dropbox.' + #13 +
+ 'If you use it to synchronize the IM-client, to properly' + #13 +
+ 'update all the components necessary to close the plug.' + #13 +
+ 'Close Dropbox?';
+ case MessageBox(MainForm.Handle, PWideChar(MsgString), PWideChar(Caption),36) of
+ 6: DropboxProcessInfo := EndProcess('Dropbox.exe', True);
+ end;
+ end;}
+ //
+ if not EndTask('HistoryToDBSync.exe', 'HistoryToDBSync for ' + IMClientType + ' (' + MyAccount + ')') then
+ Inc(AllProcessEndErr);
+ if not EndTask('HistoryToDBViewer.exe', 'HistoryToDBViewer for ' + IMClientType + ' (' + MyAccount + ')') then
+ Inc(AllProcessEndErr);
+ if not EndTask('HistoryToDBImport.exe', 'HistoryToDBImport for ' + IMClientType + ' (' + MyAccount + ')') then
+ Inc(AllProcessEndErr);
+ // ,
+ if AllProcessEndErr = 0 then
+ begin
+ // IM-
+ if IMClientType = 'QIP' then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['qip.exe']));
+ QIPProcessInfo := EndProcess('qip.exe', 0, True);
+ end;
+ if IMClientType = 'Miranda' then
+ begin
+ if IMClientPlatformType = 'x86' then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda32.exe']));
+ MirandaProcessInfo := EndProcess('miranda32.exe', 1, True);
+ end
+ else
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda64.exe']));
+ MirandaProcessInfo := EndProcess('miranda64.exe', 1, True);
+ end;
+ end;
+ if IMClientType = 'MirandaNG' then
+ begin
+ if IMClientPlatformType = 'x86' then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda32.exe']));
+ MirandaProcessInfo := EndProcess('miranda32.exe', 0, True);
+ end
+ else
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['miranda64.exe']));
+ MirandaProcessInfo := EndProcess('miranda64.exe', 0, True);
+ end;
+ end;
+ if IMClientType = 'RnQ' then
+ begin
+ if IsProcessRun('rnq.exe') then
+ begin
+ RnQProcessInfo := EndProcess('rnq.exe', 0, True);
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['rnq.exe']));
+ end;
+ if IsProcessRun('R&Q.exe') then
+ begin
+ RnQProcessInfo := EndProcess('R&Q.exe', 0, True);
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['R&Q.exe']));
+ end;
+ end;
+ if IMClientType = 'Skype' then
+ begin
+ SkypeProcessInfo := EndProcess('skype.exe', 0, True);
+ LogMemo.Lines.Add(Format(GetLangStr('EndProcess'), ['skype.exe']));
+ end;
+ //
+ TrueHeader := False;
+ CurrentUpdateStep := 0;
+ SetProxySettings;
+ if IMClientPlatformType = 'x86' then
+ IMDownloader1.URL := UpdateServer + '&platform=windows-x86'
+ else
+ IMDownloader1.URL := UpdateServer + '&platform=windows-x64';
+ IMDownloader1.DownLoad;
+ end
+ else
+ MsgInf(Caption, GetLangStr('ManualUpdate'));
+ end;
+end;
+
+{ }
+procedure TMainForm.SetProxySettings;
+begin
+ if CBUseProxy.Checked then
+ begin
+ IMDownloader1.Proxy := EProxyAddress.Text + ':' + EProxyPort.Text;
+ if CBProxyAuth.Checked then
+ begin
+ IMDownloader1.ProxyAuthUserName := EProxyUser.Text;
+ IMDownloader1.ProxyAuthPassword := EProxyUserPasswd.Text;
+ end
+ else
+ begin
+ IMDownloader1.ProxyAuthUserName := '';
+ IMDownloader1.ProxyAuthPassword := '';
+ end;
+ end
+ else
+ begin
+ IMDownloader1.Proxy := '';
+ IMDownloader1.AuthUserName := '';
+ IMDownloader1.AuthPassword := '';
+ end;
+end;
+
+procedure TMainForm.IMDownloader1Accepted(Sender: TObject);
+var
+ MaxSteps: Integer;
+begin
+ LStatus.Caption := GetLangStr('DownloadSuccessful');
+ LStatus.Hint := 'DownloadSuccessful';
+ LStatus.Repaint;
+ LAmount.Caption := CurrToStr(IMDownloader1.AcceptedSize/1024)+' '+GetLangStr('Kb');
+ LAmount.Repaint;
+ if not TrueHeader then
+ begin
+ LFileName.Caption := GetLangStr('Unknown');
+ LFileDescription.Caption := GetLangStr('Unknown');
+ LFileMD5.Caption := GetLangStr('Unknown');
+ LStatus.Caption := GetLangStr('InvalidResponseHeader');
+ LStatus.Hint := 'InvalidResponseHeader';
+ LStatus.Repaint;
+ ButtonUpdateEnableStart;
+ end
+ else
+ begin
+ LStatus.Caption := GetLangStr('IsChecksum');
+ LStatus.Hint := 'IsChecksum';
+ LStatus.Repaint;
+ if MD5InMemory <> 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' then
+ begin
+ LogMemo.Lines.Add(GetLangStr('MD5FileInMemory') + ' ' + MD5InMemory);
+ LogMemo.Lines.Add(GetLangStr('FileSizeInMemory') + ' ' + IntToStr(IMDownloader1.OutStream.Size));
+ end;
+ if IMMD5Correct and IMSizeCorrect then
+ begin
+ if MD5InMemory <> 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' then
+ begin
+ LStatus.Caption := GetLangStr('ChecksumConfirmed');
+ LStatus.Hint := 'ChecksumConfirmed';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(GetLangStr('ChecksumConfirmed'));
+ end
+ else
+ begin
+ LStatus.Caption := GetLangStr('ChecksumFileEqServer');
+ LStatus.Hint := 'ChecksumFileEqServer';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(GetLangStr('ChecksumFileEqServer'));
+ end;
+ // - INI
+ if CurrentUpdateStep = 0 then
+ INISavePath := SavePath + HeaderFileName;
+ //
+ if not DirectoryExists(SavePath) then
+ CreateDir(SavePath);
+ //
+ if CurrentUpdateStep = 0 then
+ begin
+ if FileExists(INISavePath) then
+ DeleteFile(INISavePath);
+ end;
+ if FileExists(SavePath + HeaderFileName) then
+ DeleteFile(SavePath + HeaderFileName);
+ //
+ try
+ if MD5InMemory <> 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' then
+ begin
+ IMDownloader1.OutStream.SaveToFile(SavePath + HeaderFileName);
+ LStatus.Caption := GetLangStr('FileSavedAs') + ' ' + HeaderFileName;
+ LStatus.Hint := 'FileSavedAs';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(GetLangStr('FileSavedAs') + ' ' + HeaderFileName);
+ end;
+ Inc(CurrentUpdateStep);
+ if CurrentUpdateStep > 0 then
+ MaxSteps := StartStepByStepUpdate(CurrentUpdateStep, INISavePath);
+ except
+ on E: Exception do
+ begin
+ LStatus.Caption := GetLangStr('ErrFileSavedAs') + ' ' + HeaderFileName;
+ LStatus.Hint := 'ErrFileSavedAs';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(GetLangStr('ErrFileSavedAs') + ' ' + HeaderFileName);
+ end;
+ end;
+ end
+ else
+ begin
+ if not IMMD5Correct then
+ begin
+ LStatus.Caption := GetLangStr('ChecksumNotConfirmed');
+ LStatus.Hint := 'ChecksumNotConfirmed';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(GetLangStr('ChecksumNotConfirmed'));
+ end;
+ if not IMSizeCorrect then
+ begin
+ LStatus.Caption := GetLangStr('SizeNotConfirmed');
+ LStatus.Hint := 'SizeNotConfirmed';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(GetLangStr('SizeNotConfirmed'));
+ end;
+ ButtonUpdateEnableStart;
+ end;
+ end;
+end;
+
+function TMainForm.StartStepByStepUpdate(CurrStep: Integer; INIFileName: String): Integer;
+var
+ UpdateINI: TIniFile;
+ MaxStep, IMClientCount, IMClientDownloadFileCount: Integer;
+ DatabaseCount, DatabaseDownloadFileCount, I, UpdateServerInServiceMode: Integer;
+ IMClientName, IMClientNum, UpdateURL: String;
+ DatabaseName, DatabaseNum, TmpUpdateServer: String;
+ FileListArray: TArrayOfString;
+ DownloadListArray: TArrayOfString;
+begin
+ Result := 0;
+ if FileExists(INIFileName) then
+ begin
+ UpdateINI := TIniFile.Create(INIFileName);
+ UpdateServerInServiceMode := UpdateINI.ReadInteger('HistoryToDBUpdate', 'UpdateServerInServiceMode', 0);
+ LogMemo.Lines.Add('UpdateServerInServiceMode = ' + IntToStr(UpdateServerInServiceMode));
+ //
+ if UpdateServerInServiceMode = 1 then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateServerInServiceMode'), [' ']));
+ IMDownloader1.BreakDownload;
+ MsgInf(Caption, Format(GetLangStr('UpdateServerInServiceMode'), [#13]));
+ Result := -1;
+ // .
+ ButtonUpdateEnableStart;
+ // IM-
+ RunAllIMClients;
+ //
+ Close;
+ Exit;
+ end;
+ //
+ TmpUpdateServer := UpdateINI.ReadString('HistoryToDBUpdate', 'UpdateServer', UpdateServer);
+ if TmpUpdateServer <> UpdateServer then
+ UpdateServer := TmpUpdateServer;
+ // End
+ MaxStep := UpdateINI.ReadInteger('HistoryToDBUpdate', 'FileCount', 0);
+ IMClientCount := UpdateINI.ReadInteger('HistoryToDBUpdate', 'IMClientCount', 0);
+ if EnableDebug then
+ LogMemo.Lines.Add(' IM- INI- = ' + IntToStr(IMClientCount));
+ IMClientDownloadFileCount := 0;
+ SetLength(DownloadListArray, 0);
+ if IMClientCount > 0 then
+ begin
+ IMClientName := '';
+ while (IMClientCount > 0) and (IMClientName <> CBIMClientType.Items[CBIMClientType.ItemIndex]) do
+ begin
+ IMClientName := UpdateINI.ReadString('HistoryToDBUpdate', 'IMClient'+IntToStr(IMClientCount)+'Name', '');
+ IMClientNum := UpdateINI.ReadString('HistoryToDBUpdate', 'IMClient'+IntToStr(IMClientCount)+'File', '');
+ if EnableDebug then
+ begin
+ LogMemo.Lines.Add('IM- = ' + IMClientName);
+ LogMemo.Lines.Add(' = ' + IMClientNum);
+ end;
+ Dec(IMClientCount);
+ end;
+ FileListArray := StringToParts(IMClientNum, [',']);
+ SetLength(DownloadListArray, Length(FileListArray));
+ DownloadListArray := FileListArray;
+ IMClientDownloadFileCount := Length(FileListArray);
+ if EnableDebug then
+ begin
+ for I := 0 to High(FileListArray) do
+ LogMemo.Lines.Add(' '+IMClientName+' = ' + FileListArray[I]);
+ end;
+ end;
+ DatabaseCount := UpdateINI.ReadInteger('HistoryToDBUpdate', 'DatabaseCount', 0);
+ DatabaseDownloadFileCount := 0;
+ if EnableDebug then
+ LogMemo.Lines.Add(' Database INI- = ' + IntToStr(DatabaseCount));
+ if DatabaseCount > 0 then
+ begin
+ DatabaseName := '';
+ while (DatabaseCount > 0) and (DatabaseName <> CBDBType.Items[CBDBType.ItemIndex]) do
+ begin
+ DatabaseName := UpdateINI.ReadString('HistoryToDBUpdate', 'Database'+IntToStr(DatabaseCount)+'Name', '');
+ DatabaseNum := UpdateINI.ReadString('HistoryToDBUpdate', 'Database'+IntToStr(DatabaseCount)+'File', '');
+ if EnableDebug then
+ begin
+ LogMemo.Lines.Add('Database = ' + DatabaseName);
+ LogMemo.Lines.Add(' = ' + DatabaseNum);
+ end;
+ Dec(DatabaseCount);
+ end;
+ FileListArray := StringToParts(DatabaseNum, [',']);
+ SetLength(DownloadListArray, Length(DownloadListArray) + Length(FileListArray));
+ DatabaseDownloadFileCount := Length(FileListArray);
+ for I := 0 to High(FileListArray) do
+ begin
+ DownloadListArray[IMClientDownloadFileCount+I] := FileListArray[I];
+ if EnableDebug then
+ LogMemo.Lines.Add(' '+DatabaseName+' = ' + FileListArray[I]);
+ end;
+ end;
+ if EnableDebug then
+ begin
+ LogMemo.Lines.Add(' = ' + IntToStr(Length(DownloadListArray)));
+ for I := 0 to High(DownloadListArray) do
+ LogMemo.Lines.Add('DownloadListArray['+IntToStr(I)+'] = ' + DownloadListArray[I]);
+ end;
+ MaxStep := IMClientDownloadFileCount + DatabaseDownloadFileCount;
+ Result := MaxStep;
+ if EnableDebug then
+ LogMemo.Lines.Add(' = ' + IntToStr(MaxStep));
+ if CurrentUpdateStep > MaxStep then
+ begin
+ LStatus.Caption := GetLangStr('AllUpdatesDownloaded');
+ LStatus.Hint := 'AllUpdatesDownloaded';
+ LStatus.Repaint;
+ LogMemo.Lines.Add('=========================================');
+ LogMemo.Lines.Add(GetLangStr('AllUpdatesDownloaded'));
+ InstallUpdate;
+ LStatus.Caption := GetLangStr('AllUpdatesInstalled');
+ LStatus.Hint := 'AllUpdatesInstalled';
+ LStatus.Repaint;
+ LogMemo.Lines.Add('=========================================');
+ LogMemo.Lines.Add(GetLangStr('AllUpdatesInstalled'));
+ // .
+ ButtonUpdateEnableStart;
+ // IM-
+ RunAllIMClients;
+ Close;
+ Exit;
+ end;
+ LogMemo.Lines.Add('================= ' + GetLangStr('Step') + ' '+IntToStr(CurrStep)+' =================');
+ LogMemo.Lines.Add(GetLangStr('NumberFilesUpdate') + ' = ' + IntToStr(MaxStep));
+ if MaxStep > 0 then
+ begin
+ UpdateURL := UpdateINI.ReadString('HistoryToDBUpdate', 'File'+DownloadListArray[CurrStep-1], '');
+ if (UpdateURL <> '') and (CurrStep <= MaxStep) then
+ begin
+ LogMemo.Lines.Add(GetLangStr('FileToUpdate') + ' = ' + UpdateURL);
+ if MatchStrings(UpdateURL, '*file=*Lang') then
+ IMDownloader1.DirPath := PluginPath + dirLangs
+ else if MatchStrings(UpdateURL, '*file=*-update-*-to-*') then
+ IMDownloader1.DirPath := PluginPath + dirSQLUpdate
+ else
+ IMDownloader1.DirPath := PluginPath;
+ IMDownloader1.URL := UpdateURL;
+ IMDownloader1.DownLoad;
+ end
+ else
+ CurrentUpdateStep := 0;
+ end;
+ end
+ else
+ LogMemo.Lines.Add(GetLangStr('UpdateSettingsFileNotFound') + ' ' + INIFileName);
+end;
+
+procedure TMainForm.InstallUpdate;
+var
+ SR: TSearchRec;
+begin
+ LAmount.Caption := '0 '+GetLangStr('Kb');
+ LFileName.Caption := GetLangStr('Unknown');
+ LFileDescription.Caption := GetLangStr('Unknown');
+ LFileMD5.Caption := GetLangStr('Unknown');
+ LSpeed.Caption := '0 '+GetLangStr('KbSec');
+ //
+ if FindFirst(SavePath + '*.*', faAnyFile or faDirectory, SR) = 0 then
+ begin
+ repeat
+ if (SR.Attr = faDirectory) and ((SR.Name = '.') or (SR.Name = '..')) then // . ..
+ begin
+ Continue; //
+ end;
+ if MatchStrings(SR.Name, 'HistoryToDBUpdater.exe') then
+ begin
+ LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]);
+ LStatus.Hint := 'UpdateFile';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name]));
+ if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + 'HistoryToDBUpdater.upd'), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then
+ begin
+ DeleteFile(SavePath + SR.Name);
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name]));
+ end
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name]));
+ end;
+ if MatchStrings(SR.Name, '*.xml') then
+ begin
+ LStatus.Caption := Format(GetLangStr('UpdateLangFile'), [SR.Name]);
+ LStatus.Hint := 'UpdateLangFile';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateLangFile'), [SR.Name]));
+ if FileExists(PluginPath + dirLangs + SR.Name) then
+ DeleteFile(PluginPath + dirLangs + SR.Name);
+ if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + dirLangs + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then
+ begin
+ DeleteFile(SavePath + SR.Name);
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateLangFileDone'), [SR.Name]));
+ end
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name]));
+ end;
+ if MatchStrings(SR.Name, '*.sql') then
+ begin
+ LStatus.Caption := Format(GetLangStr('UpdateSQLFile'), [SR.Name]);
+ LStatus.Hint := 'UpdateSQLFile';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateSQLFile'), [SR.Name]));
+ if not DirectoryExists(PluginPath + dirSQLUpdate) then
+ CreateDir(PluginPath + dirSQLUpdate);
+ if FileExists(PluginPath + dirSQLUpdate + SR.Name) then
+ DeleteFile(PluginPath + dirSQLUpdate + SR.Name);
+ if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + dirSQLUpdate + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then
+ begin
+ DeleteFile(SavePath + SR.Name);
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateSQLFileDone'), [SR.Name]));
+ end
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name]));
+ end;
+ if MatchStrings(SR.Name, '*.exe') then
+ begin
+ LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]);
+ LStatus.Hint := 'UpdateFile';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name]));
+ if FileExists(PluginPath + SR.Name) then
+ DeleteFile(PluginPath + SR.Name);
+ if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), nil, nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then
+ begin
+ DeleteFile(SavePath + SR.Name);
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name]));
+ end
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name]));
+ end;
+ if MatchStrings(SR.Name, '*.dll') then
+ begin
+ LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]);
+ LStatus.Hint := 'UpdateFile';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name]));
+ if FileExists(PluginPath + SR.Name) then
+ DeleteFile(PluginPath + SR.Name);
+ if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then
+ begin
+ DeleteFile(SavePath + SR.Name);
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name]));
+ end
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name]));
+ end;
+ if MatchStrings(SR.Name, '*.msg') then
+ begin
+ LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]);
+ LStatus.Hint := 'UpdateFile';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name]));
+ if FileExists(PluginPath + SR.Name) then
+ DeleteFile(PluginPath + SR.Name);
+ if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), nil, nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then
+ begin
+ DeleteFile(SavePath + SR.Name);
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name]));
+ end
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name]));
+ end;
+ if MatchStrings(SR.Name, '*.txt') then
+ begin
+ LStatus.Caption := Format(GetLangStr('UpdateFile'), [SR.Name]);
+ LStatus.Hint := 'UpdateFile';
+ LStatus.Repaint;
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFile'), [SR.Name]));
+ if FileExists(PluginPath + SR.Name) then
+ DeleteFile(PluginPath + SR.Name);
+ if CopyFileEx(PChar(SavePath + SR.Name), PChar(PluginPath + SR.Name), Addr(CopyProgressFunc), nil, Addr(IMCancelCopy), COPY_FILE_RESTARTABLE) then
+ begin
+ DeleteFile(SavePath + SR.Name);
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileDone'), [SR.Name]));
+ end
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('UpdateFileErr'), [SR.Name]));
+ end;
+ until FindNext(SR) <> 0;
+ FindClose(SR);
+ end;
+end;
+
+procedure TMainForm.IMDownloader1Break(Sender: TObject);
+begin
+ LStatus.Caption := GetLangStr('DownloadStopped');
+ LStatus.Hint := 'DownloadStopped';
+ LAmount.Caption := CurrToStr(IMDownloader1.AcceptedSize/1024)+' '+GetLangStr('Kb');
+ LAmount.Repaint;
+ ButtonUpdateEnableStart;
+end;
+
+procedure TMainForm.IMDownloader1Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal);
+begin
+ QueryPerformanceCounter(C2);
+ ProgressBarDownloads.Max := MaxSize;
+ ProgressBarDownloads.Position := AcceptedSize;
+ LStatus.Caption := GetLangStr('Loading');
+ LStatus.Hint := 'Loading';
+ LAmount.Caption := CurrToStr(AcceptedSize/1024)+' '+GetLangStr('Kb');
+ LAmount.Repaint;
+ LSpeed.Caption := CurrToStr((AcceptedSize/1024)/((C2 - C1) / iCounterPerSec))+' '+GetLangStr('KbSec');
+ LSpeed.Repaint;
+end;
+
+procedure TMainForm.IMDownloader1Error(Sender: TObject; E: TIMDownloadError);
+var
+ S, HS: String;
+begin
+ case E of
+ deInternetOpen:
+ begin
+ S := GetLangStr('ErrInternetOpen');
+ HS := 'ErrInternetOpen';
+ end;
+ deInternetOpenUrl:
+ begin
+ S := GetLangStr('ErrInternetOpenURL');
+ HS := 'ErrInternetOpenURL';
+ end;
+ deDownloadingFile:
+ begin
+ S := GetLangStr('ErrDownloadingFile');
+ HS := 'ErrDownloadingFile';
+ end;
+ deRequest:
+ begin
+ S := GetLangStr('ErrRequest');
+ HS := 'ErrRequest';
+ end;
+ end;
+ LStatus.Caption := S;
+ LStatus.Hint := HS;
+ LogMemo.Lines.Add(S);
+ LAmount.Caption := CurrToStr(IMDownloader1.AcceptedSize/1024)+' '+GetLangStr('Kb');
+ LAmount.Repaint;
+ if not TrueHeader then
+ begin
+ LFileName.Caption := GetLangStr('Unknown');
+ LFileDescription.Caption := GetLangStr('Unknown');
+ LFileMD5.Caption := GetLangStr('Unknown');
+ end;
+ ButtonUpdateEnableStart;
+end;
+
+{
+ :
+ _|_|MD5Sum_|_
+}
+procedure TMainForm.IMDownloader1Headers(Sender: TObject; Headers: string);
+var
+ HeadersStrList: TStringList;
+ I: Integer;
+ Size: String;
+ Ch: Char;
+ ResultFilename, ResultFileDesc, ResultMD5Sum, ResultHeaders: String;
+ ResultFileSize: Integer;
+begin
+ //LogMemo.Lines.Add(Headers);
+ HeadersStrList := TStringList.Create;
+ HeadersStrList.Clear;
+ HeadersStrList.Text := Headers;
+ HeadersStrList.Delete(HeadersStrList.Count-1); // CRLF
+ if HeadersStrList.Count > 0 then
+ begin
+ ResultFilename := 'Test';
+ ResultFileDesc := 'Test';
+ ResultMD5Sum := '00000000000000000000000000000000';
+ ResultFileSize := 0;
+ LogMemo.Lines.Add(GetLangStr('ParseHeader'));
+ for I := 0 to HeadersStrList.Count - 1 do
+ begin
+ //LogMemo.Lines.Add(HeadersStrList[I]);
+ //
+ // Content-Disposition: attachment; filename="-"
+ // HTTP-
+ // get.php
+ if pos('content-disposition', lowercase(HeadersStrList[I])) > 0 then
+ begin
+ ResultFilename := HeadersStrList[I];
+ Delete(ResultFilename, 1, Pos('"', HeadersStrList[I]));
+ Delete(ResultFilename, Length(ResultFilename),1);
+ //LogMemo.Lines.Add('Filename: '+ResultFilename);
+ end;
+ //
+ // Content-Description: Desc
+ if pos('content-description', lowercase(HeadersStrList[I])) > 0 then
+ begin
+ ResultFileDesc := HeadersStrList[I];
+ Delete(ResultFileDesc, 1, Pos(':', HeadersStrList[I]));
+ Delete(ResultFileDesc, 1,1);
+ //LogMemo.Lines.Add('Description: '+ResultFileDesc);
+ end;
+ //
+ // Content-MD5Sum: MD5
+ if pos('content-md5sum', lowercase(HeadersStrList[I])) > 0 then
+ begin
+ ResultMD5Sum := HeadersStrList[I];
+ Delete(ResultMD5Sum, 1, Pos(':', HeadersStrList[I]));
+ Delete(ResultMD5Sum, 1,1);
+ //LogMemo.Lines.Add('MD5: '+ResultMD5Sum);
+ end;
+ //
+ // Content-Length:
+ if pos('content-length', lowercase(HeadersStrList[i])) > 0 then
+ begin
+ Size := '';
+ for Ch in HeadersStrList[I]do
+ if Ch in ['0'..'9'] then
+ Size := Size + Ch;
+ ResultFileSize := StrToIntDef(Size,-1);// + Length(HeadersStrList.Text);
+ end;
+ end;
+ ResultHeaders := ResultFilename + '|' + ResultFileDesc + '|' + ResultMD5Sum + '|' + IntToStr(ResultFileSize) + '|';
+ if(ResultHeaders <> 'Test|Test|00000000000000000000000000000000|' + IntToStr(ResultFileSize) + '|') then
+ begin
+ LogMemo.Lines.Add(GetLangStr('HeaderData'));
+ LogMemo.Lines.Add(GetLangStr('FileName') + ' ' + ResultFilename);
+ LogMemo.Lines.Add(GetLangStr('FileDesc') + ' ' + ResultFileDesc);
+ LogMemo.Lines.Add('MD5: ' + ResultMD5Sum);
+ LogMemo.Lines.Add(GetLangStr('FileSize') + ' ' + IntToStr(ResultFileSize));
+ LFileName.Caption := ResultFilename;
+ LFileDescription.Caption := ResultFileDesc;
+ LFileMD5.Caption := ResultMD5Sum;
+ HeaderFileName := ResultFilename;
+ HeaderMD5 := ResultMD5Sum;
+ HeaderFileSize := ResultFileSize;
+ if (CurrentUpdateStep = 0) and FileExists(PluginPath+HeaderFileName) then
+ DeleteFile(PluginPath+HeaderFileName);
+ TrueHeader := True;
+ end
+ else
+ begin
+ LogMemo.Lines.Add(GetLangStr('InvalidResponseHeader'));
+ LogMemo.Lines.Add(GetLangStr('InvalidResponseHeaderDesc'));
+ HeaderFileName := 'Test';
+ HeaderMD5 := '00000000000000000000000000000000';
+ HeaderFileSize := 0;
+ TrueHeader := False;
+ end;
+ end;
+ HeadersStrList.Free;
+end;
+
+procedure TMainForm.IMDownloader1MD5Checked(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: string);
+begin
+ MD5InMemory := MD5Str;
+ IMMD5Correct := MD5Correct;
+ IMSizeCorrect := SizeCorrect;
+end;
+
+procedure TMainForm.IMDownloader1StartDownload(Sender: TObject);
+begin
+ QueryPerformanceFrequency(iCounterPerSec);
+ QueryPerformanceCounter(C1);
+ ButtonUpdateEnableStop;
+ LStatus.Caption := GetLangStr('InitDownload');
+ LStatus.Hint := 'InitDownload';
+ LAmount.Caption := '0 '+GetLangStr('Kb');
+ LSpeed.Caption := '0 '+GetLangStr('KbSec');
+ LogMemo.Lines.Add(GetLangStr('InitDownloadFromURL') + ' ' + IMDownloader1.URL);
+end;
+
+procedure TMainForm.ButtonUpdateStopClick(Sender: TObject);
+begin
+ //
+ IMDownloader1.BreakDownload;
+ //
+ IMCancelCopy := True;
+end;
+
+procedure TMainForm.CBUseProxyClick(Sender: TObject);
+begin
+ if CBUseProxy.Checked then
+ begin
+ EProxyAddress.Enabled := True;
+ EProxyPort.Enabled := True;
+ CBProxyAuth.Enabled := True;
+ end
+ else
+ begin
+ EProxyAddress.Enabled := False;
+ EProxyPort.Enabled := False;
+ CBProxyAuth.Enabled := False;
+ end;
+end;
+
+procedure TMainForm.CBProxyAuthClick(Sender: TObject);
+begin
+ if CBProxyAuth.Checked then
+ begin
+ EProxyUser.Enabled := True;
+ EProxyUserPasswd.Enabled := True;
+ end
+ else
+ begin
+ EProxyUser.Enabled := False;
+ EProxyUserPasswd.Enabled := False;
+ end;
+end;
+
+procedure TMainForm.ButtonUpdateEnableStart;
+begin
+ ButtonUpdate.OnClick := ButtonUpdateStartClick;
+ ButtonUpdate.Caption := GetLangStr('UpdateButton');
+ ButtonUpdate.Hint := 'UpdateButton';
+ ButtonSettings.Enabled := True;
+ CBIMClientType.Enabled := True;
+ CBDBType.Enabled := True;
+end;
+
+procedure TMainForm.ButtonUpdateEnableStop;
+begin
+ ButtonUpdate.OnClick := ButtonUpdateStopClick;
+ ButtonUpdate.Caption := GetLangStr('StopButton');
+ ButtonUpdate.Hint := 'StopButton';
+ ButtonSettings.Enabled := False;
+ CBIMClientType.Enabled := False;
+ CBDBType.Enabled := False;
+end;
+
+procedure TMainForm.CBDBTypeChange(Sender: TObject);
+begin
+ DBType := CBDBType.Items[CBDBType.ItemIndex];
+end;
+
+procedure TMainForm.CBIMClientTypeChange(Sender: TObject);
+begin
+ IMClientType := CBIMClientType.Items[CBIMClientType.ItemIndex];
+end;
+
+{ }
+procedure TMainForm.CBLangChange(Sender: TObject);
+begin
+ FLanguage := CBLang.Items[CBLang.ItemIndex];
+ DefaultLanguage := CBLang.Items[CBLang.ItemIndex];
+ CoreLanguageChanged;
+end;
+
+{ }
+procedure TMainForm.FindLangFile;
+var
+ SR: TSearchRec;
+ I: Integer;
+begin
+ CBLang.Items.Clear;
+ if FindFirst(PluginPath + dirLangs + '\*.*', faAnyFile or faDirectory, SR) = 0 then
+ begin
+ repeat
+ if (SR.Attr = faDirectory) and ((SR.Name = '.') or (SR.Name = '..')) then // . ..
+ begin
+ Continue; //
+ end;
+ if MatchStrings(SR.Name, '*.xml') then
+ begin
+ //
+ CBLang.Items.Add(ExtractFileNameEx(SR.Name, False));
+ end;
+ until FindNext(SR) <> 0;
+ FindClose(SR);
+ end;
+ if CBLang.Items.Count > 0 then
+ begin
+ for I := 0 to CBLang.Items.Count-1 do
+ begin
+ if CBLang.Items[I] = CoreLanguage then
+ CBLang.ItemIndex := I;
+ end;
+ end
+ else
+ begin
+ CBLang.Items.Add(GetLangStr('NotFoundLangFile'));
+ CBLang.ItemIndex := 0;
+ CBLang.Enabled := False;
+ end;
+end;
+
+{ WM_LANGUAGECHANGED }
+procedure TMainForm.OnLanguageChanged(var Msg: TMessage);
+begin
+ LoadLanguageStrings;
+end;
+
+{ }
+procedure TMainForm.CoreLanguageChanged;
+var
+ LangFile: String;
+begin
+ if CoreLanguage = '' then
+ Exit;
+ try
+ LangFile := PluginPath + dirLangs + CoreLanguage + '.xml';
+ if FileExists(LangFile) then
+ LangDoc.LoadFromFile(LangFile)
+ else
+ begin
+ if FileExists(PluginPath + dirLangs + defaultLangFile) then
+ LangDoc.LoadFromFile(PluginPath + dirLangs + defaultLangFile)
+ else
+ begin
+ MsgDie(ProgramsName, 'Not found any language file!');
+ Exit;
+ end;
+ end;
+ Global.CoreLanguage := CoreLanguage;
+ SendMessage(MainFormHandle, WM_LANGUAGECHANGED, 0, 0);
+ //SendMessage(AboutFormHandle, WM_LANGUAGECHANGED, 0, 0);
+ except
+ on E: Exception do
+ MsgDie(ProgramsName, 'Error on CoreLanguageChanged: ' + E.Message + sLineBreak +
+ 'CoreLanguage: ' + CoreLanguage);
+ end;
+end;
+
+{ }
+procedure TMainForm.LoadLanguageStrings;
+begin
+ if IMClientType <> 'Unknown' then
+ Caption := ProgramsName + ' for ' + IMClientType + ' (' + MyAccount + ')'
+ else
+ Caption := ProgramsName;
+ if ButtonUpdate.Hint = 'UpdateButton' then
+ begin
+ ButtonUpdate.Caption := GetLangStr('UpdateButton');
+ ButtonUpdate.Hint := 'UpdateButton';
+ end
+ else
+ begin
+ ButtonUpdate.Caption := GetLangStr('StopButton');
+ ButtonUpdate.Hint := 'StopButton';
+ end;
+ ButtonSettings.Caption := GetLangStr('SettingsButton');
+ LIMClientType.Caption := GetLangStr('IMClientType');
+ LDBType.Caption := GetLangStr('LDBType');
+ LLanguage.Caption := GetLangStr('Language');
+ TabSheetSettings.Caption := GetLangStr('GeneralSettings');
+ TabSheetConnectSettings.Caption := GetLangStr('ConnectionSettings');
+ TabSheetLog.Caption := GetLangStr('Logs');
+ GBSettings.Caption := GetLangStr('GeneralSettings');
+ GBConnectSettings.Caption := GetLangStr('ConnectionSettings');
+ CBUseProxy.Caption := GetLangStr('UseProxy');
+ LProxyAddress.Caption := GetLangStr('ProxyAddress');
+ LProxyPort.Caption := GetLangStr('ProxyPort');
+ CBProxyAuth.Caption := GetLangStr('ProxyAuth');
+ LProxyUser.Caption := GetLangStr('ProxyUser');
+ LProxyUserPasswd.Caption := GetLangStr('ProxyUserPasswd');
+ EProxyAddress.Left := LProxyAddress.Left + LProxyAddress.Width + 5;
+ LProxyPort.Left := EProxyAddress.Left + EProxyAddress.Width + 5;
+ EProxyPort.Left := LProxyPort.Left + LProxyPort.Width + 5;
+ GBUpdater.Caption := GetLangStr('Update');
+ LStatus.Caption := GetLangStr(LStatus.Hint);
+ LAmountDesc.Caption := GetLangStr('Amount');
+ LSpeedDesc.Caption := GetLangStr('Speed');
+ LFileNameDesc.Caption := GetLangStr('FileName');
+ LFileDesc.Caption := GetLangStr('FileDesc');
+ LAmount.Left := LAmountDesc.Left + LAmountDesc.Width + 5;
+ LSpeed.Left := LSpeedDesc.Left + LSpeedDesc.Width + 5;
+ LFileName.Left := LFileNameDesc.Left + LFileNameDesc.Width + 5;
+ LFileDescription.Left := LFileDesc.Left + LFileDesc.Width + 5;
+ if ButtonSettings.Enabled then
+ begin
+ LFileName.Caption := GetLangStr('Unknown');
+ LFileDescription.Caption := GetLangStr('Unknown');
+ LFileMD5.Caption := GetLangStr('Unknown');
+ end;
+end;
+
+function TMainForm.EndTask(TaskName, FormName: String): Boolean;
+begin
+ Result := False;
+ if IsProcessRun(TaskName, FormName) then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('InMemoryFoundProcess'), [TaskName, IntToStr(GetProcessID(TaskName))]));
+ LogMemo.Lines.Add(GetLangStr('SendExitCommand'));
+ OnSendMessageToOneComponent(FormName, '009');
+ Sleep(1200);
+ LogMemo.Lines.Add(Format(GetLangStr('SearchProcessInMemory'), [TaskName]));
+ if IsProcessRun(TaskName, FormName) then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('InMemoryFoundProcess'), [TaskName, IntToStr(GetProcessID(TaskName))]));
+ LogMemo.Lines.Add(Format(GetLangStr('KillProcess'), [TaskName]));
+ if KillTask(TaskName, FormName) = 1 then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('KillProcessDone'), [TaskName]));
+ Result := True;
+ end
+ else
+ begin
+ if Global_IMProcessPID <> 0 then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('NotKillProcess'), [TaskName]));
+ LogMemo.Lines.Add(Format(GetLangStr('SeDebugPrivilege'), [TaskName]));
+ if ProcessTerminate(Global_IMProcessPID) then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('SeDebugPrivilegeDone'), [TaskName]));
+ Result := True;
+ end
+ else
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('NotKillSeDebugPrivilege'), [TaskName]));
+ Result := False;
+ end;
+ end;
+ end;
+ end
+ else
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('InMemoryNotFoundProcess'), [TaskName]));
+ Result := True;
+ end;
+ end
+ else
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('InMemoryNotFoundProcess'), [TaskName]));
+ Result := True;
+ end;
+end;
+
+{ WM_COPYDATA }
+procedure TMainForm.OnControlReq(var Msg : TWMCopyData);
+var
+ ControlStr, EncryptControlStr: String;
+ copyDataType : TCopyDataType;
+ GotChars: Integer;
+begin
+ copyDataType := TCopyDataType(Msg.CopyDataStruct.dwData);
+ if copyDataType = cdtString then
+ begin
+ GotChars := Msg.CopyDataStruct.cbData div SizeOf(Char);
+ SetLength(EncryptControlStr, GotChars);
+ Move(Msg.CopyDataStruct.lpData^, PChar(EncryptControlStr)^, GotChars * sizeof(Char));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnControlReq: : ' + EncryptControlStr, 1);
+ ControlStr := DecryptStr(EncryptControlStr);
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnControlReq: : ' + ControlStr, 1);
+ //Msg.Result := 2006;
+ if ControlStr = 'Russian' then
+ begin
+ FLanguage := 'Russian';
+ CoreLanguageChanged;
+ end
+ else if ControlStr = 'English' then
+ begin
+ FLanguage := 'English';
+ CoreLanguageChanged;
+ end;
+ // 001 - HistoryToDB.ini
+ if ControlStr = '001' then
+ begin
+ //
+ LoadINI(ProfilePath, true);
+ end;
+ // 004 - -
+ if ControlStr = '0040' then //
+ AntiBoss(False);
+ if ControlStr = '0041' then //
+ AntiBoss(True);
+ // 003 -
+ {if (ControlStr = '003') and (ButtonUpdate.Enabled) then
+ Close;}
+ // 009 -
+ if ControlStr = '009' then
+ begin
+ IMDownloader1.BreakDownload;
+ Close;
+ end;
+ end;
+end;
+
+{ - }
+procedure TMainForm.AntiBoss(HideAllForms: Boolean);
+begin
+ if not Assigned(MainForm) then Exit;
+ if HideAllForms then
+ begin
+ ShowWindow(MainForm.Handle, SW_HIDE);
+ MainForm.Hide;
+ //ShowWindow(AboutForm.Handle, SW_HIDE);
+ //AboutForm.Hide;
+ end
+ else
+ begin
+ // ,
+ if Global_MainForm_Showing then
+ begin
+ ShowWindow(MainForm.Handle, SW_SHOW);
+ MainForm.Show;
+ // ,
+ if MainForm.WindowState = wsMinimized then
+ begin
+ MainForm.FormStyle := fsStayOnTop;
+ MainForm.WindowState := wsNormal;
+ MainForm.FormStyle := fsNormal;
+ end;
+ if MainForm.WindowState = wsNormal then
+ begin
+ MainForm.FormStyle := fsStayOnTop;
+ MainForm.FormStyle := fsNormal;
+ end;
+ end;
+ {if Global_AboutForm_Showing then
+ begin
+ ShowWindow(AboutForm.Handle, SW_SHOW);
+ AboutForm.Show;
+ end;}
+ end;
+end;
+
+procedure TMainForm.RunIMClient(IMClientName: String; IMProcessArray: TProcessInfoArray);
+var
+ i: Integer;
+begin
+ for i := Low(IMProcessArray) to High(IMProcessArray) do
+ begin
+ if LowerCase(IMClientName) = LowerCase(IMProcessArray[i].ProcessName) then
+ begin
+ if FileExists(IMProcessArray[i].ProcessPath) then
+ begin
+ LogMemo.Lines.Add(Format(GetLangStr('StartProgram'), [IMProcessArray[i].ProcessPath + IMProcessArray[i].ProcessParamCmd]));
+ ShellExecute(0, 'open', PWideChar(IMProcessArray[i].ProcessPath), PWideChar(' '+IMProcessArray[i].ProcessParamCmd), nil, SW_SHOWNORMAL);
+ Sleep(500);
+ if IsProcessRun(IMProcessArray[i].ProcessName) then
+ LogMemo.Lines.Add(Format(GetLangStr('StartProgramDone'), [IMProcessArray[i].ProcessPath]))
+ else
+ LogMemo.Lines.Add(Format(GetLangStr('StartProgramFail'), [IMProcessArray[i].ProcessPath]));
+ end;
+ end;
+ end;
+end;
+
+procedure TMainForm.RunAllIMClients;
+begin
+ if IMClientType = 'QIP' then
+ RunIMClient('qip.exe', QIPProcessInfo);
+ if (IMClientType = 'Miranda') or (IMClientType = 'MirandaNG') then
+ {$IfDef WIN32}
+ RunIMClient('miranda32.exe', MirandaProcessInfo);
+ {$Else}
+ RunIMClient('miranda64.exe', MirandaProcessInfo);
+ {$EndIf}
+ if IMClientType = 'RnQ' then
+ begin
+ RunIMClient('R&Q.exe', RnQProcessInfo);
+ RunIMClient('rnq.exe', RnQProcessInfo);
+ end;
+ if IMClientType = 'Skype' then
+ begin
+ if SystemLang = 'Russian' then
+ begin
+ if FileExists(PluginPath + 'installupdater-ru.cmd') then
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'installupdater-ru.cmd'), nil, nil, SW_HIDE)
+ else
+ RunIMClient('skype.exe', SkypeProcessInfo);
+ end
+ else
+ begin
+ if FileExists(PluginPath + 'installupdater-en.cmd') then
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'installupdater-en.cmd'), nil, nil, SW_HIDE)
+ else
+ RunIMClient('skype.exe', SkypeProcessInfo);
+ end;
+ end;
+ // Dropbox
+ {if not IsProcessRun('Dropbox.exe') then
+ RunIMClient('Dropbox.exe', DropboxProcessInfo);}
+end;
+
+function CopyProgressFunc(TotalFileSize: Int64; TotalBytesTransferred: Int64;
+ StreamSize: Int64; StreamBytesTransferred: Int64; dwStreamNumber: DWORD;
+ dwCallbackReason: DWORD; hSourceFile: THandle; hDestinationFile: THandle;
+ lpData: Pointer): DWORD; stdcall;
+begin
+ MainForm.ProgressBarDownloads.Position := 100 * TotalBytesTransferred div TotalFileSize;
+ Application.ProcessMessages;
+ CopyProgressFunc := PROGRESS_CONTINUE;
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas
new file mode 100644
index 0000000000..0f6a2bd831
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/NTNative.pas
@@ -0,0 +1,210 @@
+unit NTNative;
+
+interface
+
+uses Classes, SysUtils, Windows;
+
+type
+ Pointer32 = ULONG;
+ THANDLE32 = ULONG;
+
+ _UNICODE_STRING = record
+ Length: Word;
+ MaximumLength: Word;
+ Buffer: LPWSTR;
+ end;
+ UNICODE_STRING = _UNICODE_STRING;
+
+ //http://msdn.microsoft.com/en-us/library/windows/desktop/ms684280%28v=vs.85%29.aspx
+ PROCESS_BASIC_INFORMATION = record
+ Reserved1 : Pointer;
+ PebBaseAddress: Pointer;
+ Reserved2: array [0..1] of Pointer;
+ UniqueProcessId: ULONG_PTR;
+ Reserved3: Pointer;
+ end;
+
+
+ //http://undocumented.ntinternals.net/UserMode/Structures/RTL_DRIVE_LETTER_CURDIR.html
+ _RTL_DRIVE_LETTER_CURDIR = record
+ Flags: Word;
+ Length: Word;
+ TimeStamp: ULONG;
+ DosPath: UNICODE_STRING;
+ end;
+ RTL_DRIVE_LETTER_CURDIR = _RTL_DRIVE_LETTER_CURDIR;
+
+ _CURDIR = record
+ DosPath: UNICODE_STRING;
+ Handle: THANDLE;
+ end;
+ CURDIR = _CURDIR;
+
+ //http://undocumented.ntinternals.net/UserMode/Structures/RTL_USER_PROCESS_PARAMETERS.html
+ _RTL_USER_PROCESS_PARAMETERS = record
+ MaximumLength: ULONG;
+ Length: ULONG;
+ Flags: ULONG;
+ DebugFlags: ULONG;
+ ConsoleHandle: THANDLE;
+ ConsoleFlags: ULONG;
+ StandardInput: THANDLE;
+ StandardOutput: THANDLE;
+ StandardError: THANDLE;
+ CurrentDirectory: CURDIR;
+ DllPath: UNICODE_STRING;
+ ImagePathName: UNICODE_STRING;
+ CommandLine: UNICODE_STRING;
+ Environment: Pointer;
+ StartingX: ULONG;
+ StartingY: ULONG;
+ CountX: ULONG;
+ CountY: ULONG;
+ CountCharsX: ULONG;
+ CountCharsY: ULONG;
+ FillAttribute: ULONG;
+ WindowFlags: ULONG;
+ ShowWindowFlags: ULONG;
+ WindowTitle: UNICODE_STRING;
+ DesktopInfo: UNICODE_STRING;
+ ShellInfo: UNICODE_STRING;
+ RuntimeData: UNICODE_STRING;
+ CurrentDirectories: array[0..31] of RTL_DRIVE_LETTER_CURDIR;
+ end;
+ RTL_USER_PROCESS_PARAMETERS = _RTL_USER_PROCESS_PARAMETERS;
+ PRTL_USER_PROCESS_PARAMETERS = ^RTL_USER_PROCESS_PARAMETERS;
+
+ _PEB = record
+ Reserved1 : array [0..1] of Byte;
+ BeingDebugged : Byte;
+ Reserved2 : Byte;
+ Reserved3 : array [0..1] of Pointer;
+ Ldr : Pointer;
+ ProcessParameters : PRTL_USER_PROCESS_PARAMETERS;
+ Reserved4 : array [0..102] of Byte;
+ Reserved5 : array [0..51] of Pointer;
+ PostProcessInitRoutine : Pointer;
+ Reserved6 : array [0..127] of byte;
+ Reserved7 : Pointer;
+ SessionId : ULONG;
+ end;
+ PEB=_PEB;
+
+{$IFDEF CPUX64}
+ _UNICODE_STRING32 = record
+ Length: Word;
+ MaximumLength: Word;
+ Buffer: Pointer32;
+ end;
+ UNICODE_STRING32 = _UNICODE_STRING32;
+
+ _RTL_DRIVE_LETTER_CURDIR32 = record
+ Flags: Word;
+ Length: Word;
+ TimeStamp: ULONG;
+ DosPath: UNICODE_STRING32;
+ end;
+ RTL_DRIVE_LETTER_CURDIR32 = _RTL_DRIVE_LETTER_CURDIR32;
+
+ _CURDIR32 = record
+ DosPath: UNICODE_STRING32;
+ Handle: THANDLE32;
+ end;
+ CURDIR32 = _CURDIR32;
+
+ _RTL_USER_PROCESS_PARAMETERS32 = record
+ MaximumLength: ULONG;
+ Length: ULONG;
+ Flags: ULONG;
+ DebugFlags: ULONG;
+ ConsoleHandle: THANDLE32;
+ ConsoleFlags: ULONG;
+ StandardInput: THANDLE32;
+ StandardOutput: THANDLE32;
+ StandardError: THANDLE32;
+ CurrentDirectory: CURDIR32;
+ DllPath: UNICODE_STRING32;
+ ImagePathName: UNICODE_STRING32;
+ CommandLine: UNICODE_STRING32;
+ Environment: Pointer32;
+ StartingX: ULONG;
+ StartingY: ULONG;
+ CountX: ULONG;
+ CountY: ULONG;
+ CountCharsX: ULONG;
+ CountCharsY: ULONG;
+ FillAttribute: ULONG;
+ WindowFlags: ULONG;
+ ShowWindowFlags: ULONG;
+ WindowTitle: UNICODE_STRING32;
+ DesktopInfo: UNICODE_STRING32;
+ ShellInfo: UNICODE_STRING32;
+ RuntimeData: UNICODE_STRING32;
+ CurrentDirectories: array[0..31] of RTL_DRIVE_LETTER_CURDIR32;
+ end;
+ RTL_USER_PROCESS_PARAMETERS32 = _RTL_USER_PROCESS_PARAMETERS32;
+ PRTL_USER_PROCESS_PARAMETERS32 = ^RTL_USER_PROCESS_PARAMETERS32;
+
+ _PEB32 = record
+ Reserved1 : array [0..1] of Byte;
+ BeingDebugged : Byte;
+ Reserved2 : Byte;
+ Reserved3 : array [0..1] of Pointer32;
+ Ldr : Pointer32;
+ ProcessParameters : Pointer32;//PRTL_USER_PROCESS_PARAMETERS;
+ Reserved4 : array [0..102] of Byte;
+ Reserved5 : array [0..51] of Pointer32;
+ PostProcessInitRoutine : Pointer32;
+ Reserved6 : array [0..127] of byte;
+ Reserved7 : Pointer32;
+ SessionId : ULONG;
+ end;
+ PEB32=_PEB32;
+{$ENDIF}
+
+type
+ TIsWow64Process = function(Handle:THandle; var IsWow64 : BOOL) : BOOL; stdcall;
+var
+ _IsWow64Process : TIsWow64Process;
+
+function NtQueryInformationProcess(ProcessHandle : THandle; ProcessInformationClass : DWORD; ProcessInformation : Pointer; ProcessInformationLength : ULONG; ReturnLength : PULONG ): LongInt; stdcall; external 'ntdll.dll';
+function NtQueryVirtualMemory(ProcessHandle : THandle; BaseAddress : Pointer; MemoryInformationClass : DWORD; MemoryInformation : Pointer; MemoryInformationLength : ULONG; ReturnLength : PULONG ): LongInt; stdcall; external 'ntdll.dll';
+function ProcessIsX64(hProcess: DWORD): Boolean;
+procedure Init_IsWow64Process;
+
+implementation
+
+procedure Init_IsWow64Process;
+var
+ hKernel32 : Integer;
+begin
+ hKernel32 := LoadLibrary(kernel32);
+ if (hKernel32 = 0) then RaiseLastOSError;
+ try
+ _IsWow64Process := GetProcAddress(hkernel32, 'IsWow64Process');
+ finally
+ FreeLibrary(hKernel32);
+ end;
+end;
+
+function ProcessIsX64(hProcess: DWORD): Boolean;
+var
+ IsWow64: BOOL;
+begin
+ Result := False;
+ {$IFNDEF CPUX64}
+ Exit;
+ {$ENDIF}
+ if not Assigned(_IsWow64Process) then
+ Init_IsWow64Process;
+
+ if Assigned(_IsWow64Process) then
+ begin
+ if (_IsWow64Process(hProcess, IsWow64)) then
+ Result := not IsWow64
+ else
+ RaiseLastOSError;
+ end;
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc
new file mode 100644
index 0000000000..c31a08c04a
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/jedi.inc
@@ -0,0 +1,1430 @@
+{$IFNDEF JEDI_INC}
+{$DEFINE JEDI_INC}
+
+{**************************************************************************************************}
+{ }
+{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");}
+{ you may not use this file except in compliance with the License. You may obtain a copy of the }
+{ License at http://www.mozilla.org/MPL/ }
+{ }
+{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
+{ ANY KIND, either express or implied. See the License for the specific language governing rights }
+{ and limitations under the License. }
+{ }
+{ The Original Code is: jedi.inc. }
+{ The Initial Developer of the Original Code is Project JEDI http://www.delphi-jedi.org }
+{ }
+{ Alternatively, the contents of this file may be used under the terms of the GNU Lesser General }
+{ Public License (the "LGPL License"), in which case the provisions of the LGPL License are }
+{ applicable instead of those above. If you wish to allow use of your version of this file only }
+{ under the terms of the LGPL License and not to allow others to use your version of this file }
+{ under the MPL, indicate your decision by deleting the provisions above and replace them with }
+{ the notice and other provisions required by the LGPL License. If you do not delete the }
+{ provisions above, a recipient may use your version of this file under either the MPL or the }
+{ LGPL License. }
+{ }
+{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html }
+{ }
+{**************************************************************************************************}
+{ }
+{ This file defines various generic compiler directives used in different libraries, e.g. in the }
+{ JEDI Code Library (JCL) and JEDI Visual Component Library Library (JVCL). The directives in }
+{ this file are of generic nature and consist mostly of mappings from the VERXXX directives }
+{ defined by Delphi, C++Builder and FPC to friendly names such as DELPHI5 and }
+{ SUPPORTS_WIDESTRING. These friendly names are subsequently used in the libraries to test for }
+{ compiler versions and/or whether the compiler supports certain features (such as widestrings or }
+{ 64 bit integers. The libraries provide an additional, library specific, include file. For the }
+{ JCL e.g. this is jcl.inc. These files should be included in source files instead of this file }
+{ (which is pulled in automatically). }
+{ }
+{**************************************************************************************************}
+{ }
+{ Last modified: $Date:: 2012-09-04 16:01:38 +0200 (út, 04 9 2012) $ }
+{ Revision: $Rev:: 161 $ }
+{ Author: $Author:: outchy $ }
+{ }
+{**************************************************************************************************}
+
+(*
+
+- Development environment directives
+
+ This file defines two directives to indicate which development environment the
+ library is being compiled with. Currently this can either be Delphi, Kylix,
+ C++Builder or FPC.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ DELPHI Defined if compiled with Delphi
+ KYLIX Defined if compiled with Kylix
+ DELPHICOMPILER Defined if compiled with Delphi or Kylix/Delphi
+ BCB Defined if compiled with C++Builder
+ CPPBUILDER Defined if compiled with C++Builder (alias for BCB)
+ BCBCOMPILER Defined if compiled with C++Builder or Kylix/C++
+ DELPHILANGUAGE Defined if compiled with Delphi, Kylix or C++Builder
+ BORLAND Defined if compiled with Delphi, Kylix or C++Builder
+ FPC Defined if compiled with FPC
+
+- Platform Directives
+
+ Platform directives are not all explicitly defined in this file, some are
+ defined by the compiler itself. They are listed here only for completeness.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ WIN32 Defined when target platform is 32 bit Windows
+ WIN64 Defined when target platform is 64 bit Windows
+ MSWINDOWS Defined when target platform is 32 bit Windows
+ LINUX Defined when target platform is Linux
+ UNIX Defined when target platform is Unix-like (including Linux)
+ CLR Defined when target platform is .NET
+
+- Architecture directives. These are auto-defined by FPC
+ CPU32 and CPU64 are mostly for generic pointer size dependant differences rather
+ than for a specific architecture.
+
+ CPU386 Defined when target platform is native x86 (win32)
+ CPUx86_64 Defined when target platform is native x86_64 (win64)
+ CPU32 Defined when target is 32-bit
+ CPU64 Defined when target is 64-bit
+ CPUASM Defined when target assembler is available
+
+- Visual library Directives
+
+ The following directives indicate for a visual library. In a Delphi/BCB
+ (Win32) application you need to define the VisualCLX symbol in the project
+ options, if you want to use the VisualCLX library. Alternatively you can use
+ the IDE expert, which is distributed with the JCL to do this automatically.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ VCL Defined for Delphi/BCB (Win32) exactly if VisualCLX is not defined
+ VisualCLX Defined for Kylix; needs to be defined for Delphi/BCB to
+ use JCL with VisualCLX applications.
+
+
+- Other cross-platform related defines
+
+ These symbols are intended to help in writing portable code.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ PUREPASCAL Code is machine-independent (as opposed to assembler code)
+ Win32API Code is specific for the Win32 API;
+ use instead of "{$IFNDEF CLR} {$IFDEF MSWINDOWS}" constructs
+
+
+- Delphi Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. These directives are only defined if
+ the compiler is Delphi (ie DELPHI is defined).
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ DELPHI1 Defined when compiling with Delphi 1 (Codename WASABI/MANGO)
+ DELPHI2 Defined when compiling with Delphi 2 (Codename POLARIS)
+ DELPHI3 Defined when compiling with Delphi 3 (Codename IVORY)
+ DELPHI4 Defined when compiling with Delphi 4 (Codename ALLEGRO)
+ DELPHI5 Defined when compiling with Delphi 5 (Codename ARGUS)
+ DELPHI6 Defined when compiling with Delphi 6 (Codename ILLIAD)
+ DELPHI7 Defined when compiling with Delphi 7 (Codename AURORA)
+ DELPHI8 Defined when compiling with Delphi 8 (Codename OCTANE)
+ DELPHI2005 Defined when compiling with Delphi 2005 (Codename DIAMONDBACK)
+ DELPHI9 Alias for DELPHI2005
+ DELPHI10 Defined when compiling with Delphi 2006 (Codename DEXTER)
+ DELPHI2006 Alias for DELPHI10
+ DELPHI11 Defined when compiling with Delphi 2007 for Win32 (Codename SPACELY)
+ DELPHI2007 Alias for DELPHI11
+ DELPHI12 Defined when compiling with Delphi 2009 for Win32 (Codename TIBURON)
+ DELPHI2009 Alias for DELPHI12
+ DELPHI14 Defined when compiling with Delphi 2010 for Win32 (Codename WEAVER)
+ DELPHI2010 Alias for DELPHI14
+ DELPHI15 Defined when compiling with Delphi XE for Win32 (Codename FULCRUM)
+ DELPHIXE Alias for DELPHI15
+ DELPHI16 Defined when compiling with Delphi XE2 for Win32 (Codename PULSAR)
+ DELPHIXE2 Alias for DELPHI16
+ DELPHI17 Defined when compiling with Delphi XE3 for Win32 (Codename WATERDRAGON)
+ DELPHIXE3 Alias for DELPHI17
+ DELPHI1_UP Defined when compiling with Delphi 1 or higher
+ DELPHI2_UP Defined when compiling with Delphi 2 or higher
+ DELPHI3_UP Defined when compiling with Delphi 3 or higher
+ DELPHI4_UP Defined when compiling with Delphi 4 or higher
+ DELPHI5_UP Defined when compiling with Delphi 5 or higher
+ DELPHI6_UP Defined when compiling with Delphi 6 or higher
+ DELPHI7_UP Defined when compiling with Delphi 7 or higher
+ DELPHI8_UP Defined when compiling with Delphi 8 or higher
+ DELPHI2005_UP Defined when compiling with Delphi 2005 or higher
+ DELPHI9_UP Alias for DELPHI2005_UP
+ DELPHI10_UP Defined when compiling with Delphi 2006 or higher
+ DELPHI2006_UP Alias for DELPHI10_UP
+ DELPHI11_UP Defined when compiling with Delphi 2007 for Win32 or higher
+ DELPHI2007_UP Alias for DELPHI11_UP
+ DELPHI12_UP Defined when compiling with Delphi 2009 for Win32 or higher
+ DELPHI2009_UP Alias for DELPHI12_UP
+ DELPHI14_UP Defined when compiling with Delphi 2010 for Win32 or higher
+ DELPHI2010_UP Alias for DELPHI14_UP
+ DELPHI15_UP Defined when compiling with Delphi XE for Win32 or higher
+ DELPHIXE_UP Alias for DELPHI15_UP
+ DELPHI16_UP Defined when compiling with Delphi XE2 for Win32 or higher
+ DELPHIXE2_UP Alias for DELPHI16_UP
+ DELPHI17_UP Defined when compiling with Delphi XE3 for Win32 or higher
+ DELPHIXE3_UP Alias for DELPHI17_UP
+
+
+- Kylix Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. These directives are only defined if
+ the compiler is Kylix (ie KYLIX is defined).
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ KYLIX1 Defined when compiling with Kylix 1
+ KYLIX2 Defined when compiling with Kylix 2
+ KYLIX3 Defined when compiling with Kylix 3 (Codename CORTEZ)
+ KYLIX1_UP Defined when compiling with Kylix 1 or higher
+ KYLIX2_UP Defined when compiling with Kylix 2 or higher
+ KYLIX3_UP Defined when compiling with Kylix 3 or higher
+
+
+- Delphi Compiler Versions (Delphi / Kylix, not in BCB mode)
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ DELPHICOMPILER1 Defined when compiling with Delphi 1
+ DELPHICOMPILER2 Defined when compiling with Delphi 2
+ DELPHICOMPILER3 Defined when compiling with Delphi 3
+ DELPHICOMPILER4 Defined when compiling with Delphi 4
+ DELPHICOMPILER5 Defined when compiling with Delphi 5
+ DELPHICOMPILER6 Defined when compiling with Delphi 6 or Kylix 1, 2 or 3
+ DELPHICOMPILER7 Defined when compiling with Delphi 7
+ DELPHICOMPILER8 Defined when compiling with Delphi 8
+ DELPHICOMPILER9 Defined when compiling with Delphi 2005
+ DELPHICOMPILER10 Defined when compiling with Delphi Personality of BDS 4.0
+ DELPHICOMPILER11 Defined when compiling with Delphi 2007 for Win32
+ DELPHICOMPILER12 Defined when compiling with Delphi Personality of BDS 6.0
+ DELPHICOMPILER14 Defined when compiling with Delphi Personality of BDS 7.0
+ DELPHICOMPILER15 Defined when compiling with Delphi Personality of BDS 8.0
+ DELPHICOMPILER16 Defined when compiling with Delphi Personality of BDS 9.0
+ DELPHICOMPILER17 Defined when compiling with Delphi Personality of BDS 10.0
+ DELPHICOMPILER1_UP Defined when compiling with Delphi 1 or higher
+ DELPHICOMPILER2_UP Defined when compiling with Delphi 2 or higher
+ DELPHICOMPILER3_UP Defined when compiling with Delphi 3 or higher
+ DELPHICOMPILER4_UP Defined when compiling with Delphi 4 or higher
+ DELPHICOMPILER5_UP Defined when compiling with Delphi 5 or higher
+ DELPHICOMPILER6_UP Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 or higher
+ DELPHICOMPILER7_UP Defined when compiling with Delphi 7 or higher
+ DELPHICOMPILER8_UP Defined when compiling with Delphi 8 or higher
+ DELPHICOMPILER9_UP Defined when compiling with Delphi 2005
+ DELPHICOMPILER10_UP Defined when compiling with Delphi 2006 or higher
+ DELPHICOMPILER11_UP Defined when compiling with Delphi 2007 for Win32 or higher
+ DELPHICOMPILER12_UP Defined when compiling with Delphi 2009 for Win32 or higher
+ DELPHICOMPILER14_UP Defined when compiling with Delphi 2010 for Win32 or higher
+ DELPHICOMPILER15_UP Defined when compiling with Delphi XE for Win32 or higher
+ DELPHICOMPILER16_UP Defined when compiling with Delphi XE2 for Win32 or higher
+ DELPHICOMPILER17_UP Defined when compiling with Delphi XE3 for Win32 or higher
+
+
+- C++Builder Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. These directives are only defined if
+ the compiler is C++Builder (ie BCB is defined).
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ BCB1 Defined when compiling with C++Builder 1
+ BCB3 Defined when compiling with C++Builder 3
+ BCB4 Defined when compiling with C++Builder 4
+ BCB5 Defined when compiling with C++Builder 5 (Codename RAMPAGE)
+ BCB6 Defined when compiling with C++Builder 6 (Codename RIPTIDE)
+ BCB10 Defined when compiling with C++Builder Personality of BDS 4.0 (also known as C++Builder 2006) (Codename DEXTER)
+ BCB11 Defined when compiling with C++Builder Personality of RAD Studio 2007 (also known as C++Builder 2007) (Codename COGSWELL)
+ BCB12 Defined when compiling with C++Builder Personality of RAD Studio 2009 (also known as C++Builder 2009) (Codename TIBURON)
+ BCB14 Defined when compiling with C++Builder Personality of RAD Studio 2010 (also known as C++Builder 2010) (Codename WEAVER)
+ BCB15 Defined when compiling with C++Builder Personality of RAD Studio XE (also known as C++Builder XE) (Codename FULCRUM)
+ BCB16 Defined when compiling with C++Builder Personality of RAD Studio XE2 (also known as C++Builder XE2) (Codename PULSAR)
+ BCB17 Defined when compiling with C++Builder Personality of RAD Studio XE3 (also known as C++Builder XE3) (Codename WATERDRAGON)
+ BCB1_UP Defined when compiling with C++Builder 1 or higher
+ BCB3_UP Defined when compiling with C++Builder 3 or higher
+ BCB4_UP Defined when compiling with C++Builder 4 or higher
+ BCB5_UP Defined when compiling with C++Builder 5 or higher
+ BCB6_UP Defined when compiling with C++Builder 6 or higher
+ BCB10_UP Defined when compiling with C++Builder Personality of BDS 4.0 or higher
+ BCB11_UP Defined when compiling with C++Builder Personality of RAD Studio 2007 or higher
+ BCB12_UP Defined when compiling with C++Builder Personality of RAD Studio 2009 or higher
+ BCB14_UP Defined when compiling with C++Builder Personality of RAD Studio 2010 or higher
+ BCB15_UP Defined when compiling with C++Builder Personality of RAD Studio XE or higher
+ BCB16_UP Defined when compiling with C++Builder Personality of RAD Studio XE2 or higher
+ BCB17_UP Defined when compiling with C++Builder Personality of RAD Studio XE3 or higher
+
+
+- RAD Studio / Borland Developer Studio Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated IDE. These directives are only defined if
+ the IDE is Borland Developer Studio Version 2 or above.
+
+ Note: Borland Developer Studio 2006 is marketed as Delphi 2006 or C++Builder 2006,
+ but those provide only different labels for identical content.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ BDS Defined when compiling with BDS version of dcc32.exe (Codename SIDEWINDER)
+ BDS2 Defined when compiling with BDS 2.0 (Delphi 8) (Codename OCTANE)
+ BDS3 Defined when compiling with BDS 3.0 (Delphi 2005) (Codename DIAMONDBACK)
+ BDS4 Defined when compiling with BDS 4.0 (Borland Developer Studio 2006) (Codename DEXTER)
+ BDS5 Defined when compiling with BDS 5.0 (CodeGear RAD Studio 2007) (Codename HIGHLANDER)
+ BDS6 Defined when compiling with BDS 6.0 (CodeGear RAD Studio 2009) (Codename TIBURON)
+ BDS7 Defined when compiling with BDS 7.0 (Embarcadero RAD Studio 2010) (Codename WEAVER)
+ BDS8 Defined when compiling with BDS 8.0 (Embarcadero RAD Studio XE) (Codename FULCRUM)
+ BDS9 Defined when compiling with BDS 9.0 (Embarcadero RAD Studio XE2) (Codename PULSAR)
+ BDS10 Defined when compiling with BDS 10.0 (Embarcadero RAD Studio XE3) (Codename WATERDRAGON)
+ BDS2_UP Defined when compiling with BDS 2.0 or higher
+ BDS3_UP Defined when compiling with BDS 3.0 or higher
+ BDS4_UP Defined when compiling with BDS 4.0 or higher
+ BDS5_UP Defined when compiling with BDS 5.0 or higher
+ BDS6_UP Defined when compiling with BDS 6.0 or higher
+ BDS7_UP Defined when compiling with BDS 7.0 or higher
+ BDS8_UP Defined when compiling with BDS 8.0 or higher
+ BDS9_UP Defined when compiling with BDS 9.0 or higher
+ BDS10_UP Defined when compiling with BDS 10.0 or higher
+
+- Compiler Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. Unlike the DELPHI_X and BCB_X
+ directives, these directives are indepedent of the development environment.
+ That is, they are defined regardless of whether compilation takes place using
+ Delphi or C++Builder.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ COMPILER1 Defined when compiling with Delphi 1
+ COMPILER2 Defined when compiling with Delphi 2 or C++Builder 1
+ COMPILER3 Defined when compiling with Delphi 3
+ COMPILER35 Defined when compiling with C++Builder 3
+ COMPILER4 Defined when compiling with Delphi 4 or C++Builder 4
+ COMPILER5 Defined when compiling with Delphi 5 or C++Builder 5
+ COMPILER6 Defined when compiling with Delphi 6 or C++Builder 6
+ COMPILER7 Defined when compiling with Delphi 7
+ COMPILER8 Defined when compiling with Delphi 8
+ COMPILER9 Defined when compiling with Delphi 9
+ COMPILER10 Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0
+ COMPILER11 Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0
+ COMPILER12 Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0
+ COMPILER14 Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0
+ COMPILER15 Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0
+ COMPILER16 Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0
+ COMPILER17 Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0
+ COMPILER1_UP Defined when compiling with Delphi 1 or higher
+ COMPILER2_UP Defined when compiling with Delphi 2 or C++Builder 1 or higher
+ COMPILER3_UP Defined when compiling with Delphi 3 or higher
+ COMPILER35_UP Defined when compiling with C++Builder 3 or higher
+ COMPILER4_UP Defined when compiling with Delphi 4 or C++Builder 4 or higher
+ COMPILER5_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher
+ COMPILER6_UP Defined when compiling with Delphi 6 or C++Builder 6 or higher
+ COMPILER7_UP Defined when compiling with Delphi 7
+ COMPILER8_UP Defined when compiling with Delphi 8
+ COMPILER9_UP Defined when compiling with Delphi Personalities of BDS 3.0
+ COMPILER10_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher
+ COMPILER11_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher
+ COMPILER12_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher
+ COMPILER14_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher
+ COMPILER15_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher
+ COMPILER16_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher
+ COMPILER17_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher
+
+
+- RTL Versions
+
+ Use e.g. following to determine the exact RTL version since version 14.0:
+ {$IFDEF CONDITIONALEXPRESSIONS}
+ {$IF Declared(RTLVersion) and (RTLVersion >= 14.2)}
+ // code for Delphi 6.02 or higher, Kylix 2 or higher, C++Builder 6 or higher
+ ...
+ {$IFEND}
+ {$ENDIF}
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ RTL80_UP Defined when compiling with Delphi 1 or higher
+ RTL90_UP Defined when compiling with Delphi 2 or higher
+ RTL93_UP Defined when compiling with C++Builder 1 or higher
+ RTL100_UP Defined when compiling with Delphi 3 or higher
+ RTL110_UP Defined when compiling with C++Builder 3 or higher
+ RTL120_UP Defined when compiling with Delphi 4 or higher
+ RTL125_UP Defined when compiling with C++Builder 4 or higher
+ RTL130_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher
+ RTL140_UP Defined when compiling with Delphi 6, Kylix 1, 2 or 3 or C++Builder 6 or higher
+ RTL150_UP Defined when compiling with Delphi 7 or higher
+ RTL160_UP Defined when compiling with Delphi 8 or higher
+ RTL170_UP Defined when compiling with Delphi Personalities of BDS 3.0 or higher
+ RTL180_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher
+ RTL185_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher
+ RTL190_UP Defined when compiling with Delphi.NET of BDS 5.0 or higher
+ RTL200_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher
+ RTL210_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher
+ RTL220_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher
+ RTL230_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher
+ RTL240_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher
+
+
+- CLR Versions
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ CLR Defined when compiling for .NET
+ CLR10 Defined when compiling for .NET 1.0 (may be overriden by FORCE_CLR10)
+ CLR10_UP Defined when compiling for .NET 1.0 or higher
+ CLR11 Defined when compiling for .NET 1.1 (may be overriden by FORCE_CLR11)
+ CLR11_UP Defined when compiling for .NET 1.1 or higher
+ CLR20 Defined when compiling for .NET 2.0 (may be overriden by FORCE_CLR20)
+ CLR20_UP Defined when compiling for .NET 2.0 or higher
+
+
+- Feature Directives
+
+ The features directives are used to test if the compiler supports specific
+ features, such as method overloading, and adjust the sources accordingly. Use
+ of these directives is preferred over the use of the DELPHI and COMPILER
+ directives.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ SUPPORTS_CONSTPARAMS Compiler supports const parameters (D1+)
+ SUPPORTS_SINGLE Compiler supports the Single type (D1+)
+ SUPPORTS_DOUBLE Compiler supports the Double type (D1+)
+ SUPPORTS_EXTENDED Compiler supports the Extended type (D1+)
+ SUPPORTS_CURRENCY Compiler supports the Currency type (D2+)
+ SUPPORTS_THREADVAR Compiler supports threadvar declarations (D2+)
+ SUPPORTS_OUTPARAMS Compiler supports out parameters (D3+)
+ SUPPORTS_VARIANT Compiler supports variant (D2+)
+ SUPPORTS_WIDECHAR Compiler supports the WideChar type (D2+)
+ SUPPORTS_WIDESTRING Compiler supports the WideString type (D3+/BCB3+)
+ SUPPORTS_INTERFACE Compiler supports interfaces (D3+/BCB3+)
+ SUPPORTS_DISPINTERFACE Compiler supports dispatch interfaces (D3+/BCB3+)
+ SUPPORTS_DISPID Compiler supports dispatch ids (D3+/BCB3+/FPC)
+ SUPPORTS_EXTSYM Compiler supports the $EXTERNALSYM directive (D4+/BCB3+)
+ SUPPORTS_NODEFINE Compiler supports the $NODEFINE directive (D4+/BCB3+)
+ SUPPORTS_LONGWORD Compiler supports the LongWord type (unsigned 32 bit) (D4+/BCB4+)
+ SUPPORTS_INT64 Compiler supports the Int64 type (D4+/BCB4+)
+ SUPPORTS_UINT64 Compiler supports the UInt64 type (D XE+ ?)
+ SUPPORTS_DYNAMICARRAYS Compiler supports dynamic arrays (D4+/BCB4+)
+ SUPPORTS_DEFAULTPARAMS Compiler supports default parameters (D4+/BCB4+)
+ SUPPORTS_OVERLOAD Compiler supports overloading (D4+/BCB4+)
+ SUPPORTS_IMPLEMENTS Compiler supports implements (D4+/BCB4+)
+ SUPPORTS_DEPRECATED Compiler supports the deprecated directive (D6+/BCB6+)
+ SUPPORTS_PLATFORM Compiler supports the platform directive (D6+/BCB6+)
+ SUPPORTS_LIBRARY Compiler supports the library directive (D6+/BCB6+/FPC)
+ SUPPORTS_LOCAL Compiler supports the local directive (D6+/BCB6+)
+ SUPPORTS_SETPEFLAGS Compiler supports the SetPEFlags directive (D6+/BCB6+)
+ SUPPORTS_EXPERIMENTAL_WARNINGS Compiler supports the WARN SYMBOL_EXPERIMENTAL and WARN UNIT_EXPERIMENTAL directives (D6+/BCB6+)
+ SUPPORTS_INLINE Compiler supports the inline directive (D9+/FPC)
+ SUPPORTS_FOR_IN Compiler supports for in loops (D9+)
+ SUPPORTS_NESTED_CONSTANTS Compiler supports nested constants (D9+)
+ SUPPORTS_NESTED_TYPES Compiler supports nested types (D9+)
+ SUPPORTS_REGION Compiler supports the REGION and ENDREGION directives (D9+)
+ SUPPORTS_ENHANCED_RECORDS Compiler supports class [operator|function|procedure] for record types (D9.NET, D10+)
+ SUPPORTS_CLASS_FIELDS Compiler supports class fields (D9.NET, D10+)
+ SUPPORTS_CLASS_HELPERS Compiler supports class helpers (D9.NET, D10+)
+ SUPPORTS_CLASS_OPERATORS Compiler supports class operators (D9.NET, D10+)
+ SUPPORTS_CLASS_CTORDTORS Compiler supports class contructors/destructors (D14+)
+ SUPPORTS_STRICT Compiler supports strict keyword (D9.NET, D10+)
+ SUPPORTS_STATIC Compiler supports static keyword (D9.NET, D10+)
+ SUPPORTS_FINAL Compiler supports final keyword (D9.NET, D10+)
+ SUPPORTS_METHODINFO Compiler supports the METHODINFO directives (D10+)
+ SUPPORTS_GENERICS Compiler supports generic implementations (D11.NET, D12+)
+ SUPPORTS_DEPRECATED_DETAILS Compiler supports additional text for the deprecated directive (D11.NET, D12+)
+ ACCEPT_DEPRECATED Compiler supports or ignores the deprecated directive (D6+/BCB6+/FPC)
+ ACCEPT_PLATFORM Compiler supports or ignores the platform directive (D6+/BCB6+/FPC)
+ ACCEPT_LIBRARY Compiler supports or ignores the library directive (D6+/BCB6+)
+ SUPPORTS_CUSTOMVARIANTS Compiler supports custom variants (D6+/BCB6+)
+ SUPPORTS_VARARGS Compiler supports varargs (D6+/BCB6+)
+ SUPPORTS_ENUMVALUE Compiler supports assigning ordinalities to values of enums (D6+/BCB6+)
+ SUPPORTS_DEPRECATED_WARNINGS Compiler supports deprecated warnings (D6+/BCB6+)
+ SUPPORTS_LIBRARY_WARNINGS Compiler supports library warnings (D6+/BCB6+)
+ SUPPORTS_PLATFORM_WARNINGS Compiler supports platform warnings (D6+/BCB6+)
+ SUPPORTS_UNSAFE_WARNINGS Compiler supports unsafe warnings (D7)
+ SUPPORTS_WEAKPACKAGEUNIT Compiler supports the WEAKPACKAGEUNIT directive
+ SUPPORTS_COMPILETIME_MESSAGES Compiler supports the MESSAGE directive
+ SUPPORTS_PACKAGES Compiler supports Packages
+ HAS_UNIT_LIBC Unit Libc exists (Kylix, FPC on Linux/x86)
+ HAS_UNIT_RTLCONSTS Unit RTLConsts exists (D6+/BCB6+/FPC)
+ HAS_UNIT_TYPES Unit Types exists (D6+/BCB6+/FPC)
+ HAS_UNIT_VARIANTS Unit Variants exists (D6+/BCB6+/FPC)
+ HAS_UNIT_STRUTILS Unit StrUtils exists (D6+/BCB6+/FPC)
+ HAS_UNIT_DATEUTILS Unit DateUtils exists (D6+/BCB6+/FPC)
+ HAS_UNIT_CONTNRS Unit contnrs exists (D6+/BCB6+/FPC)
+ HAS_UNIT_HTTPPROD Unit HTTPProd exists (D9+)
+ HAS_UNIT_GIFIMG Unit GifImg exists (D11+)
+ HAS_UNIT_ANSISTRINGS Unit AnsiStrings exists (D12+)
+ HAS_UNIT_PNGIMAGE Unit PngImage exists (D12+)
+ HAS_UNIT_CHARACTER Unit Character exists (D12+)
+ XPLATFORM_RTL The RTL supports crossplatform function names (e.g. RaiseLastOSError) (D6+/BCB6+/FPC)
+ SUPPORTS_UNICODE string type is aliased to an unicode string (WideString or UnicodeString) (DX.NET, D12+)
+ SUPPORTS_UNICODE_STRING Compiler supports UnicodeString (D12+)
+ SUPPORTS_INT_ALIASES Types Int8, Int16, Int32, UInt8, UInt16 and UInt32 are defined in the unit System (D12+)
+ HAS_UNIT_RTTI Unit RTTI is available (D14+)
+ SUPPORTS_CAST_INTERFACE_TO_OBJ The compiler supports casts from interfaces to objects (D14+)
+ SUPPORTS_DELAYED_LOADING The compiler generates stubs for delaying imported function loads (D14+)
+ HAS_UNIT_REGULAREXPRESSIONSAPI Unit RegularExpressionsAPI is available (D15+)
+ HAS_UNIT_SYSTEM_UITYPES Unit System.UITypes is available (D16+)
+ HAS_UNIT_SYSTEM_ACTIONS Unit System.Actions is available (D17+)
+
+
+- Compiler Settings
+
+ The compiler settings directives indicate whether a specific compiler setting
+ is in effect. This facilitates changing compiler settings locally in a more
+ compact and readible manner.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ ALIGN_ON Compiling in the A+ state (no alignment)
+ BOOLEVAL_ON Compiling in the B+ state (complete boolean evaluation)
+ ASSERTIONS_ON Compiling in the C+ state (assertions on)
+ DEBUGINFO_ON Compiling in the D+ state (debug info generation on)
+ IMPORTEDDATA_ON Compiling in the G+ state (creation of imported data references)
+ LONGSTRINGS_ON Compiling in the H+ state (string defined as AnsiString)
+ IOCHECKS_ON Compiling in the I+ state (I/O checking enabled)
+ WRITEABLECONST_ON Compiling in the J+ state (typed constants can be modified)
+ LOCALSYMBOLS Compiling in the L+ state (local symbol generation)
+ LOCALSYMBOLS_ON Alias of LOCALSYMBOLS
+ TYPEINFO_ON Compiling in the M+ state (RTTI generation on)
+ OPTIMIZATION_ON Compiling in the O+ state (code optimization on)
+ OPENSTRINGS_ON Compiling in the P+ state (variable string parameters are openstrings)
+ OVERFLOWCHECKS_ON Compiling in the Q+ state (overflow checing on)
+ RANGECHECKS_ON Compiling in the R+ state (range checking on)
+ TYPEDADDRESS_ON Compiling in the T+ state (pointers obtained using the @ operator are typed)
+ SAFEDIVIDE_ON Compiling in the U+ state (save FDIV instruction through RTL emulation)
+ VARSTRINGCHECKS_ON Compiling in the V+ state (type checking of shortstrings)
+ STACKFRAMES_ON Compiling in the W+ state (generation of stack frames)
+ EXTENDEDSYNTAX_ON Compiling in the X+ state (Delphi extended syntax enabled)
+*)
+
+{$DEFINE BORLAND}
+
+{ Set FreePascal to Delphi mode }
+{$IFDEF FPC}
+ {$MODE DELPHI}
+ {$ASMMODE Intel}
+ {$UNDEF BORLAND}
+ {$DEFINE CPUASM}
+ // FPC defines CPU32, CPU64 and Unix automatically
+{$ENDIF}
+
+{$IFDEF BORLAND}
+ {$IFDEF LINUX}
+ {$DEFINE KYLIX}
+ {$ENDIF LINUX}
+ {$IFNDEF CLR}
+ {$IFNDEF CPUX86}
+ {$IFNDEF CPUX64}
+ {$DEFINE CPU386} // For Borland compilers select the x86 compat assembler by default
+ {$DEFINE CPU32} // Assume Borland compilers are 32-bit (rather than 64-bit)
+ {$DEFINE CPUASM}
+ {$ELSE ~CPUX64}
+ {$DEFINE CPU64}
+ {$DEFINE CPUASM}
+ {$DEFINE DELPHI64_TEMPORARY}
+ {$ENDIF ~CPUX64}
+ {$ELSE ~CPUX86}
+ {$DEFINE CPU386}
+ {$DEFINE CPU32}
+ {$DEFINE CPUASM}
+ {$ENDIF ~CPUX86}
+ {$ENDIF ~CLR}
+{$ENDIF BORLAND}
+
+{------------------------------------------------------------------------------}
+{ VERXXX to COMPILERX, DELPHIX and BCBX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BORLAND}
+ {$IFDEF KYLIX}
+ {$I kylix.inc} // FPC incompatible stuff
+ {$ELSE ~KYLIX}
+
+ {$DEFINE UNKNOWN_COMPILER_VERSION}
+
+ {$IFDEF VER80}
+ {$DEFINE COMPILER1}
+ {$DEFINE DELPHI1}
+ {$DEFINE DELPHICOMPILER1}
+ {$DEFINE RTL80_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER90}
+ {$DEFINE COMPILER2}
+ {$DEFINE DELPHI2}
+ {$DEFINE DELPHICOMPILER2}
+ {$DEFINE RTL90_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER93}
+ {$DEFINE COMPILER2}
+ {$DEFINE BCB1}
+ {$DEFINE BCB}
+ {$DEFINE RTL93_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER100}
+ {$DEFINE COMPILER3}
+ {$DEFINE DELPHI3}
+ {$DEFINE DELPHICOMPILER3}
+ {$DEFINE RTL100_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER110}
+ {$DEFINE COMPILER35}
+ {$DEFINE BCB3}
+ {$DEFINE BCB}
+ {$DEFINE RTL110_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER120}
+ {$DEFINE COMPILER4}
+ {$DEFINE DELPHI4}
+ {$DEFINE DELPHICOMPILER4}
+ {$DEFINE RTL120_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER125}
+ {$DEFINE COMPILER4}
+ {$DEFINE BCB4}
+ {$DEFINE BCB}
+ {$DEFINE RTL125_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER130}
+ {$DEFINE COMPILER5}
+ {$IFDEF BCB}
+ {$DEFINE BCB5}
+ {$ELSE}
+ {$DEFINE DELPHI5}
+ {$DEFINE DELPHICOMPILER5}
+ {$ENDIF}
+ {$DEFINE RTL130_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER140}
+ {$DEFINE COMPILER6}
+ {$IFDEF BCB}
+ {$DEFINE BCB6}
+ {$ELSE}
+ {$DEFINE DELPHI6}
+ {$DEFINE DELPHICOMPILER6}
+ {$ENDIF}
+ {$DEFINE RTL140_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER150}
+ {$DEFINE COMPILER7}
+ {$DEFINE DELPHI7}
+ {$DEFINE DELPHICOMPILER7}
+ {$DEFINE RTL150_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER160}
+ {$DEFINE BDS2}
+ {$DEFINE BDS}
+ {$IFDEF CLR}
+ {$DEFINE CLR10}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER8}
+ {$DEFINE DELPHI8}
+ {$DEFINE DELPHICOMPILER8}
+ {$DEFINE RTL160_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER170}
+ {$DEFINE BDS3}
+ {$DEFINE BDS}
+ {$IFDEF CLR}
+ {$DEFINE CLR11}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER9}
+ {$DEFINE DELPHI9}
+ {$DEFINE DELPHI2005} // synonym to DELPHI9
+ {$DEFINE DELPHICOMPILER9}
+ {$DEFINE RTL170_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER180}
+ {$DEFINE BDS}
+ {$IFDEF CLR}
+ {$DEFINE CLR11}
+ {$ENDIF CLR}
+ {$IFDEF VER185}
+ {$DEFINE BDS5}
+ {$DEFINE COMPILER11}
+ {$IFDEF BCB}
+ {$DEFINE BCB11}
+ {$ELSE}
+ {$DEFINE DELPHI11}
+ {$DEFINE DELPHI2007} // synonym to DELPHI11
+ {$DEFINE DELPHICOMPILER11}
+ {$ENDIF}
+ {$DEFINE RTL185_UP}
+ {$ELSE ~~VER185}
+ {$DEFINE BDS4}
+ {$DEFINE COMPILER10}
+ {$IFDEF BCB}
+ {$DEFINE BCB10}
+ {$ELSE}
+ {$DEFINE DELPHI10}
+ {$DEFINE DELPHI2006} // synonym to DELPHI10
+ {$DEFINE DELPHICOMPILER10}
+ {$ENDIF}
+ {$DEFINE RTL180_UP}
+ {$ENDIF ~VER185}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER190} // Delphi 2007 for .NET
+ {$DEFINE BDS}
+ {$DEFINE BDS5}
+ {$IFDEF CLR}
+ {$DEFINE CLR20}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER11}
+ {$DEFINE DELPHI11}
+ {$DEFINE DELPHI2007} // synonym to DELPHI11
+ {$DEFINE DELPHICOMPILER11}
+ {$DEFINE RTL190_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER190}
+
+ {$IFDEF VER200} // RAD Studio 2009
+ {$DEFINE BDS}
+ {$DEFINE BDS6}
+ {$IFDEF CLR}
+ {$DEFINE CLR20}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER12}
+ {$IFDEF BCB}
+ {$DEFINE BCB12}
+ {$ELSE}
+ {$DEFINE DELPHI12}
+ {$DEFINE DELPHI2009} // synonym to DELPHI12
+ {$DEFINE DELPHICOMPILER12}
+ {$ENDIF BCB}
+ {$IFDEF CLR}
+ {$DEFINE RTL190_UP}
+ {$ELSE}
+ {$DEFINE RTL200_UP}
+ {$ENDIF}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER200}
+
+ {$IFDEF VER210} // RAD Studio 2010
+ {$DEFINE BDS}
+ {$DEFINE BDS7}
+ {$DEFINE COMPILER14}
+ {$IFDEF BCB}
+ {$DEFINE BCB14}
+ {$ELSE}
+ {$DEFINE DELPHI14}
+ {$DEFINE DELPHI2010} // synonym to DELPHI14
+ {$DEFINE DELPHICOMPILER14}
+ {$ENDIF BCB}
+ {$DEFINE RTL210_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER210}
+
+ {$IFDEF VER220} // RAD Studio XE
+ {$DEFINE BDS}
+ {$DEFINE BDS8}
+ {$DEFINE COMPILER15}
+ {$IFDEF BCB}
+ {$DEFINE BCB15}
+ {$ELSE}
+ {$DEFINE DELPHI15}
+ {$DEFINE DELPHIXE} // synonym to DELPHI15
+ {$DEFINE DELPHICOMPILER15}
+ {$ENDIF BCB}
+ {$DEFINE RTL220_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER220}
+
+ {$IFDEF VER230} // RAD Studio XE2
+ {$DEFINE BDS}
+ {$DEFINE BDS9}
+ {$DEFINE COMPILER16}
+ {$IFDEF BCB}
+ {$DEFINE BCB16}
+ {$ELSE}
+ {$DEFINE DELPHI16}
+ {$DEFINE DELPHIXE2} // synonym to DELPHI16
+ {$DEFINE DELPHICOMPILER16}
+ {$ENDIF BCB}
+ {$DEFINE RTL230_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER230}
+
+ {$IFDEF VER240} // RAD Studio XE3
+ {$DEFINE BDS}
+ {$DEFINE BDS10}
+ {$DEFINE COMPILER17}
+ {$IFDEF BCB}
+ {$DEFINE BCB17}
+ {$ELSE}
+ {$DEFINE DELPHI17}
+ {$DEFINE DELPHIXE3} // synonym to DELPHI17
+ {$DEFINE DELPHICOMPILER17}
+ {$ENDIF BCB}
+ {$DEFINE RTL240_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER240}
+
+ {$IFDEF UNKNOWN_COMPILER_VERSION} // adjust for newer version (always use latest version)
+ {$DEFINE BDS}
+ {$DEFINE BDS10}
+ {$DEFINE COMPILER17}
+ {$IFDEF BCB}
+ {$DEFINE BCB17}
+ {$ELSE}
+ {$DEFINE DELPHI17}
+ {$DEFINE DELPHIXE3} // synonym to DELPHI17
+ {$DEFINE DELPHICOMPILER17}
+ {$ENDIF BCB}
+ {$DEFINE RTL240_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$ENDIF ~KYLIX}
+
+ {$IFDEF BCB}
+ {$DEFINE CPPBUILDER}
+ {$DEFINE BCBCOMPILER}
+ {$ELSE ~BCB}
+ {$DEFINE DELPHI}
+ {$DEFINE DELPHICOMPILER}
+ {$ENDIF ~BCB}
+
+{$ENDIF BORLAND}
+
+{------------------------------------------------------------------------------}
+{ DELPHIX_UP from DELPHIX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHI17} {$DEFINE DELPHI17_UP} {$ENDIF}
+{$IFDEF DELPHI16} {$DEFINE DELPHI16_UP} {$ENDIF}
+{$IFDEF DELPHI15} {$DEFINE DELPHI15_UP} {$ENDIF}
+{$IFDEF DELPHI14} {$DEFINE DELPHI14_UP} {$ENDIF}
+{$IFDEF DELPHI12} {$DEFINE DELPHI12_UP} {$ENDIF}
+{$IFDEF DELPHI11} {$DEFINE DELPHI11_UP} {$ENDIF}
+{$IFDEF DELPHI10} {$DEFINE DELPHI10_UP} {$ENDIF}
+{$IFDEF DELPHI9} {$DEFINE DELPHI9_UP} {$ENDIF}
+{$IFDEF DELPHI8} {$DEFINE DELPHI8_UP} {$ENDIF}
+{$IFDEF DELPHI7} {$DEFINE DELPHI7_UP} {$ENDIF}
+{$IFDEF DELPHI6} {$DEFINE DELPHI6_UP} {$ENDIF}
+{$IFDEF DELPHI5} {$DEFINE DELPHI5_UP} {$ENDIF}
+{$IFDEF DELPHI4} {$DEFINE DELPHI4_UP} {$ENDIF}
+{$IFDEF DELPHI3} {$DEFINE DELPHI3_UP} {$ENDIF}
+{$IFDEF DELPHI2} {$DEFINE DELPHI2_UP} {$ENDIF}
+{$IFDEF DELPHI1} {$DEFINE DELPHI1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ DELPHIX_UP from DELPHIX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHI17_UP}
+ {$DEFINE DELPHIXE3_UP} // synonym to DELPHI17_UP
+ {$DEFINE DELPHI16_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI16_UP}
+ {$DEFINE DELPHIXE2_UP} // synonym to DELPHI16_UP
+ {$DEFINE DELPHI15_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI15_UP}
+ {$DEFINE DELPHIXE_UP} // synonym to DELPHI15_UP
+ {$DEFINE DELPHI14_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI14_UP}
+ {$DEFINE DELPHI2010_UP} // synonym to DELPHI14_UP
+ {$DEFINE DELPHI12_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI12_UP}
+ {$DEFINE DELPHI2009_UP} // synonym to DELPHI12_UP
+ {$DEFINE DELPHI11_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI11_UP}
+ {$DEFINE DELPHI2007_UP} // synonym to DELPHI11_UP
+ {$DEFINE DELPHI10_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI10_UP}
+ {$DEFINE DELPHI2006_UP} // synonym to DELPHI10_UP
+ {$DEFINE DELPHI9_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI9_UP}
+ {$DEFINE DELPHI2005_UP} // synonym to DELPHI9_UP
+ {$DEFINE DELPHI8_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI8_UP} {$DEFINE DELPHI7_UP} {$ENDIF}
+{$IFDEF DELPHI7_UP} {$DEFINE DELPHI6_UP} {$ENDIF}
+{$IFDEF DELPHI6_UP} {$DEFINE DELPHI5_UP} {$ENDIF}
+{$IFDEF DELPHI5_UP} {$DEFINE DELPHI4_UP} {$ENDIF}
+{$IFDEF DELPHI4_UP} {$DEFINE DELPHI3_UP} {$ENDIF}
+{$IFDEF DELPHI3_UP} {$DEFINE DELPHI2_UP} {$ENDIF}
+{$IFDEF DELPHI2_UP} {$DEFINE DELPHI1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BCBX_UP from BCBX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BCB17} {$DEFINE BCB17_UP} {$ENDIF}
+{$IFDEF BCB16} {$DEFINE BCB16_UP} {$ENDIF}
+{$IFDEF BCB15} {$DEFINE BCB15_UP} {$ENDIF}
+{$IFDEF BCB14} {$DEFINE BCB14_UP} {$ENDIF}
+{$IFDEF BCB12} {$DEFINE BCB12_UP} {$ENDIF}
+{$IFDEF BCB11} {$DEFINE BCB11_UP} {$ENDIF}
+{$IFDEF BCB10} {$DEFINE BCB10_UP} {$ENDIF}
+{$IFDEF BCB6} {$DEFINE BCB6_UP} {$ENDIF}
+{$IFDEF BCB5} {$DEFINE BCB5_UP} {$ENDIF}
+{$IFDEF BCB4} {$DEFINE BCB4_UP} {$ENDIF}
+{$IFDEF BCB3} {$DEFINE BCB3_UP} {$ENDIF}
+{$IFDEF BCB1} {$DEFINE BCB1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BCBX_UP from BCBX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BCB17_UP} {$DEFINE BCB16_UP} {$ENDIF}
+{$IFDEF BCB16_UP} {$DEFINE BCB15_UP} {$ENDIF}
+{$IFDEF BCB15_UP} {$DEFINE BCB14_UP} {$ENDIF}
+{$IFDEF BCB14_UP} {$DEFINE BCB12_UP} {$ENDIF}
+{$IFDEF BCB12_UP} {$DEFINE BCB11_UP} {$ENDIF}
+{$IFDEF BCB11_UP} {$DEFINE BCB10_UP} {$ENDIF}
+{$IFDEF BCB10_UP} {$DEFINE BCB6_UP} {$ENDIF}
+{$IFDEF BCB6_UP} {$DEFINE BCB5_UP} {$ENDIF}
+{$IFDEF BCB5_UP} {$DEFINE BCB4_UP} {$ENDIF}
+{$IFDEF BCB4_UP} {$DEFINE BCB3_UP} {$ENDIF}
+{$IFDEF BCB3_UP} {$DEFINE BCB1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BDSX_UP from BDSX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BDS10} {$DEFINE BDS10_UP} {$ENDIF}
+{$IFDEF BDS9} {$DEFINE BDS9_UP} {$ENDIF}
+{$IFDEF BDS8} {$DEFINE BDS8_UP} {$ENDIF}
+{$IFDEF BDS7} {$DEFINE BDS7_UP} {$ENDIF}
+{$IFDEF BDS6} {$DEFINE BDS6_UP} {$ENDIF}
+{$IFDEF BDS5} {$DEFINE BDS5_UP} {$ENDIF}
+{$IFDEF BDS4} {$DEFINE BDS4_UP} {$ENDIF}
+{$IFDEF BDS3} {$DEFINE BDS3_UP} {$ENDIF}
+{$IFDEF BDS2} {$DEFINE BDS2_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BDSX_UP from BDSX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BDS10_UP} {$DEFINE BDS9_UP} {$ENDIF}
+{$IFDEF BDS9_UP} {$DEFINE BDS8_UP} {$ENDIF}
+{$IFDEF BDS8_UP} {$DEFINE BDS7_UP} {$ENDIF}
+{$IFDEF BDS7_UP} {$DEFINE BDS6_UP} {$ENDIF}
+{$IFDEF BDS6_UP} {$DEFINE BDS5_UP} {$ENDIF}
+{$IFDEF BDS5_UP} {$DEFINE BDS4_UP} {$ENDIF}
+{$IFDEF BDS4_UP} {$DEFINE BDS3_UP} {$ENDIF}
+{$IFDEF BDS3_UP} {$DEFINE BDS2_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ DELPHICOMPILERX_UP from DELPHICOMPILERX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHICOMPILER17} {$DEFINE DELPHICOMPILER17_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER16} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER15} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER14} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER12} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER11} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER10} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER9} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER8} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER7} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER6} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER5} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER4} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER3} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER2} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER1} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ DELPHICOMPILERX_UP from DELPHICOMPILERX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHICOMPILER17_UP} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER16_UP} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER15_UP} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER14_UP} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER12_UP} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER11_UP} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER10_UP} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER9_UP} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER7_UP} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER6_UP} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER5_UP} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER4_UP} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER3_UP} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER2_UP} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ COMPILERX_UP from COMPILERX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF COMPILER17} {$DEFINE COMPILER17_UP} {$ENDIF}
+{$IFDEF COMPILER16} {$DEFINE COMPILER16_UP} {$ENDIF}
+{$IFDEF COMPILER15} {$DEFINE COMPILER15_UP} {$ENDIF}
+{$IFDEF COMPILER14} {$DEFINE COMPILER14_UP} {$ENDIF}
+{$IFDEF COMPILER12} {$DEFINE COMPILER12_UP} {$ENDIF}
+{$IFDEF COMPILER11} {$DEFINE COMPILER11_UP} {$ENDIF}
+{$IFDEF COMPILER10} {$DEFINE COMPILER10_UP} {$ENDIF}
+{$IFDEF COMPILER9} {$DEFINE COMPILER9_UP} {$ENDIF}
+{$IFDEF COMPILER8} {$DEFINE COMPILER8_UP} {$ENDIF}
+{$IFDEF COMPILER7} {$DEFINE COMPILER7_UP} {$ENDIF}
+{$IFDEF COMPILER6} {$DEFINE COMPILER6_UP} {$ENDIF}
+{$IFDEF COMPILER5} {$DEFINE COMPILER5_UP} {$ENDIF}
+{$IFDEF COMPILER4} {$DEFINE COMPILER4_UP} {$ENDIF}
+{$IFDEF COMPILER35} {$DEFINE COMPILER35_UP} {$ENDIF}
+{$IFDEF COMPILER3} {$DEFINE COMPILER3_UP} {$ENDIF}
+{$IFDEF COMPILER2} {$DEFINE COMPILER2_UP} {$ENDIF}
+{$IFDEF COMPILER1} {$DEFINE COMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ COMPILERX_UP from COMPILERX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF COMPILER17_UP} {$DEFINE COMPILER16_UP} {$ENDIF}
+{$IFDEF COMPILER16_UP} {$DEFINE COMPILER15_UP} {$ENDIF}
+{$IFDEF COMPILER15_UP} {$DEFINE COMPILER14_UP} {$ENDIF}
+{$IFDEF COMPILER14_UP} {$DEFINE COMPILER12_UP} {$ENDIF}
+{$IFDEF COMPILER12_UP} {$DEFINE COMPILER11_UP} {$ENDIF}
+{$IFDEF COMPILER11_UP} {$DEFINE COMPILER10_UP} {$ENDIF}
+{$IFDEF COMPILER10_UP} {$DEFINE COMPILER9_UP} {$ENDIF}
+{$IFDEF COMPILER9_UP} {$DEFINE COMPILER8_UP} {$ENDIF}
+{$IFDEF COMPILER8_UP} {$DEFINE COMPILER7_UP} {$ENDIF}
+{$IFDEF COMPILER7_UP} {$DEFINE COMPILER6_UP} {$ENDIF}
+{$IFDEF COMPILER6_UP} {$DEFINE COMPILER5_UP} {$ENDIF}
+{$IFDEF COMPILER5_UP} {$DEFINE COMPILER4_UP} {$ENDIF}
+{$IFDEF COMPILER4_UP} {$DEFINE COMPILER35_UP} {$ENDIF}
+{$IFDEF COMPILER35_UP} {$DEFINE COMPILER3_UP} {$ENDIF}
+{$IFDEF COMPILER3_UP} {$DEFINE COMPILER2_UP} {$ENDIF}
+{$IFDEF COMPILER2_UP} {$DEFINE COMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ RTLX_UP from RTLX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF RTL240_UP} {$DEFINE RTL230_UP} {$ENDIF}
+{$IFDEF RTL230_UP} {$DEFINE RTL220_UP} {$ENDIF}
+{$IFDEF RTL220_UP} {$DEFINE RTL210_UP} {$ENDIF}
+{$IFDEF RTL210_UP} {$DEFINE RTL200_UP} {$ENDIF}
+{$IFDEF RTL200_UP} {$DEFINE RTL190_UP} {$ENDIF}
+{$IFDEF RTL190_UP} {$DEFINE RTL185_UP} {$ENDIF}
+{$IFDEF RTL185_UP} {$DEFINE RTL180_UP} {$ENDIF}
+{$IFDEF RTL180_UP} {$DEFINE RTL170_UP} {$ENDIF}
+{$IFDEF RTL170_UP} {$DEFINE RTL160_UP} {$ENDIF}
+{$IFDEF RTL160_UP} {$DEFINE RTL150_UP} {$ENDIF}
+{$IFDEF RTL150_UP} {$DEFINE RTL145_UP} {$ENDIF}
+{$IFDEF RTL145_UP} {$DEFINE RTL142_UP} {$ENDIF}
+{$IFDEF RTL142_UP} {$DEFINE RTL140_UP} {$ENDIF}
+{$IFDEF RTL140_UP} {$DEFINE RTL130_UP} {$ENDIF}
+{$IFDEF RTL130_UP} {$DEFINE RTL125_UP} {$ENDIF}
+{$IFDEF RTL125_UP} {$DEFINE RTL120_UP} {$ENDIF}
+{$IFDEF RTL120_UP} {$DEFINE RTL110_UP} {$ENDIF}
+{$IFDEF RTL110_UP} {$DEFINE RTL100_UP} {$ENDIF}
+{$IFDEF RTL100_UP} {$DEFINE RTL93_UP} {$ENDIF}
+{$IFDEF RTL93_UP} {$DEFINE RTL90_UP} {$ENDIF}
+{$IFDEF RTL90_UP} {$DEFINE RTL80_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ Check for CLR overrides of default detection }
+{------------------------------------------------------------------------------}
+
+{$IFDEF CLR}
+ {$IFDEF FORCE_CLR10}
+ {$DEFINE CLR10}
+ {$UNDEF CLR11}
+ {$UNDEF CLR20}
+ {$ENDIF FORCE_CLR10}
+
+ {$IFDEF FORCE_CLR11}
+ {$UNDEF CLR10}
+ {$DEFINE CLR11}
+ {$UNDEF CLR20}
+ {$ENDIF FORCE_CLR11}
+
+ {$IFDEF FORCE_CLR20}
+ {$UNDEF CLR10}
+ {$UNDEF CLR11}
+ {$DEFINE CLR20}
+ {$ENDIF FORCE_CLR20}
+{$ENDIF CLR}
+
+{------------------------------------------------------------------------------}
+{ CLRX from CLRX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF CLR10} {$DEFINE CLR10_UP} {$ENDIF}
+{$IFDEF CLR11} {$DEFINE CLR11_UP} {$ENDIF}
+{$IFDEF CLR20} {$DEFINE CLR20_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ CLRX_UP from CLRX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF CLR20_UP} {$DEFINE CLR11_UP} {$ENDIF}
+{$IFDEF CLR11_UP} {$DEFINE CLR10_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHICOMPILER}
+ {$DEFINE DELPHILANGUAGE}
+{$ENDIF}
+
+{$IFDEF BCBCOMPILER}
+ {$DEFINE DELPHILANGUAGE}
+{$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ KYLIXX_UP from KYLIXX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF KYLIX3} {$DEFINE KYLIX3_UP} {$ENDIF}
+{$IFDEF KYLIX2} {$DEFINE KYLIX2_UP} {$ENDIF}
+{$IFDEF KYLIX1} {$DEFINE KYLIX1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ KYLIXX_UP from KYLIXX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF KYLIX3_UP} {$DEFINE KYLIX2_UP} {$ENDIF}
+{$IFDEF KYLIX2_UP} {$DEFINE KYLIX1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ Map COMPILERX_UP to friendly feature names }
+{------------------------------------------------------------------------------}
+
+{$IFDEF FPC}
+ {$IFDEF VER1_0}
+ Please use FPC 2.0 or higher to compile this.
+ {$ELSE}
+ {$DEFINE SUPPORTS_OUTPARAMS}
+ {$DEFINE SUPPORTS_WIDECHAR}
+ {$DEFINE SUPPORTS_WIDESTRING}
+ {$IFDEF HASINTF}
+ {$DEFINE SUPPORTS_INTERFACE}
+ {$ENDIF}
+ {$IFDEF HASVARIANT}
+ {$DEFINE SUPPORTS_VARIANT}
+ {$ENDIF}
+ {$IFDEF FPC_HAS_TYPE_SINGLE}
+ {$DEFINE SUPPORTS_SINGLE}
+ {$ENDIF}
+ {$IFDEF FPC_HAS_TYPE_DOUBLE}
+ {$DEFINE SUPPORTS_DOUBLE}
+ {$ENDIF}
+ {$IFDEF FPC_HAS_TYPE_EXTENDED}
+ {$DEFINE SUPPORTS_EXTENDED}
+ {$ENDIF}
+ {$IFDEF HASCURRENCY}
+ {$DEFINE SUPPORTS_CURRENCY}
+ {$ENDIF}
+ {$DEFINE SUPPORTS_THREADVAR}
+ {$DEFINE SUPPORTS_CONSTPARAMS}
+ {$DEFINE SUPPORTS_LONGWORD}
+ {$DEFINE SUPPORTS_INT64}
+ {$DEFINE SUPPORTS_DYNAMICARRAYS}
+ {$DEFINE SUPPORTS_DEFAULTPARAMS}
+ {$DEFINE SUPPORTS_OVERLOAD}
+ {$DEFINE ACCEPT_DEPRECATED} // 2.2 also gives warnings
+ {$DEFINE ACCEPT_PLATFORM} // 2.2 also gives warnings
+ {$DEFINE ACCEPT_LIBRARY}
+ {$DEFINE SUPPORTS_EXTSYM}
+ {$DEFINE SUPPORTS_NODEFINE}
+
+ {$DEFINE SUPPORTS_CUSTOMVARIANTS}
+ {$DEFINE SUPPORTS_VARARGS}
+ {$DEFINE SUPPORTS_ENUMVALUE}
+ {$IFDEF LINUX}
+ {$DEFINE HAS_UNIT_LIBC}
+ {$ENDIF LINUX}
+ {$DEFINE HAS_UNIT_CONTNRS}
+ {$DEFINE HAS_UNIT_TYPES}
+ {$DEFINE HAS_UNIT_VARIANTS}
+ {$DEFINE HAS_UNIT_STRUTILS}
+ {$DEFINE HAS_UNIT_DATEUTILS}
+ {$DEFINE HAS_UNIT_RTLCONSTS}
+
+ {$DEFINE XPLATFORM_RTL}
+
+ {$IFDEF VER2_2}
+ {$DEFINE SUPPORTS_DISPINTERFACE}
+ {$DEFINE SUPPORTS_IMPLEMENTS}
+ {$DEFINE SUPPORTS_DISPID}
+ {$ELSE}
+ {$UNDEF SUPPORTS_DISPINTERFACE}
+ {$UNDEF SUPPORTS_IMPLEMENTS}
+ {$endif}
+ {$UNDEF SUPPORTS_UNSAFE_WARNINGS}
+ {$ENDIF}
+{$ENDIF FPC}
+
+{$IFDEF CLR}
+ {$DEFINE SUPPORTS_UNICODE}
+{$ENDIF CLR}
+
+{$IFDEF COMPILER1_UP}
+ {$DEFINE SUPPORTS_CONSTPARAMS}
+ {$DEFINE SUPPORTS_SINGLE}
+ {$DEFINE SUPPORTS_DOUBLE}
+ {$DEFINE SUPPORTS_EXTENDED}
+ {$DEFINE SUPPORTS_PACKAGES}
+{$ENDIF COMPILER1_UP}
+
+{$IFDEF COMPILER2_UP}
+ {$DEFINE SUPPORTS_CURRENCY}
+ {$DEFINE SUPPORTS_THREADVAR}
+ {$DEFINE SUPPORTS_VARIANT}
+ {$DEFINE SUPPORTS_WIDECHAR}
+{$ENDIF COMPILER2_UP}
+
+{$IFDEF COMPILER3_UP}
+ {$DEFINE SUPPORTS_OUTPARAMS}
+ {$DEFINE SUPPORTS_WIDESTRING}
+ {$DEFINE SUPPORTS_INTERFACE}
+ {$DEFINE SUPPORTS_DISPINTERFACE}
+ {$DEFINE SUPPORTS_DISPID}
+ {$DEFINE SUPPORTS_WEAKPACKAGEUNIT}
+{$ENDIF COMPILER3_UP}
+
+{$IFDEF COMPILER35_UP}
+ {$DEFINE SUPPORTS_EXTSYM}
+ {$DEFINE SUPPORTS_NODEFINE}
+{$ENDIF COMPILER35_UP}
+
+{$IFDEF COMPILER4_UP}
+ {$DEFINE SUPPORTS_LONGWORD}
+ {$DEFINE SUPPORTS_INT64}
+ {$DEFINE SUPPORTS_DYNAMICARRAYS}
+ {$DEFINE SUPPORTS_DEFAULTPARAMS}
+ {$DEFINE SUPPORTS_OVERLOAD}
+ {$DEFINE SUPPORTS_IMPLEMENTS}
+{$ENDIF COMPILER4_UP}
+
+{$IFDEF COMPILER6_UP}
+ {$DEFINE SUPPORTS_DEPRECATED}
+ {$DEFINE SUPPORTS_LIBRARY}
+ {$DEFINE SUPPORTS_PLATFORM}
+ {$DEFINE SUPPORTS_LOCAL}
+ {$DEFINE SUPPORTS_SETPEFLAGS}
+ {$DEFINE SUPPORTS_EXPERIMENTAL_WARNINGS}
+ {$DEFINE ACCEPT_DEPRECATED}
+ {$DEFINE ACCEPT_PLATFORM}
+ {$DEFINE ACCEPT_LIBRARY}
+ {$DEFINE SUPPORTS_DEPRECATED_WARNINGS}
+ {$DEFINE SUPPORTS_LIBRARY_WARNINGS}
+ {$DEFINE SUPPORTS_PLATFORM_WARNINGS}
+ {$DEFINE SUPPORTS_CUSTOMVARIANTS}
+ {$DEFINE SUPPORTS_VARARGS}
+ {$DEFINE SUPPORTS_ENUMVALUE}
+ {$DEFINE SUPPORTS_COMPILETIME_MESSAGES}
+{$ENDIF COMPILER6_UP}
+
+{$IFDEF COMPILER7_UP}
+ {$DEFINE SUPPORTS_UNSAFE_WARNINGS}
+{$ENDIF COMPILER7_UP}
+
+{$IFDEF COMPILER9_UP}
+ {$DEFINE SUPPORTS_FOR_IN}
+ {$DEFINE SUPPORTS_INLINE}
+ {$DEFINE SUPPORTS_NESTED_CONSTANTS}
+ {$DEFINE SUPPORTS_NESTED_TYPES}
+ {$DEFINE SUPPORTS_REGION}
+ {$IFDEF CLR}
+ {$DEFINE SUPPORTS_ENHANCED_RECORDS}
+ {$DEFINE SUPPORTS_CLASS_FIELDS}
+ {$DEFINE SUPPORTS_CLASS_HELPERS}
+ {$DEFINE SUPPORTS_CLASS_OPERATORS}
+ {$DEFINE SUPPORTS_STRICT}
+ {$DEFINE SUPPORTS_STATIC}
+ {$DEFINE SUPPORTS_FINAL}
+ {$ENDIF CLR}
+{$ENDIF COMPILER9_UP}
+
+{$IFDEF COMPILER10_UP}
+ {$DEFINE SUPPORTS_ENHANCED_RECORDS}
+ {$DEFINE SUPPORTS_CLASS_FIELDS}
+ {$DEFINE SUPPORTS_CLASS_HELPERS}
+ {$DEFINE SUPPORTS_CLASS_OPERATORS}
+ {$DEFINE SUPPORTS_STRICT}
+ {$DEFINE SUPPORTS_STATIC}
+ {$DEFINE SUPPORTS_FINAL}
+ {$DEFINE SUPPORTS_METHODINFO}
+{$ENDIF COMPILER10_UP}
+
+{$IFDEF COMPILER11_UP}
+ {$IFDEF CLR}
+ {$DEFINE SUPPORTS_GENERICS}
+ {$DEFINE SUPPORTS_DEPRECATED_DETAILS}
+ {$ENDIF CLR}
+{$ENDIF COMPILER11_UP}
+
+{$IFDEF COMPILER12_UP}
+ {$DEFINE SUPPORTS_GENERICS}
+ {$DEFINE SUPPORTS_DEPRECATED_DETAILS}
+ {$DEFINE SUPPORTS_INT_ALIASES}
+ {$IFNDEF CLR}
+ {$DEFINE SUPPORTS_UNICODE}
+ {$DEFINE SUPPORTS_UNICODE_STRING}
+ {$ENDIF CLR}
+{$ENDIF COMPILER12_UP}
+
+{$IFDEF COMPILER14_UP}
+ {$DEFINE SUPPORTS_CLASS_CTORDTORS}
+ {$DEFINE HAS_UNIT_RTTI}
+ {$DEFINE SUPPORTS_CAST_INTERFACE_TO_OBJ}
+ {$DEFINE SUPPORTS_DELAYED_LOADING}
+{$ENDIF COMPILER14_UP}
+
+{$IFDEF COMPILER16_UP}
+ {$DEFINE USE_64BIT_TYPES}
+{$ENDIF COMPILER16_UP}
+
+{$IFDEF RTL130_UP}
+ {$DEFINE HAS_UNIT_CONTNRS}
+{$ENDIF RTL130_UP}
+
+{$IFDEF RTL140_UP}
+ {$IFDEF LINUX}
+ {$DEFINE HAS_UNIT_LIBC}
+ {$ENDIF LINUX}
+ {$DEFINE HAS_UNIT_RTLCONSTS}
+ {$DEFINE HAS_UNIT_TYPES}
+ {$DEFINE HAS_UNIT_VARIANTS}
+ {$DEFINE HAS_UNIT_STRUTILS}
+ {$DEFINE HAS_UNIT_DATEUTILS}
+ {$DEFINE XPLATFORM_RTL}
+{$ENDIF RTL140_UP}
+
+{$IFDEF RTL170_UP}
+ {$DEFINE HAS_UNIT_HTTPPROD}
+{$ENDIF RTL170_UP}
+
+{$IFDEF RTL185_UP}
+ {$DEFINE HAS_UNIT_GIFIMG}
+{$ENDIF RTL185_UP}
+
+{$IFDEF RTL200_UP}
+ {$DEFINE HAS_UNIT_ANSISTRINGS}
+ {$DEFINE HAS_UNIT_PNGIMAGE}
+ {$DEFINE HAS_UNIT_CHARACTER}
+{$ENDIF RTL200_UP}
+
+{$IFDEF RTL220_UP}
+ {$DEFINE SUPPORTS_UINT64}
+ {$DEFINE HAS_UNIT_REGULAREXPRESSIONSAPI}
+{$ENDIF RTL220_UP}
+
+{$IFDEF RTL230_UP}
+ {$DEFINE HAS_UNITSCOPE}
+ {$DEFINE HAS_UNIT_SYSTEM_UITYPES}
+{$ENDIF RTL230_UP}
+
+{$IFDEF RTL240_UP}
+ {$DEFINE HAS_UNIT_SYSTEM_ACTIONS}
+{$ENDIF RTL240_UP}
+
+{------------------------------------------------------------------------------}
+{ Cross-platform related defines }
+{------------------------------------------------------------------------------}
+
+{$IFNDEF CPUASM}
+ {$DEFINE PUREPASCAL}
+{$ENDIF ~CPUASM}
+
+{$IFDEF WIN32}
+ {$DEFINE MSWINDOWS} // predefined for D6+/BCB6+
+ {$DEFINE Win32API}
+{$ENDIF}
+
+{$IFDEF DELPHILANGUAGE}
+ {$IFDEF LINUX}
+ {$DEFINE UNIX}
+ {$ENDIF}
+
+ {$IFNDEF CONSOLE}
+ {$IFDEF LINUX}
+ {$DEFINE VisualCLX}
+ {$ENDIF}
+ {$IFNDEF VisualCLX}
+ {$DEFINE VCL}
+ {$ENDIF}
+ {$ENDIF ~CONSOLE}
+{$ENDIF DELPHILANGUAGE}
+
+{------------------------------------------------------------------------------}
+{ Compiler settings }
+{------------------------------------------------------------------------------}
+
+{$IFOPT A+} {$DEFINE ALIGN_ON} {$ENDIF}
+{$IFOPT B+} {$DEFINE BOOLEVAL_ON} {$ENDIF}
+{$IFDEF COMPILER2_UP}
+ {$IFOPT C+} {$DEFINE ASSERTIONS_ON} {$ENDIF}
+{$ENDIF}
+{$IFOPT D+} {$DEFINE DEBUGINFO_ON} {$ENDIF}
+{$IFOPT G+} {$DEFINE IMPORTEDDATA_ON} {$ENDIF}
+{$IFDEF COMPILER2_UP}
+ {$IFOPT H+} {$DEFINE LONGSTRINGS_ON} {$ENDIF}
+{$ENDIF}
+
+// Hints
+{$IFOPT I+} {$DEFINE IOCHECKS_ON} {$ENDIF}
+{$IFDEF COMPILER2_UP}
+ {$IFOPT J+} {$DEFINE WRITEABLECONST_ON} {$ENDIF}
+{$ENDIF}
+{$IFOPT L+} {$DEFINE LOCALSYMBOLS} {$DEFINE LOCALSYMBOLS_ON} {$ENDIF}
+{$IFOPT M+} {$DEFINE TYPEINFO_ON} {$ENDIF}
+{$IFOPT O+} {$DEFINE OPTIMIZATION_ON} {$ENDIF}
+{$IFOPT P+} {$DEFINE OPENSTRINGS_ON} {$ENDIF}
+{$IFOPT Q+} {$DEFINE OVERFLOWCHECKS_ON} {$ENDIF}
+{$IFOPT R+} {$DEFINE RANGECHECKS_ON} {$ENDIF}
+
+// Real compatibility
+{$IFOPT T+} {$DEFINE TYPEDADDRESS_ON} {$ENDIF}
+{$IFOPT U+} {$DEFINE SAFEDIVIDE_ON} {$ENDIF}
+{$IFOPT V+} {$DEFINE VARSTRINGCHECKS_ON} {$ENDIF}
+{$IFOPT W+} {$DEFINE STACKFRAMES_ON} {$ENDIF}
+
+// Warnings
+{$IFOPT X+} {$DEFINE EXTENDEDSYNTAX_ON} {$ENDIF}
+
+// for Delphi/BCB trial versions remove the point from the line below
+{.$UNDEF SUPPORTS_WEAKPACKAGEUNIT}
+
+{$ENDIF ~JEDI_INC}
diff --git a/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt
new file mode 100644
index 0000000000..4ee09c3d24
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/HistoryToDBUpdater/readme-dev.txt
@@ -0,0 +1,38 @@
+HistoryToDBUpdater
+------------------
+
+Утилита установки/обновления компонентов плагинов RnQHistoryToDB, QIPHistoryToDB, MirandaIMHistoryToDB, MirandaNGHistoryToDB.
+
+Автор: Михаил Григорьев
+E-Mail: sleuthhound@gmail.com
+ICQ: 161867489
+WWW: http://www.im-history.ru
+Лицензия: GNU GPLv3
+
+Системные требования:
+---------------------
+ОС: Win2000/XP/2003/Vista/7
+IM-клиент: Любой
+БД: MySQL 4.0, 4.1, 5.0, 5.1
+ PostgreSQL 7.1 - 8.3
+ Oracle 8i - 11i
+ SQLite 3
+ Firebird 2.x
+
+Необходимые компоненты для сборки плагина:
+------------------------------------------
+
+1. Embarcadero RAD Studio XE3
+
+2. IM-History Downloader Component
+ See also directory IMDownloaderComponent
+
+3. DCPcrypt Cryptographic Component Library v2
+ http://www.cityinthesky.co.uk/
+
+Описание параметров запуска:
+----------------------------
+
+HistoryToDBUpdater.exe <1>
+
+<1> - (Необязательный параметр) - Путь до файла настроек HistoryToDB.ini (Например: "C:\Program Files\QIP Infium\Profiles\username@qip.ru\Plugins\QIPHistoryToDB\")
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr
new file mode 100644
index 0000000000..8942f8b61d
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dpr
@@ -0,0 +1,15 @@
+program DownLoaderTest;
+
+uses
+ Forms,
+ DownLoaderTestUnit in 'DownLoaderTestUnit.pas' {MainForm};
+
+{$R *.res}
+
+begin
+ Application.Initialize;
+ Application.MainFormOnTaskbar := True;
+ Application.Title := 'IM Downloader Demo';
+ Application.CreateForm(TMainForm, MainForm);
+ Application.Run;
+end.
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj
new file mode 100644
index 0000000000..c0b14483c0
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.dproj
@@ -0,0 +1,109 @@
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{8B841E47-C817-4F26-8ACF-89048F0E7C42}</ProjectGuid>
+ <MainSource>DownLoaderTest.dpr</MainSource>
+ <Base>True</Base>
+ <Config Condition="'$(Config)'==''">Release</Config>
+ <Platform>Win32</Platform>
+ <AppType>Application</AppType>
+ <FrameworkType>VCL</FrameworkType>
+ <DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+ <ProjectVersion>12.3</ProjectVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+ <Cfg_1>true</Cfg_1>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+ <Cfg_2>true</Cfg_2>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base)'!=''">
+ <DCC_ImageBase>00400000</DCC_ImageBase>
+ <DCC_E>false</DCC_E>
+ <DCC_S>false</DCC_S>
+ <DCC_F>false</DCC_F>
+ <DCC_N>false</DCC_N>
+ <DCC_K>false</DCC_K>
+ <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1)'!=''">
+ <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+ <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+ <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+ <DCC_DebugInformation>false</DCC_DebugInformation>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2)'!=''">
+ <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+ <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+ <DCC_Optimize>false</DCC_Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <DelphiCompile Include="DownLoaderTest.dpr">
+ <MainSource>MainSource</MainSource>
+ </DelphiCompile>
+ <DCCReference Include="DownLoaderTestUnit.pas">
+ <Form>MainForm</Form>
+ </DCCReference>
+ <BuildConfiguration Include="Debug">
+ <Key>Cfg_2</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Base">
+ <Key>Base</Key>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Release">
+ <Key>Cfg_1</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ </ItemGroup>
+ <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
+ <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
+ <ProjectExtensions>
+ <Borland.Personality>Delphi.Personality.12</Borland.Personality>
+ <Borland.ProjectType>VCLApplication</Borland.ProjectType>
+ <BorlandProject>
+ <Delphi.Personality>
+ <Source>
+ <Source Name="MainSource">DownLoaderTest.dpr</Source>
+ </Source>
+ <VersionInfo>
+ <VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+ <VersionInfo Name="AutoIncBuild">False</VersionInfo>
+ <VersionInfo Name="MajorVer">1</VersionInfo>
+ <VersionInfo Name="MinorVer">0</VersionInfo>
+ <VersionInfo Name="Release">0</VersionInfo>
+ <VersionInfo Name="Build">0</VersionInfo>
+ <VersionInfo Name="Debug">False</VersionInfo>
+ <VersionInfo Name="PreRelease">False</VersionInfo>
+ <VersionInfo Name="Special">False</VersionInfo>
+ <VersionInfo Name="Private">False</VersionInfo>
+ <VersionInfo Name="DLL">False</VersionInfo>
+ <VersionInfo Name="Locale">1049</VersionInfo>
+ <VersionInfo Name="CodePage">1251</VersionInfo>
+ </VersionInfo>
+ <VersionInfoKeys>
+ <VersionInfoKeys Name="CompanyName"/>
+ <VersionInfoKeys Name="FileDescription"/>
+ <VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="InternalName"/>
+ <VersionInfoKeys Name="LegalCopyright"/>
+ <VersionInfoKeys Name="LegalTrademarks"/>
+ <VersionInfoKeys Name="OriginalFilename"/>
+ <VersionInfoKeys Name="ProductName"/>
+ <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="Comments"/>
+ </VersionInfoKeys>
+ </Delphi.Personality>
+ <Platforms>
+ <Platform value="Win32">True</Platform>
+ </Platforms>
+ </BorlandProject>
+ <ProjectFileVersion>12</ProjectFileVersion>
+ </ProjectExtensions>
+ </Project>
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.res b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.res
new file mode 100644
index 0000000000..fc1937e1c7
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTest.res
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm
new file mode 100644
index 0000000000..b245bf8704
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.dfm
@@ -0,0 +1,125 @@
+object MainForm: TMainForm
+ Left = 0
+ Top = 0
+ Caption = 'TIMDownloadThread Test'
+ ClientHeight = 252
+ ClientWidth = 608
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ OldCreateOrder = False
+ Position = poDesktopCenter
+ OnShow = FormShow
+ PixelsPerInch = 96
+ TextHeight = 13
+ object ToolBar1: TToolBar
+ Left = 0
+ Top = 0
+ Width = 608
+ Height = 25
+ ButtonHeight = 27
+ ButtonWidth = 79
+ Caption = 'ToolBar1'
+ List = True
+ ShowCaptions = True
+ TabOrder = 0
+ object Edit1: TEdit
+ Left = 0
+ Top = 0
+ Width = 385
+ Height = 27
+ TabOrder = 0
+ end
+ object TBDownload: TToolButton
+ Left = 385
+ Top = 0
+ AutoSize = True
+ Caption = #1057#1082#1072#1095#1072#1090#1100
+ ImageIndex = 0
+ OnClick = TBDownloadClick
+ end
+ object TBStopDownload: TToolButton
+ Left = 444
+ Top = 0
+ AutoSize = True
+ Caption = #1054#1089#1090#1072#1085#1086#1074#1080#1090#1100
+ ImageIndex = 1
+ Visible = False
+ OnClick = TBStopDownloadClick
+ end
+ object TBView: TToolButton
+ Left = 521
+ Top = 0
+ AutoSize = True
+ Caption = #1042#1099#1074#1077#1089#1090#1080
+ DropdownMenu = PopupMenu1
+ ImageIndex = 2
+ Style = tbsDropDown
+ Visible = False
+ OnClick = TBViewClick
+ end
+ end
+ object StatusBar1: TStatusBar
+ Left = 0
+ Top = 233
+ Width = 608
+ Height = 19
+ Panels = <>
+ SimplePanel = True
+ end
+ object RichEdit1: TRichEdit
+ Left = 0
+ Top = 25
+ Width = 608
+ Height = 191
+ Align = alClient
+ Font.Charset = RUSSIAN_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ ParentFont = False
+ ReadOnly = True
+ ScrollBars = ssBoth
+ TabOrder = 2
+ end
+ object ProgressBar1: TProgressBar
+ Left = 0
+ Top = 216
+ Width = 608
+ Height = 17
+ Align = alBottom
+ TabOrder = 3
+ end
+ object IMDownloader_Demo: TIMDownloader
+ OnError = IMDownloader_DemoError
+ OnAccepted = IMDownloader_DemoAccepted
+ OnHeaders = IMDownloader_DemoHeaders
+ OnMD5Checked = IMDownloader_DemoMD5Checked
+ OnDownloading = IMDownloader_DemoDownloading
+ OnStartDownload = IMDownloader_DemoStartDownload
+ OnBreak = IMDownloader_DemoBreak
+ Left = 72
+ Top = 40
+ end
+ object SaveDialog1: TSaveDialog
+ Left = 136
+ Top = 96
+ end
+ object PopupMenu1: TPopupMenu
+ Left = 224
+ Top = 120
+ object ViewAsTest: TMenuItem
+ Caption = #1054#1090#1086#1073#1088#1072#1079#1080#1090#1100' '#1082#1072#1082' '#1090#1077#1082#1089#1090
+ Default = True
+ OnClick = ViewAsTestClick
+ end
+ object SaveToFile: TMenuItem
+ Caption = #1057#1086#1093#1088#1072#1085#1080#1090#1100' '#1074' '#1092#1072#1081#1083
+ OnClick = SaveToFileClick
+ end
+ end
+end
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas
new file mode 100644
index 0000000000..2ca42ac174
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/Demo/DownLoaderTestUnit.pas
@@ -0,0 +1,176 @@
+unit DownLoaderTestUnit;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+ Dialogs, uIMDownLoader, StdCtrls, ToolWin, ComCtrls, Menus;
+
+type
+ TMainForm = class(TForm)
+ IMDownloader_Demo: TIMDownloader;
+ Edit1: TEdit;
+ ToolBar1: TToolBar;
+ StatusBar1: TStatusBar;
+ RichEdit1: TRichEdit;
+ SaveDialog1: TSaveDialog;
+ TBDownload: TToolButton;
+ TBStopDownload: TToolButton;
+ TBView: TToolButton;
+ ViewAsTest: TMenuItem;
+ SaveToFile: TMenuItem;
+ PopupMenu1: TPopupMenu;
+ ProgressBar1: TProgressBar;
+ procedure FormShow(Sender: TObject);
+ procedure IMDownloader_DemoError(Sender: TObject; E: TIMDownLoadError);
+ procedure IMDownloader_DemoAccepted(Sender: TObject);
+ procedure IMDownloader_DemoStartDownload(Sender: TObject);
+ procedure IMDownloader_DemoBreak(Sender: TObject);
+ procedure ViewAsTestClick(Sender: TObject);
+ procedure SaveToFileClick(Sender: TObject);
+ procedure TBDownloadClick(Sender: TObject);
+ procedure TBStopDownloadClick(Sender: TObject);
+ procedure TBViewClick(Sender: TObject);
+ procedure IMDownloader_DemoDownloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal);
+ procedure IMDownloader_DemoHeaders(Sender: TObject; Headers: string);
+ procedure IMDownloader_DemoMD5Checked(Sender: TObject; MD5Correct,
+ SizeCorrect: Boolean; MD5Str: string);
+ private
+ { Private declarations }
+ public
+ { Public declarations }
+ end;
+
+var
+ MainForm: TMainForm;
+
+const
+ uURL = 'http://im-history.ru/update/get.php?file=HistoryToDB-Update';
+
+implementation
+
+{$R *.dfm}
+
+procedure TMainForm.FormShow(Sender: TObject);
+begin
+ Edit1.Text := uURL;
+ IMDownloader_Demo.DirPath := ExtractFilePath(Application.ExeName);
+end;
+
+procedure TMainForm.IMDownloader_DemoAccepted(Sender: TObject);
+begin
+ ProgressBar1.Visible := False;
+ TBStopDownload.Visible := false;
+ TBDownload.Visible := true;
+ TBView.Visible := true;
+ Edit1.ReadOnly := false;
+ StatusBar1.SimpleText :=
+ ' . : ' + IntToStr
+ (IMDownloader_Demo.AcceptedSize);
+ //RichEdit1.Lines.Append('MD5 : '+MD5DigestToStr(MD5Stream(IMDownloader_Demo.OutStream)));
+end;
+
+procedure TMainForm.IMDownloader_DemoBreak(Sender: TObject);
+begin
+ ProgressBar1.Visible := False;
+ TBStopDownload.Visible := false;
+ TBStopDownload.Enabled := true;
+ TBDownload.Visible := true;
+ TBView.Visible := IMDownloader_Demo.AcceptedSize > 0;
+ Edit1.ReadOnly := false;
+ StatusBar1.SimpleText :=
+ ' . : ' + IntToStr
+ (IMDownloader_Demo.AcceptedSize);
+end;
+
+procedure TMainForm.IMDownloader_DemoDownloading(Sender: TObject; AcceptedSize,
+ MaxSize: Cardinal);
+begin
+ StatusBar1.SimpleText := ' : ' + IntToStr(AcceptedSize);
+ ProgressBar1.Visible := MaxSize > AcceptedSize;
+ ProgressBar1.Max := MaxSize;
+ ProgressBar1.Position := AcceptedSize;
+end;
+
+procedure TMainForm.IMDownloader_DemoError(Sender: TObject; E: TIMDownLoadError);
+var
+ s: string;
+begin
+ ProgressBar1.Visible := False;
+ TBStopDownload.Visible := false;
+ TBDownload.Visible := true;
+ TBView.Visible := IMDownloader_Demo.AcceptedSize > 0;
+ Edit1.ReadOnly := false;
+ case E of
+ deInternetOpen: s := ' . ';
+ deInternetOpenUrl: s := ' . ';
+ deDownloadingFile: s := ' . ';
+ deRequest: s := ' -. ';
+ end;
+ StatusBar1.SimpleText :=
+ s + ' : ' + IntToStr
+ (IMDownloader_Demo.AcceptedSize);
+end;
+
+procedure TMainForm.IMDownloader_DemoHeaders(Sender: TObject; Headers: string);
+begin
+ RichEdit1.Lines.Text := Headers;
+end;
+
+procedure TMainForm.IMDownloader_DemoMD5Checked(Sender: TObject; MD5Correct,
+ SizeCorrect: Boolean; MD5Str: string);
+begin
+ if MD5Correct then
+ RichEdit1.Lines.Append(' MD5 = '+MD5Str+' - !')
+ else
+ RichEdit1.Lines.Append(' MD5 = '+MD5Str+' - !');
+ if SizeCorrect then
+ RichEdit1.Lines.Append(' = '+IntToStr(IMDownloader_Demo.AcceptedSize)+' - !')
+ else
+ RichEdit1.Lines.Append(' = '+IntToStr(IMDownloader_Demo.AcceptedSize)+' - !');
+end;
+
+procedure TMainForm.IMDownloader_DemoStartDownload(Sender: TObject);
+begin
+ TBDownload.Visible := false;
+ TBStopDownload.Visible := true;
+ TBView.Visible := false;
+ Edit1.ReadOnly := true;
+ StatusBar1.SimpleText := ' ...';
+end;
+
+procedure TMainForm.ViewAsTestClick(Sender: TObject);
+begin
+ RichEdit1.Lines.LoadFromStream(IMDownloader_Demo.OutStream);
+end;
+
+procedure TMainForm.SaveToFileClick(Sender: TObject);
+begin
+ if Edit1.Text = uURL then
+ SaveDialog1.FileName := 'HistoryToDBCreateDB.rar';
+ if SaveDialog1.Execute then
+ IMDownloader_Demo.OutStream.SaveToFile(SaveDialog1.FileName);
+end;
+
+procedure TMainForm.TBDownloadClick(Sender: TObject);
+begin
+ IMDownloader_Demo.URL := Edit1.Text;
+ //IMDownloader_Demo.Proxy := '192.168.42.240:1522';
+ IMDownloader_Demo.Proxy := '172.29.72.168:8080';
+ IMDownloader_Demo.Download;
+end;
+
+procedure TMainForm.TBStopDownloadClick(Sender: TObject);
+begin
+ StatusBar1.SimpleText := ' ';
+ TBStopDownload.Enabled := false;
+ IMDownloader_Demo.BreakDownload;
+end;
+
+procedure TMainForm.TBViewClick(Sender: TObject);
+begin
+ TBView.DropdownMenu.Popup(TBView.ClientOrigin.X,
+ TBView.ClientOrigin.Y + TBView.Height);
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcr b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcr
new file mode 100644
index 0000000000..2311dc0fef
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dcr
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk
new file mode 100644
index 0000000000..f925b6df62
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dpk
@@ -0,0 +1,38 @@
+package IMDownloader;
+
+{$R *.res}
+{$IFDEF IMPLICITBUILDING This IFDEF should not be used by users}
+{$ALIGN 8}
+{$ASSERTIONS ON}
+{$BOOLEVAL OFF}
+{$DEBUGINFO OFF}
+{$EXTENDEDSYNTAX ON}
+{$IMPORTEDDATA ON}
+{$IOCHECKS ON}
+{$LOCALSYMBOLS OFF}
+{$LONGSTRINGS ON}
+{$OPENSTRINGS ON}
+{$OPTIMIZATION ON}
+{$OVERFLOWCHECKS OFF}
+{$RANGECHECKS OFF}
+{$REFERENCEINFO OFF}
+{$SAFEDIVIDE OFF}
+{$STACKFRAMES OFF}
+{$TYPEDADDRESS OFF}
+{$VARSTRINGCHECKS ON}
+{$WRITEABLECONST OFF}
+{$MINENUMSIZE 1}
+{$IMAGEBASE $400000}
+{$DEFINE RELEASE}
+{$ENDIF IMPLICITBUILDING}
+{$IMPLICITBUILD ON}
+
+requires
+ rtl,
+ vcl;
+
+contains
+ uIMDownloader in 'uIMDownloader.pas',
+ uMD5 in 'uMD5.pas';
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj
new file mode 100644
index 0000000000..092d815fc7
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.dproj
@@ -0,0 +1,168 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{BF7E5A55-CA0C-4DDD-B399-17FA1A2FF83F}</ProjectGuid>
+ <MainSource>IMDownloader.dpk</MainSource>
+ <Base>True</Base>
+ <Config Condition="'$(Config)'==''">Release</Config>
+ <AppType>Package</AppType>
+ <FrameworkType>VCL</FrameworkType>
+ <DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+ <ProjectVersion>14.3</ProjectVersion>
+ <Platform Condition="'$(Platform)'==''">Win32</Platform>
+ <TargetedPlatforms>3</TargetedPlatforms>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
+ <Base_Win32>true</Base_Win32>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
+ <Base_Win64>true</Base_Win64>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+ <Cfg_1>true</Cfg_1>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
+ <Cfg_1_Win32>true</Cfg_1_Win32>
+ <CfgParent>Cfg_1</CfgParent>
+ <Cfg_1>true</Cfg_1>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
+ <Cfg_1_Win64>true</Cfg_1_Win64>
+ <CfgParent>Cfg_1</CfgParent>
+ <Cfg_1>true</Cfg_1>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+ <Cfg_2>true</Cfg_2>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base)'!=''">
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace)</DCC_Namespace>
+ <VerInfo_Build>4</VerInfo_Build>
+ <VerInfo_Locale>1049</VerInfo_Locale>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.4;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+ <DCC_DebugInformation>false</DCC_DebugInformation>
+ <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+ <DCC_ImageBase>00400000</DCC_ImageBase>
+ <GenDll>true</GenDll>
+ <DCC_E>false</DCC_E>
+ <DCC_S>false</DCC_S>
+ <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+ <DCC_N>false</DCC_N>
+ <GenPackage>true</GenPackage>
+ <DCC_K>false</DCC_K>
+ <DCC_F>false</DCC_F>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_Win32)'!=''">
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <Icon_MainIcon>IMDownloader_Icon.ico</Icon_MainIcon>
+ <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <DCC_UsePackage>vcl;rtl;$(DCC_UsePackage)</DCC_UsePackage>
+ <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_Win64)'!=''">
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <Icon_MainIcon>IMDownloader_Icon.ico</Icon_MainIcon>
+ <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
+ <DCC_UsePackage>vcl;rtl;$(DCC_UsePackage)</DCC_UsePackage>
+ <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <VerInfo_Build>0</VerInfo_Build>
+ <DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <VerInfo_Build>0</VerInfo_Build>
+ <DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2)'!=''">
+ <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+ <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+ <DCC_Optimize>false</DCC_Optimize>
+ </PropertyGroup>
+ <ItemGroup>
+ <DelphiCompile Include="$(MainSource)">
+ <MainSource>MainSource</MainSource>
+ </DelphiCompile>
+ <DCCReference Include="rtl.dcp"/>
+ <DCCReference Include="vcl.dcp"/>
+ <DCCReference Include="uIMDownloader.pas"/>
+ <DCCReference Include="uMD5.pas"/>
+ <BuildConfiguration Include="Debug">
+ <Key>Cfg_2</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Base">
+ <Key>Base</Key>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Release">
+ <Key>Cfg_1</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ </ItemGroup>
+ <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
+ <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
+ <ProjectExtensions>
+ <Borland.Personality>Delphi.Personality.12</Borland.Personality>
+ <Borland.ProjectType>Package</Borland.ProjectType>
+ <BorlandProject>
+ <Delphi.Personality>
+ <Source>
+ <Source Name="MainSource">IMDownloader.dpk</Source>
+ </Source>
+ <VersionInfo>
+ <VersionInfo Name="IncludeVerInfo">True</VersionInfo>
+ <VersionInfo Name="AutoIncBuild">False</VersionInfo>
+ <VersionInfo Name="MajorVer">1</VersionInfo>
+ <VersionInfo Name="MinorVer">0</VersionInfo>
+ <VersionInfo Name="Release">0</VersionInfo>
+ <VersionInfo Name="Build">4</VersionInfo>
+ <VersionInfo Name="Debug">False</VersionInfo>
+ <VersionInfo Name="PreRelease">False</VersionInfo>
+ <VersionInfo Name="Special">False</VersionInfo>
+ <VersionInfo Name="Private">False</VersionInfo>
+ <VersionInfo Name="DLL">False</VersionInfo>
+ <VersionInfo Name="Locale">1049</VersionInfo>
+ <VersionInfo Name="CodePage">1251</VersionInfo>
+ </VersionInfo>
+ <VersionInfoKeys>
+ <VersionInfoKeys Name="CompanyName"/>
+ <VersionInfoKeys Name="FileDescription"/>
+ <VersionInfoKeys Name="FileVersion">1.0.0.4</VersionInfoKeys>
+ <VersionInfoKeys Name="InternalName"/>
+ <VersionInfoKeys Name="LegalCopyright"/>
+ <VersionInfoKeys Name="LegalTrademarks"/>
+ <VersionInfoKeys Name="OriginalFilename"/>
+ <VersionInfoKeys Name="ProductName"/>
+ <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="Comments"/>
+ </VersionInfoKeys>
+ <Excluded_Packages/>
+ </Delphi.Personality>
+ <Platforms>
+ <Platform value="Win32">True</Platform>
+ <Platform value="Win64">True</Platform>
+ </Platforms>
+ </BorlandProject>
+ <ProjectFileVersion>12</ProjectFileVersion>
+ </ProjectExtensions>
+</Project>
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.res b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.res
new file mode 100644
index 0000000000..ebc501849a
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader.res
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.ico b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.ico
new file mode 100644
index 0000000000..379ec80d91
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/IMDownloader_Icon.ico
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas
new file mode 100644
index 0000000000..168fc21a7f
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uIMDownloader.pas
@@ -0,0 +1,612 @@
+{ ################################################################################### }
+{ # # }
+{ # IMDownloader # }
+{ # # }
+{ # Base on Downloader www.webdelphi.ru # }
+{ # http://www.webdelphi.ru/2009/10/mnogopotochnost-v-svoix-prilozheniyax-chast-2/ # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ # Downloader: # }
+{ # + ( Proxy, ProxyBypass, # }
+{ # AuthUserName, AuthPassword, ProxyAuthUserName, ProxyAuthPassword) # }
+{ # + DirPath - MD5. # }
+{ # ( MD5 ). MD5 # }
+{ # MD5 , . # }
+{ # + OnHeaders - . # }
+{ # + OnMD5Checked - MD5 . # }
+{ # # }
+{ ################################################################################### }
+
+unit uIMDownloader;
+
+interface
+
+uses Classes, WinInet, SysUtils, Dialogs, Windows, Forms, uMD5;
+
+const
+ Accept = 'Accept: */*' + sLineBreak;
+ ProxyConnection = 'Proxy-Connection: Keep-Alive' + sLineBreak;
+ Lang = 'Accept-Language: ru' + sLineBreak;
+ Agent =
+ 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; ' +
+ 'Windows NT 5.1; SV1; .NET CLR 2.0.50727)' + sLineBreak;
+
+type
+ PMemoryStream = ^TMemoryStream;
+ TIMDownloadError = (deInternetOpen, deInternetOpenUrl, deDownloadingFile, deConnect, deRequest);
+ TErrorEvent = procedure(Sender: TObject; E: TIMDownloadError) of object;
+ TDownloadingEvent = procedure(Sender: TObject; AcceptedSize, MaxSize: Cardinal) of object;
+ THeadersEvent = procedure(Sender: TObject; Headers: String) of object;
+ TMD5Event = procedure(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: String) of object;
+
+ TIMDownloadThread = class(TThread)
+ private
+ fURL: String;
+ fProxy: String;
+ fProxyBypass: String;
+ fAuthUserName: String;
+ fAuthPassword: String;
+ fProxyAuthUserName: String;
+ fProxyAuthPassword: String;
+ fDirPath: String;
+ MemoryStream: TMemoryStream;
+ Err: TIMDownloadError;
+ fError: TErrorEvent;
+ fAccepted: TNotifyEvent;
+ fBreak: TNotifyEvent;
+ fDownloading: TDownloadingEvent;
+ fHeaders: THeadersEvent;
+ AcceptedSize: Cardinal;
+ AllSize: Cardinal;
+ Headers: String;
+ MD5Str: String;
+ MD5Correct: Boolean;
+ SizeCorrect: Boolean;
+ fMD5: TMD5Event;
+ procedure toError;
+ procedure toHeaders;
+ procedure toDownloading;
+ procedure toAccepted;
+ procedure toBreak;
+ procedure toMD5;
+ procedure Complete;
+ function ErrorResult(E: Boolean; eType: TIMDownloadError): Boolean;
+ function GetQueryInfo(hRequest: Pointer; Flag: Integer): String;
+ protected
+ procedure Execute; override;
+ public
+ constructor Create(CreateSuspennded: Boolean; const URL, Proxy, ProxyBypass, AuthUserName, AuthPassword, ProxyAuthUserName, ProxyAuthPassword, DirPath: String; Stream: PMemoryStream);
+ property URL: string read fURL;
+ property Proxy: string read fProxy; //
+ property ProxyBypass: string read fProxyBypass; //
+ property AuthUserName: string read fAuthUserName; // Authorization: Basic
+ property AuthPassword: string read fAuthPassword; // Authorization: Basic
+ property ProxyAuthUserName: string read fProxyAuthUserName; //
+ property ProxyAuthPassword: string read fProxyAuthPassword; //
+ property DirPath: string read fDirPath write fDirPath; // MD5
+ property OnError: TErrorEvent read fError write fError;
+ property OnAccepted: TNotifyEvent read fAccepted write fAccepted;
+ property OnBreak: TNotifyEvent read fBreak write fBreak;
+ property OnDownloading: TDownloadingEvent read fDownloading write fDownloading;
+ property OnHeaders: THeadersEvent read fHeaders write fHeaders;
+ property OnMD5Checked: TMD5Event read fMD5 write fMD5;
+ end;
+
+ TIMDownloader = class(TComponent)
+ private
+ fOutStream: TMemoryStream;
+ fURL: String;
+ fProxy: String;
+ fProxyBypass: String;
+ fAuthUserName: String;
+ fAuthPassword: String;
+ fProxyAuthUserName: String;
+ fProxyAuthPassword: String;
+ fDirPath: String;
+ Downloader: TIMDownloadThread;
+ fOnError: TErrorEvent;
+ fOnAccepted: TNotifyEvent;
+ fOnBreak: TNotifyEvent;
+ fOnStartDownload: TNotifyEvent;
+ fInDowloading: Boolean;
+ fAcceptedSize: Cardinal;
+ fMyHeaders: String;
+ fMyMD5Str: String;
+ fMyMD5Correct: Boolean;
+ fMySizeCorrect: Boolean;
+ fHeaders: THeadersEvent;
+ fDownloading: TDownloadingEvent;
+ fMD5: TMD5Event;
+ procedure AcceptDownload(Sender: TObject);
+ procedure Break_Download(Sender: TObject);
+ procedure Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal);
+ procedure GetHeaders(Sender: TObject; Headers: String);
+ procedure GetMD5(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: String);
+ procedure ErrorDownload(Sender: TObject; Error: TIMDownloadError);
+ public
+ procedure Download;
+ procedure BreakDownload;
+ property OutStream: TMemoryStream read fOutStream;
+ property InDowloading: Boolean read fInDowloading;
+ property AcceptedSize: Cardinal read fAcceptedSize;
+ property MyHeaders: String read fMyHeaders;
+ property MyMD5Str: String read fMyMD5Str;
+ property MyMD5Correct: Boolean read fMyMD5Correct;
+ property MySizeCorrect: Boolean read fMySizeCorrect;
+ published
+ property URL: string read fURL write fURL;
+ property Proxy: string read fProxy write fProxy; //
+ property ProxyBypass: string read fProxyBypass write fProxyBypass; //
+ property AuthUserName: string read fAuthUserName write fAuthUserName; // Authorization: Basic
+ property AuthPassword: string read fAuthPassword write fAuthPassword; // Authorization: Basic
+ property ProxyAuthUserName: string read fProxyAuthUserName write fProxyAuthUserName; //
+ property ProxyAuthPassword: string read fProxyAuthPassword write fProxyAuthUserName; //
+ property DirPath: string read fDirPath write fDirPath; // MD5
+ property OnError: TErrorEvent read fOnError write fOnError;
+ property OnAccepted: TNotifyEvent read fOnAccepted write fOnAccepted;
+ property OnHeaders: THeadersEvent read fHeaders write fHeaders;
+ property OnMD5Checked: TMD5Event read fMD5 write fMD5;
+ property OnDownloading: TDownloadingEvent read fDownloading write fDownloading;
+ property OnStartDownload: TNotifyEvent read fOnStartDownload write fOnStartDownload;
+ property OnBreak: TNotifyEvent read fOnBreak write fOnBreak;
+ end;
+
+{$R IMDownloader.dcr}
+
+procedure Register;
+
+implementation
+
+procedure Register;
+begin
+ RegisterComponents('IM-History', [TIMDownloader]);
+end;
+
+procedure TIMDownloadThread.toHeaders;
+begin
+ if Assigned(fHeaders) then
+ fHeaders(Self, Headers);
+end;
+
+procedure TIMDownloadThread.toMD5;
+begin
+ if Assigned(fMD5) then
+ fMD5(Self, MD5Correct, SizeCorrect, MD5Str);
+end;
+
+procedure TIMDownloadThread.toDownloading;
+begin
+ if Assigned(fDownloading) then
+ fDownloading(Self, AcceptedSize, AllSize);
+end;
+
+procedure TIMDownloadThread.toAccepted;
+begin
+ if Assigned(fAccepted) then
+ fAccepted(Self);
+end;
+
+procedure TIMDownloadThread.toBreak;
+begin
+ if Assigned(fBreak) then
+ fBreak(Self);
+end;
+
+procedure TIMDownloadThread.Complete;
+begin
+ if Terminated then
+ Synchronize(toBreak)
+ else
+ Synchronize(toAccepted);
+end;
+
+procedure TIMDownloadThread.toError;
+begin
+ if Assigned(fError) then
+ OnError(Self, err);
+end;
+
+function TIMDownloadThread.ErrorResult(E: Boolean; eType: TIMDownloadError): Boolean;
+begin
+ Result := E;
+ if E then
+ begin
+ err := eType;
+ toError;
+ end;
+end;
+
+function TIMDownloadThread.GetQueryInfo(hRequest: Pointer; Flag: Integer): String;
+var
+ Code: String;
+ Size, Index: Cardinal;
+begin
+ SetLength(Code, 8); // -
+ Size := Length(Code);
+ Index := 0;
+ if HttpQueryInfo(hRequest, Flag ,PChar(Code), Size, Index) then
+ Result := Code
+ else
+ if GetLastError = ERROR_INSUFFICIENT_BUFFER then //
+ begin
+ SetLength(Code, Size);
+ Size := Length(Code);
+ if HttpQueryInfo(hRequest, Flag, PChar(Code), Size, Index) then
+ Result := Code;
+ end
+ else
+ begin
+ //FErrorCode := GetLastError;
+ Result := '';
+ end;
+end;
+
+procedure TIMDownloadThread.Execute;
+var
+ Buffer: Array [0 .. 1024] of Byte;
+ BytesRead: Cardinal;
+ FSession, FConnect, FRequest: hInternet;
+ dwBuffer: array [0 .. 1024] of Byte;
+ dwBufferLen, dwIndex: DWORD;
+ FHost, FScript, SRequest, ARequest: String;
+ ProxyReqRes, ProxyReqLen: Cardinal;
+ TempHeaders, TempMD5, DownloadsFileName, DownloadsFileMD5: String;
+
+ function DelHttp(sURL: String): String;
+ var
+ HttpPos: Integer;
+ begin
+ HttpPos := Pos('http://', sURL);
+ if HttpPos > 0 then Delete(sURL, HttpPos, 7);
+ Result := Copy(sURL, 1, Pos('/', sURL) - 1);
+ if Result = '' then Result := sURL;
+ end;
+
+ function ParseHeadersMD5andSize(HeaderStr: String): String;
+ var
+ HeadersStrList: TStringList;
+ I: Integer;
+ Size: String;
+ Ch: Char;
+ ResultFilename, ResultMD5Sum, ResultHeaders: String;
+ ResultFileSize: Integer;
+ begin
+ ResultFilename := 'Test';
+ ResultMD5Sum := '00000000000000000000000000000000';
+ ResultFileSize := 0;
+ // TStringList
+ HeadersStrList := TStringList.Create;
+ HeadersStrList.Clear;
+ HeadersStrList.Text := HeaderStr;
+ HeadersStrList.Delete(HeadersStrList.Count-1); // CRLF
+ if HeadersStrList.Count > 0 then
+ begin
+ for I := 0 to HeadersStrList.Count - 1 do
+ begin
+ //
+ // Content-Disposition: attachment; filename="-"
+ // HTTP-
+ // get.php
+ if pos('content-disposition', LowerCase(HeadersStrList[I])) > 0 then
+ begin
+ ResultFilename := HeadersStrList[I];
+ Delete(ResultFilename, 1, Pos('"', HeadersStrList[I]));
+ Delete(ResultFilename, Length(ResultFilename),1);
+ //LogMemo.Lines.Add('Filename: '+ResultFilename);
+ end;
+ //
+ // Content-MD5Sum: MD5
+ // HTTP-
+ // get.php
+ if pos('content-md5sum', LowerCase(HeadersStrList[I])) > 0 then
+ begin
+ ResultMD5Sum := HeadersStrList[I];
+ Delete(ResultMD5Sum, 1, Pos(':', HeadersStrList[I]));
+ Delete(ResultMD5Sum, 1,1);
+ end;
+ //
+ // Content-Length:
+ if pos('content-length', LowerCase(HeadersStrList[i])) > 0 then
+ begin
+ Size := '';
+ for Ch in HeadersStrList[I]do
+ if Ch in ['0'..'9'] then
+ Size := Size + Ch;
+ ResultFileSize := StrToIntDef(Size,-1);
+ end;
+ end;
+ Result := ResultFilename + '|' + LowerCase(ResultMD5Sum) + '|' + IntToStr(ResultFileSize) + '|';
+ end;
+ HeadersStrList.Free;
+ end;
+
+ { S , -,
+ Sep. ,
+ S }
+ function Tok(Sep: String; var S: String): String;
+
+ function isoneof(c, s: string): Boolean;
+ var
+ iTmp: integer;
+ begin
+ Result := False;
+ for iTmp := 1 to Length(s) do
+ begin
+ if c = Copy(s, iTmp, 1) then
+ begin
+ Result := True;
+ Exit;
+ end;
+ end;
+ end;
+
+ var
+ c, t: String;
+ begin
+ if s = '' then
+ begin
+ Result := s;
+ Exit;
+ end;
+ c := Copy(s, 1, 1);
+ while isoneof(c, sep) do
+ begin
+ s := Copy(s, 2, Length(s) - 1);
+ c := Copy(s, 1, 1);
+ end;
+ t := '';
+ while (not isoneof(c, sep)) and (s <> '') do
+ begin
+ t := t + c;
+ s := Copy(s, 2, length(s) - 1);
+ c := Copy(s, 1, 1);
+ end;
+ Result := t;
+ end;
+
+begin
+ // WinInet
+ if fProxy = '' then
+ FSession := InternetOpen('IM-History Download Master', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0)
+ else
+ begin
+ FSession := InternetOpen('IM-History Download Master', INTERNET_OPEN_TYPE_PROXY, PChar(fProxy), PChar(fProxyBypass), 0);
+ if fProxyAuthUserName <> '' then
+ begin
+ InternetSetOption(FSession, INTERNET_OPTION_PROXY_USERNAME, @fProxyAuthUserName, Length(fProxyAuthUserName));
+ InternetSetOption(FSession, INTERNET_OPTION_PROXY_PASSWORD, @fProxyAuthPassword, Length(fProxyAuthPassword));
+ end;
+ end;
+ if ErrorResult(FSession = nil, deInternetOpen) then
+ Exit;
+ if Assigned(FSession) then
+ begin
+ //
+ //
+ ARequest := fURL;
+ FHost := DelHttp(ARequest);
+ FScript := ARequest;
+ Delete(FScript, 1, Pos(FHost, FScript) + Length(FHost));
+ //
+ if fAuthUserName = '' then // Basic-
+ FConnect := InternetOpenURL(FSession, PChar(fURL), nil, 0, INTERNET_FLAG_RELOAD, 0)
+ else
+ FConnect := InternetConnect(FSession, PChar(FHost), INTERNET_DEFAULT_HTTP_PORT, PChar(fAuthUserName),
+ PChar(fAuthPassword), INTERNET_SERVICE_HTTP, 0, 0);
+ if ErrorResult(FConnect = nil, deInternetOpenUrl) then
+ Exit;
+ dwIndex := 0;
+ dwBufferLen := Length(dwBuffer);
+ if fProxy <> '' then
+ begin
+ //
+ FRequest := HttpOpenRequest(FConnect, 'GET', PChar(FScript), nil, '', nil, 0, 0);
+ //
+ HttpAddRequestHeaders(FRequest, Accept, Length(Accept), HTTP_ADDREQ_FLAG_ADD);
+ HttpAddRequestHeaders(FRequest, ProxyConnection, Length(ProxyConnection), HTTP_ADDREQ_FLAG_ADD);
+ HttpAddRequestHeaders(FRequest, Lang, Length(Lang), HTTP_ADDREQ_FLAG_ADD);
+ HttpAddRequestHeaders(FRequest, Agent, Length(Agent), HTTP_ADDREQ_FLAG_ADD);
+ // :
+ ProxyReqLen := 0;
+ ProxyReqRes := 0;
+ SRequest := ' ';
+ HttpQueryInfo(FRequest, HTTP_QUERY_RAW_HEADERS_CRLF or
+ HTTP_QUERY_FLAG_REQUEST_HEADERS, @SRequest[1], ProxyReqLen, ProxyReqRes);
+ if ProxyReqLen > 0 then
+ begin
+ SetLength(SRequest, ProxyReqLen);
+ HttpQueryInfo(FRequest, HTTP_QUERY_RAW_HEADERS_CRLF or
+ HTTP_QUERY_FLAG_REQUEST_HEADERS, @SRequest[1], ProxyReqLen, ProxyReqRes);
+ end;
+ //
+ if ErrorResult(not HttpSendRequest(FRequest, nil, 0, nil, 0), deRequest) then Exit;
+ end;
+ if fProxy = '' then
+ begin
+ //
+ Headers := GetQueryInfo(FConnect, HTTP_QUERY_RAW_HEADERS_CRLF);
+ Synchronize(toHeaders);
+ //
+ if HttpQueryInfo(FConnect, HTTP_QUERY_CONTENT_LENGTH, @dwBuffer, dwBufferLen, dwIndex) then
+ AllSize := StrToInt('0' + PChar(@dwBuffer));
+ end
+ else
+ begin
+ //
+ Headers := GetQueryInfo(FRequest, HTTP_QUERY_RAW_HEADERS_CRLF);
+ Synchronize(toHeaders);
+ //
+ if HttpQueryInfo(FRequest, HTTP_QUERY_CONTENT_LENGTH, @dwBuffer, dwBufferLen, dwIndex) then
+ AllSize := StrToInt('0' + PChar(@dwBuffer));
+ end;
+ // MD5
+ TempHeaders := ParseHeadersMD5andSize(Headers);
+ DownloadsFileName := Tok('|', TempHeaders);
+ DownloadsFileMD5 := Tok('|', TempHeaders);
+ if FileExists(fDirPath+DownloadsFileName) then
+ TempMD5 := LowerCase(MD5DigestToStr(MD5File(fDirPath+DownloadsFileName)))
+ else
+ TempMD5 := '00000000000000000000000000000000';
+ if LowerCase(DownloadsFileMD5) <> TempMD5 then
+ begin
+ repeat
+ if Terminated then
+ Break;
+ FillChar(Buffer, SizeOf(Buffer), 0);
+ if fProxy = '' then
+ begin
+ if ErrorResult(not InternetReadFile(FConnect, @Buffer, Length(Buffer), BytesRead), deDownloadingFile) then
+ Exit
+ else
+ MemoryStream.Write(Buffer, BytesRead);
+ end
+ else
+ begin
+ if ErrorResult(not InternetReadFile(FRequest, @Buffer, Length(Buffer), BytesRead), deDownloadingFile) then
+ Exit
+ else
+ MemoryStream.Write(Buffer, BytesRead);
+ end;
+ AcceptedSize := MemoryStream.Size;
+ Synchronize(toDownloading);
+ until (BytesRead = 0);
+ MemoryStream.Position := 0;
+ // MD5
+ MD5Str := LowerCase(MD5DigestToStr(MD5Stream(MemoryStream)));
+ TempHeaders := ParseHeadersMD5andSize(Headers);
+ DownloadsFileName := Tok('|', TempHeaders);
+ if Tok('|', TempHeaders) = MD5Str then
+ MD5Correct := True
+ else
+ MD5Correct := False;
+ if Tok('|', TempHeaders) = IntToStr(MemoryStream.Size) then
+ SizeCorrect := True
+ else
+ SizeCorrect := False;
+ Synchronize(toMD5);
+ end
+ else
+ begin
+ AcceptedSize := 0;
+ Synchronize(toDownloading);
+ MD5Str := 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
+ MD5Correct := True;
+ SizeCorrect := True;
+ Synchronize(toMD5);
+ end;
+ //
+ if Assigned(FRequest) then
+ InternetCloseHandle(FRequest);
+ if Assigned(FConnect) then
+ InternetCloseHandle(FConnect);
+ InternetCloseHandle(FSession);
+ Pointer(MemoryStream) := nil;
+ Complete;
+ end;
+end;
+
+constructor TIMDownloadThread.Create(CreateSuspennded: Boolean; const URL, Proxy, ProxyBypass, AuthUserName, AuthPassword, ProxyAuthUserName, ProxyAuthPassword, DirPath: String; Stream: PMemoryStream);
+begin
+ inherited Create(CreateSuspennded);
+ FreeOnTerminate := True;
+ Pointer(MemoryStream) := Stream;
+ AcceptedSize := 0;
+ Headers := '';
+ MD5Str := '';
+ MD5Correct := False;
+ SizeCorrect := False;
+ fURL := URL;
+ fProxy := Proxy;
+ fProxyBypass := ProxyBypass;
+ fAuthUserName := AuthUserName;
+ fAuthPassword := AuthPassword;
+ fProxyAuthUserName := ProxyAuthUserName;
+ fProxyAuthPassword := ProxyAuthPassword;
+ fDirPath := DirPath;
+end;
+
+procedure TIMDownloader.Download;
+begin
+ fInDowloading := True;
+ if Assigned(Downloader) then
+ Downloader.Terminate;
+ if Assigned(fOutStream) then
+ FreeAndNil(fOutStream);
+ fAcceptedSize := 0;
+ fMyHeaders := '';
+ fMyMD5Str := '';
+ fMyMD5Correct := False;
+ fMySizeCorrect := False;
+ fOutStream := TMemoryStream.Create;
+ Downloader := TIMDownloadThread.Create(True, fURL, fProxy, fProxyBypass, fAuthUserName, fAuthPassword, fProxyAuthUserName, fProxyAuthPassword, fDirPath, Pointer(fOutStream));
+ Downloader.OnAccepted := AcceptDownload;
+ Downloader.OnError := ErrorDownload;
+ Downloader.OnHeaders := GetHeaders;
+ Downloader.OnDownloading := Downloading;
+ Downloader.OnBreak := Break_Download;
+ Downloader.OnMD5Checked := GetMD5;
+ Downloader.Resume;
+ if Assigned(fOnStartDownload) then
+ fOnStartDownload(Self);
+end;
+
+procedure TIMDownloader.BreakDownload;
+begin
+ if not InDowloading then
+ Exit;
+ if Assigned(Downloader) then
+ Downloader.Terminate;
+end;
+
+procedure TIMDownloader.Break_Download(Sender: TObject);
+begin
+ fInDowloading := False;
+ Downloader := nil;
+ if Assigned(fOnBreak) then
+ fOnBreak(Self);
+end;
+
+procedure TIMDownloader.AcceptDownload(Sender: TObject);
+begin
+ fInDowloading := False;
+ Downloader := nil;
+ if Assigned(fOnAccepted) then
+ fOnAccepted(Self);
+end;
+
+procedure TIMDownloader.GetHeaders(Sender: TObject; Headers: String);
+begin
+ fMyHeaders := Headers;
+ if Assigned(fHeaders) then
+ fHeaders(Self, Headers);
+end;
+
+procedure TIMDownloader.GetMD5(Sender: TObject; MD5Correct, SizeCorrect: Boolean; MD5Str: String);
+begin
+ fMyMD5Str := MD5Str;
+ fMyMD5Correct := MD5Correct;
+ fMySizeCorrect := SizeCorrect;
+ if Assigned(fMD5) then
+ fMD5(Self, MD5Correct, SizeCorrect, MD5Str);
+end;
+
+procedure TIMDownloader.Downloading(Sender: TObject; AcceptedSize, MaxSize: Cardinal);
+begin
+ fAcceptedSize := AcceptedSize;
+ if Assigned(fDownloading) then
+ fDownloading(Self, AcceptedSize, MaxSize);
+end;
+
+procedure TIMDownloader.ErrorDownload(Sender: TObject; Error: TIMDownloadError);
+begin
+ fInDowloading := False;
+ Downloader := nil;
+ fOutStream := nil;
+ if Assigned(fOnError) then
+ fOnError(Self, Error);
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas
new file mode 100644
index 0000000000..81a6f4697b
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/IMDownloaderComponent/uMD5.pas
@@ -0,0 +1,456 @@
+{******************************************************************}
+{ - MD5 }
+{ }
+{ by delphibase.endimus.com }
+{ : Windows, SysUtils, Classes }
+{ : Dimka Maslov, mainbox@endimus.ru, ICQ:148442121, - }
+{ Copyright: http://www.faqs.org/rfcs/rfc1321.html }
+{ : 19 2002 . }
+{******************************************************************}
+
+{******************************************************************}
+{ MD5 Hashsum Evaluation Unit For Borland Delphi }
+{ }
+{ Copyright 2002 by Dimka Maslov }
+{ E-mail: mainbox@endimus.com, }
+{ Web-site: http://www.endimus.com }
+{ }
+{ Derived from the RSA Data Security, Inc. }
+{ MD5 Message-Digest Algorithm described in RFC 1321 }
+{ http://www.faqs.org/rfcs/rfc1321.html }
+{******************************************************************}
+
+unit uMD5;
+
+Interface
+
+Uses Windows, SysUtils, Classes;
+
+Type
+{ The TMD5Digest record is the type of results of
+ the MD5 hashsum evaluation functions. The contents
+ of a record may be used as four 32-bit integer values
+ or as an array of 16 bytes }
+{ TMD5Digest
+ -.
+
+ 4 ,
+ 16 }
+ PMD5Digest = ^TMD5Digest;
+
+ TMD5Digest = Record
+ Case Integer Of
+ 0: (A, B, C, D: LongInt);
+ 1: (v: Array[0..15] Of Byte);
+ End;
+
+{ The MD5String function evaluates the MD5 hashsum for
+ a string. The S parameter specifies a string to
+ evaluate hashsum }
+// -
+Function MD5String(Const S: String): TMD5Digest;
+
+{ The MD5File function evaluates the MD5 hashsum for
+ a file. The FileName parameter specifies the name
+ of a file to evaluate hashsum }
+// -
+Function MD5File(Const FileName: String): TMD5Digest;
+
+{ The MD5Stream function evaluates the MD5 hashsum for
+ a stream. The Stream parameters specifies the
+ TStream descendant class object to evaluate hashsum }
+// - Stream
+Function MD5Stream(Const Stream: TStream): TMD5Digest;
+
+{ The MD5Buffer function evaluates the MD5 hashsum for
+ any memory buffer. The Buffer parameters specifies a
+ buffer to evaluate hashsum. The Size parameter specifies
+ the size (in bytes) of a buffer }
+// -
+Function MD5Buffer(Const Buffer; Size: Integer): TMD5Digest;
+
+{ The MD5DigestToStr function converts the result of
+ a hashsum evaluation function into a string of
+ hexadecimal digits }
+// -
+Function MD5DigestToStr(Const Digest: TMD5Digest): String;
+
+
+{ The MD5DigestCompare function compares two
+ TMD5Digest record variables. This function returns
+ TRUE if parameters are equal or FALSE otherwise }
+// -
+Function MD5DigestCompare(Const Digest1, Digest2: TMD5Digest): Boolean;
+
+{
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+}
+
+Implementation
+
+Type
+ UINT4 = LongWord;
+
+ PArray4UINT4 = ^TArray4UINT4;
+ TArray4UINT4 = Array[0..3] Of UINT4;
+ PArray2UINT4 = ^TArray2UINT4;
+ TArray2UINT4 = Array[0..1] Of UINT4;
+ PArray16Byte = ^TArray16Byte;
+ TArray16Byte = Array[0..15] Of Byte;
+ PArray64Byte = ^TArray64Byte;
+ TArray64Byte = Array[0..63] Of Byte;
+
+ PByteArray = ^TByteArray;
+ TByteArray = Array[0..0] Of Byte;
+
+ PUINT4Array = ^TUINT4Array;
+ TUINT4Array = Array[0..0] Of UINT4;
+
+ PMD5Context = ^TMD5Context;
+ TMD5Context = Record
+ state: TArray4UINT4;
+ count: TArray2UINT4;
+ buffer: TArray64Byte;
+ End;
+
+Const
+ S11 = 7;
+ S12 = 12;
+ S13 = 17;
+ S14 = 22;
+ S21 = 5;
+ S22 = 9;
+ S23 = 14;
+ S24 = 20;
+ S31 = 4;
+ S32 = 11;
+ S33 = 16;
+ S34 = 23;
+ S41 = 6;
+ S42 = 10;
+ S43 = 15;
+ S44 = 21;
+
+Var
+ Padding: TArray64Byte =
+ ($80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+
+Function _F(x, y, z: UINT4): UINT4;
+Begin
+ Result := (((x) And (y)) Or ((Not x) And (z)));
+End;
+
+Function _G(x, y, z: UINT4): UINT4;
+Begin
+ Result := (((x) And (z)) Or ((y) And (Not z)));
+End;
+
+Function _H(x, y, z: UINT4): UINT4;
+Begin
+ Result := ((x) Xor (y) Xor (z));
+End;
+
+Function _I(x, y, z: UINT4): UINT4;
+Begin
+ Result := ((y) Xor ((x) Or (Not z)));
+End;
+
+Function ROTATE_LEFT(x, n: UINT4): UINT4;
+Begin
+ Result := (((x) Shl (n)) Or ((x) Shr (32 - (n))));
+End;
+
+Procedure FF(Var a: UINT4; b, c, d, x, s, ac: UINT4);
+Begin
+ a := a + _F(b, c, d) + x + ac;
+ a := ROTATE_LEFT(a, s);
+ a := a + b;
+End;
+
+Procedure GG(Var a: UINT4; b, c, d, x, s, ac: UINT4);
+Begin
+ a := a + _G(b, c, d) + x + ac;
+ a := ROTATE_LEFT(a, s);
+ a := a + b;
+End;
+
+Procedure HH(Var a: UINT4; b, c, d, x, s, ac: UINT4);
+Begin
+ a := a + _H(b, c, d) + x + ac;
+ a := ROTATE_LEFT(a, s);
+ a := a + b;
+End;
+
+Procedure II(Var a: UINT4; b, c, d, x, s, ac: UINT4);
+Begin
+ a := a + _I(b, c, d) + x + ac;
+ a := ROTATE_LEFT(a, s);
+ a := a + b;
+End;
+
+Procedure MD5Encode(Output: PByteArray; Input: PUINT4Array; Len: LongWord);
+Var
+ i, j: LongWord;
+Begin
+ j := 0;
+ i := 0;
+ While j < Len Do Begin
+ output[j] := Byte(input[i] And $FF);
+ output[j + 1] := Byte((input[i] Shr 8) And $FF);
+ output[j + 2] := Byte((input[i] Shr 16) And $FF);
+ output[j + 3] := Byte((input[i] Shr 24) And $FF);
+ Inc(j, 4);
+ Inc(i);
+ End;
+End;
+
+Procedure MD5Decode(Output: PUINT4Array; Input: PByteArray; Len: LongWord);
+Var
+ i, j: LongWord;
+Begin
+ j := 0;
+ i := 0;
+ While j < Len Do Begin
+ Output[i] := UINT4(input[j]) Or (UINT4(input[j + 1]) Shl 8) Or
+ (UINT4(input[j + 2]) Shl 16) Or (UINT4(input[j + 3]) Shl 24);
+ Inc(j, 4);
+ Inc(i);
+ End;
+End;
+
+Procedure MD5_memcpy(Output: PByteArray; Input: PByteArray; Len: LongWord);
+Begin
+ Move(Input^, Output^, Len);
+End;
+
+Procedure MD5_memset(Output: PByteArray; Value: Integer; Len: LongWord);
+Begin
+ FillChar(Output^, Len, Byte(Value));
+End;
+
+Procedure MD5Transform(State: PArray4UINT4; Buffer: PArray64Byte);
+Var
+ a, b, c, d: UINT4;
+ x: Array[0..15] Of UINT4;
+Begin
+ a := State[0]; b := State[1]; c := State[2]; d := State[3];
+ MD5Decode(PUINT4Array(@x), PByteArray(Buffer), 64);
+
+ FF(a, b, c, d, x[0], S11, $D76AA478);
+ FF(d, a, b, c, x[1], S12, $E8C7B756);
+ FF(c, d, a, b, x[2], S13, $242070DB);
+ FF(b, c, d, a, x[3], S14, $C1BDCEEE);
+ FF(a, b, c, d, x[4], S11, $F57C0FAF);
+ FF(d, a, b, c, x[5], S12, $4787C62A);
+ FF(c, d, a, b, x[6], S13, $A8304613);
+ FF(b, c, d, a, x[7], S14, $FD469501);
+ FF(a, b, c, d, x[8], S11, $698098D8);
+ FF(d, a, b, c, x[9], S12, $8B44F7AF);
+ FF(c, d, a, b, x[10], S13, $FFFF5BB1);
+ FF(b, c, d, a, x[11], S14, $895CD7BE);
+ FF(a, b, c, d, x[12], S11, $6B901122);
+ FF(d, a, b, c, x[13], S12, $FD987193);
+ FF(c, d, a, b, x[14], S13, $A679438E);
+ FF(b, c, d, a, x[15], S14, $49B40821);
+
+ GG(a, b, c, d, x[1], S21, $F61E2562);
+ GG(d, a, b, c, x[6], S22, $C040B340);
+ GG(c, d, a, b, x[11], S23, $265E5A51);
+ GG(b, c, d, a, x[0], S24, $E9B6C7AA);
+ GG(a, b, c, d, x[5], S21, $D62F105D);
+ GG(d, a, b, c, x[10], S22, $2441453);
+ GG(c, d, a, b, x[15], S23, $D8A1E681);
+ GG(b, c, d, a, x[4], S24, $E7D3FBC8);
+ GG(a, b, c, d, x[9], S21, $21E1CDE6);
+ GG(d, a, b, c, x[14], S22, $C33707D6);
+ GG(c, d, a, b, x[3], S23, $F4D50D87);
+
+ GG(b, c, d, a, x[8], S24, $455A14ED);
+ GG(a, b, c, d, x[13], S21, $A9E3E905);
+ GG(d, a, b, c, x[2], S22, $FCEFA3F8);
+ GG(c, d, a, b, x[7], S23, $676F02D9);
+ GG(b, c, d, a, x[12], S24, $8D2A4C8A);
+
+ HH(a, b, c, d, x[5], S31, $FFFA3942);
+ HH(d, a, b, c, x[8], S32, $8771F681);
+ HH(c, d, a, b, x[11], S33, $6D9D6122);
+ HH(b, c, d, a, x[14], S34, $FDE5380C);
+ HH(a, b, c, d, x[1], S31, $A4BEEA44);
+ HH(d, a, b, c, x[4], S32, $4BDECFA9);
+ HH(c, d, a, b, x[7], S33, $F6BB4B60);
+ HH(b, c, d, a, x[10], S34, $BEBFBC70);
+ HH(a, b, c, d, x[13], S31, $289B7EC6);
+ HH(d, a, b, c, x[0], S32, $EAA127FA);
+ HH(c, d, a, b, x[3], S33, $D4EF3085);
+ HH(b, c, d, a, x[6], S34, $4881D05);
+ HH(a, b, c, d, x[9], S31, $D9D4D039);
+ HH(d, a, b, c, x[12], S32, $E6DB99E5);
+ HH(c, d, a, b, x[15], S33, $1FA27CF8);
+ HH(b, c, d, a, x[2], S34, $C4AC5665);
+
+ II(a, b, c, d, x[0], S41, $F4292244);
+ II(d, a, b, c, x[7], S42, $432AFF97);
+ II(c, d, a, b, x[14], S43, $AB9423A7);
+ II(b, c, d, a, x[5], S44, $FC93A039);
+ II(a, b, c, d, x[12], S41, $655B59C3);
+ II(d, a, b, c, x[3], S42, $8F0CCC92);
+ II(c, d, a, b, x[10], S43, $FFEFF47D);
+ II(b, c, d, a, x[1], S44, $85845DD1);
+ II(a, b, c, d, x[8], S41, $6FA87E4F);
+ II(d, a, b, c, x[15], S42, $FE2CE6E0);
+ II(c, d, a, b, x[6], S43, $A3014314);
+ II(b, c, d, a, x[13], S44, $4E0811A1);
+ II(a, b, c, d, x[4], S41, $F7537E82);
+ II(d, a, b, c, x[11], S42, $BD3AF235);
+ II(c, d, a, b, x[2], S43, $2AD7D2BB);
+ II(b, c, d, a, x[9], S44, $EB86D391);
+
+ Inc(State[0], a);
+ Inc(State[1], b);
+ Inc(State[2], c);
+ Inc(State[3], d);
+
+ MD5_memset(PByteArray(@x), 0, SizeOf(x));
+End;
+
+
+Procedure MD5Init(Var Context: TMD5Context);
+Begin
+ FillChar(Context, SizeOf(Context), 0);
+ Context.state[0] := $67452301;
+ Context.state[1] := $EFCDAB89;
+ Context.state[2] := $98BADCFE;
+ Context.state[3] := $10325476;
+End;
+
+Procedure MD5Update(Var Context: TMD5Context; Input: PByteArray; InputLen: LongWord);
+Var
+ i, index, partLen: LongWord;
+
+Begin
+ index := LongWord((context.count[0] Shr 3) And $3F);
+ Inc(Context.count[0], UINT4(InputLen) Shl 3);
+ If Context.count[0] < UINT4(InputLen) Shl 3 Then Inc(Context.count[1]);
+ Inc(Context.count[1], UINT4(InputLen) Shr 29);
+ partLen := 64 - index;
+ If inputLen >= partLen Then Begin
+ MD5_memcpy(PByteArray(@Context.buffer[index]), Input, PartLen);
+ MD5Transform(@Context.state, @Context.buffer);
+ i := partLen;
+ While i + 63 < inputLen Do Begin
+ MD5Transform(@Context.state, PArray64Byte(@Input[i]));
+ Inc(i, 64);
+ End;
+ index := 0;
+ End Else i := 0;
+ MD5_memcpy(PByteArray(@Context.buffer[index]), PByteArray(@Input[i]), inputLen - i);
+End;
+
+
+Procedure MD5Final(Var Digest: TMD5Digest; Var Context: TMD5Context);
+Var
+ bits: Array[0..7] Of Byte;
+ index, padLen: LongWord;
+Begin
+ MD5Encode(PByteArray(@bits), PUINT4Array(@Context.count), 8);
+ index := LongWord((Context.count[0] Shr 3) And $3F);
+ If index < 56 Then padLen := 56 - index Else padLen := 120 - index;
+ MD5Update(Context, PByteArray(@PADDING), padLen);
+ MD5Update(Context, PByteArray(@Bits), 8);
+ MD5Encode(PByteArray(@Digest), PUINT4Array(@Context.state), 16);
+ MD5_memset(PByteArray(@Context), 0, SizeOf(Context));
+End;
+
+Function MD5DigestToStr(Const Digest: TMD5Digest): String;
+Var
+ i: Integer;
+Begin
+ Result := '';
+ For i := 0 To 15 Do Result := Result + IntToHex(Digest.v[i], 2);
+End;
+
+Function MD5String(Const S: String): TMD5Digest;
+Begin
+ Result := MD5Buffer(PChar(S)^, Length(S));
+End;
+
+Function MD5File(Const FileName: String): TMD5Digest;
+Var
+ F: TFileStream;
+Begin
+ F := TFileStream.Create(FileName, fmOpenRead);
+ Try
+ Result := MD5Stream(F);
+ Finally
+ F.Free;
+ End;
+End;
+
+Function MD5Stream(Const Stream: TStream): TMD5Digest;
+Var
+ Context: TMD5Context;
+ Buffer: Array[0..4095] Of Byte;
+ Size: Integer;
+ ReadBytes: Integer;
+ TotalBytes: Integer;
+ SavePos: Integer;
+Begin
+ MD5Init(Context);
+ Size := Stream.Size;
+ SavePos := Stream.Position;
+ TotalBytes := 0;
+ Try
+ Stream.Seek(0, soFromBeginning);
+ Repeat
+ ReadBytes := Stream.Read(Buffer, SizeOf(Buffer));
+ Inc(TotalBytes, ReadBytes);
+ MD5Update(Context, @Buffer, ReadBytes);
+ Until (ReadBytes = 0) Or (TotalBytes = Size);
+ Finally
+ Stream.Seek(SavePos, soFromBeginning);
+ End;
+ MD5Final(Result, Context);
+End;
+
+Function MD5Buffer(Const Buffer; Size: Integer): TMD5Digest;
+Var
+ Context: TMD5Context;
+Begin
+ MD5Init(Context);
+ MD5Update(Context, PByteArray(@Buffer), Size);
+ MD5Final(Result, Context);
+End;
+
+Function MD5DigestCompare(Const Digest1, Digest2: TMD5Digest): Boolean;
+Begin
+ Result := False;
+ If Digest1.A <> Digest2.A Then Exit;
+ If Digest1.B <> Digest2.B Then Exit;
+ If Digest1.C <> Digest2.C Then Exit;
+ If Digest1.D <> Digest2.D Then Exit;
+ Result := True;
+End;
+
+End.
diff --git a/plugins/MirandaNGHistoryToDB/MapStream.pas b/plugins/MirandaNGHistoryToDB/MapStream.pas
new file mode 100644
index 0000000000..af0b67409a
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/MapStream.pas
@@ -0,0 +1,185 @@
+{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+//*****************************************************************//
+// //
+// TMapStream //
+// Copyright BrandsPatch LLC //
+// http://www.explainth.at //
+// //
+// All Rights Reserved //
+// //
+// Permission is granted to use, modify and redistribute //
+// the code in this Delphi unit on the condition that this //
+// notice is retained unchanged. //
+// //
+// BrandsPatch declines all responsibility for any losses, //
+// direct or indirect, that may arise as a result of using //
+// this code. //
+// //
+//*****************************************************************//
+unit MapStream;
+
+interface
+
+uses Windows, SysUtils, Classes, SyncObjs;
+
+const MAXINTMINUS = MAXINT - 1;
+
+type TMapBytes = array[0..MAXINTMINUS] of Byte;
+ PMapBytes = ^TMapBytes;
+
+type TMapStream = class(TObject)
+private
+ FHandle: THandle;
+ FPosition: Integer;
+ FSize: Integer;
+ FTimeOut: Integer;
+ procedure SetPosition(Value: Integer);
+ function CountGood(Count: Integer):Boolean;
+ function GrabEvent: Boolean;
+ procedure ReleaseEvent;
+protected
+ FEvent: TEvent;
+ FMemory: PMapBytes;
+public
+ property Position: Integer read FPosition write SetPosition;
+ constructor CreateEx(const AName: String; ASize,ATimeOut: Integer);
+ destructor Destroy; override;
+ function Clear: Boolean;
+ function CopyFrom(AStream: TStream;Count: Integer): Boolean;
+ function ReadBuffer(P: Pointer; Count: Integer): Boolean;
+ function WriteBuffer(P: Pointer; Count: Integer): Boolean;
+end;
+
+type ENoMapping = class(Exception);
+
+implementation
+
+// MapStream Create & Destroy
+constructor TMapStream.CreateEx(const AName:String;ASize,ATimeOut:Integer);
+begin
+ inherited Create;
+ FSize := ASize;
+ FTimeOut := ATimeOut;
+ if (FSize < 1) or (FSize > MAXINTMINUS) then FSize:=MAXWORD;
+ if (FTimeOut < 1) or (FTimeOut > 5000) then FTimeOut:=2000;
+ //2000ms timeout for safety
+ FHandle:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,FSize,PChar(AName));
+ //See the Windows Kernel32 CreateFileMapping function for information
+ if (FHandle = 0) then ENoMapping.Create(Format('%s file mapping failed.',[AName]))
+ else begin
+ FMemory:=MapViewOfFile(FHandle,FILE_MAP_ALL_ACCESS,0,0,0);
+
+ FEvent:=TEvent.Create(nil,True,True,Format('ExplainThat_%s_MAP',[AName]));
+ {1. map a view of the file mapping into the address
+ space of the parent application
+
+ 2. create an event to prevent simultaneous access
+ to the map by different apps. We try to make the
+ event name unique so we don't end up with a handle to
+ an unrelated event that already exists
+ }
+ end;
+end;
+
+destructor TMapStream.Destroy;
+begin
+ UnMapViewOfFile(FMemory);
+ CloseHandle(FHandle);
+ FEvent.Free;
+ inherited;
+end;
+
+function TMapStream.CountGood(Count:Integer):Boolean;
+begin
+ Result:=(FPosition + Count < FSize);
+end;
+
+function TMapStream.GrabEvent:Boolean;
+begin
+ Result:=True;
+ with FEvent do
+ begin
+ case WaitFor(FTimeOut) of
+ wrSignaled:ReSetEvent;
+ {locks the event for exclusive use by this app. Funny name, ReSetEvent, not
+ our choice!}
+ else Result:=False;
+ end;
+ end;
+end;
+
+procedure TMapStream.ReleaseEvent;
+begin
+ FEvent.SetEvent; //unlock the event so other apps can use it
+end;
+
+// MapStream Manipulation
+function TMapStream.Clear:Boolean;
+begin
+ if GrabEvent then
+ try
+ FillChar(FMemory^[0],FSize,0);
+ FPosition:=0;
+ Result:=True;
+ finally ReleaseEvent end else Result:=False;
+end;
+
+function TMapStream.CopyFrom(AStream:TStream;Count:Integer):Boolean;
+
+ function SizeGood:Boolean;
+ var i,ASize:Integer;
+ begin
+ ASize:=AStream.Size;
+ if (Count = 0) or (Count > ASize) then
+ begin
+ Count:=ASize;
+ AStream.Position:=0;
+ end;
+ Result:=(FPosition + Count < FSize);
+ {make sure the copy block is not too big. Incidentally, also make Count = 0
+ as in Delphi.TStream}
+ end;
+
+begin
+ if SizeGood and GrabEvent then
+ try
+ AStream.ReadBuffer(Byte(FMemory^[FPosition]),Count);
+ Result:=True;
+ finally ReleaseEvent end else Result:=False;
+end;
+
+function TMapStream.ReadBuffer(P:Pointer;Count:Integer):Boolean;
+begin
+ if CountGood(Count) and GrabEvent then
+ try
+ Move(FMemory^[FPosition],P^,Count);
+ inc(FPosition,Count);
+ Result:=True;
+ finally ReleaseEvent end else Result:=False;
+end;
+
+function TMapStream.WriteBuffer(P:Pointer;Count:Integer):Boolean;
+begin
+ if CountGood(Count) and GrabEvent then
+ try
+ Move(P^,FMemory^[FPosition],Count);
+ inc(FPosition,Count);
+ Result:=True;
+ finally ReleaseEvent end else Result:=False;
+end;
+
+procedure TMapStream.SetPosition(Value:Integer);
+begin
+ if (Value < FSize) and (Value >= 0) then FPosition:=Value;
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/Menu.pas b/plugins/MirandaNGHistoryToDB/Menu.pas
new file mode 100644
index 0000000000..15d51a11b7
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/Menu.pas
@@ -0,0 +1,326 @@
+{ ################################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ################################################################################ }
+
+unit Menu;
+
+{$I jedi.inc}
+
+interface
+
+uses
+ Windows, Classes, SysUtils, ShellApi, MsgExport, m_api, Database, Global;
+
+type
+ TMenuItem = record
+ Name: String;
+ Icon: String;
+ Position: Integer;
+ Proc: TMIRANDASERVICEPARAM;
+ Flags: DWord;
+ end;
+
+var
+ MainMenuItems: Array [1..9] of TMenuItem;
+ MainMenuHandle: Array [1..9] of THandle;
+ MenuHandle: Array [1..9] of THandle;
+ ChildExport: TExportForm;
+
+procedure MenuMainItemsInit; cdecl; forward;
+procedure RebuildMainMenu; cdecl; forward;
+{$ifdef DELPHIXE_UP}
+function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl; forward;
+{$ELSE}
+function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl; forward;
+{$endif DELPHIXE_UP}
+
+implementation
+
+uses Contacts, About, FSMonitor;
+
+{ }
+procedure MenuMainItemsInit;
+begin
+ MainMenuItems[1].Name := WideStringToString(GetLangStr('SyncButton'), CP_ACP);
+ MainMenuItems[1].Icon := 'ICON_0';
+ MainMenuItems[1].Position := 000000;
+ MainMenuItems[1].Proc := MainMenuSync;
+
+ MainMenuItems[2].Name := WideStringToString(GetLangStr('ExportAllHistoryButton'), CP_ACP);
+ MainMenuItems[2].Icon := '';
+ MainMenuItems[2].Position := 100000;
+ MainMenuItems[2].Proc := MainMenuExportAllHistory;
+
+ MainMenuItems[3].Name := WideStringToString(GetLangStr('GetContactListButton'), CP_ACP);
+ MainMenuItems[3].Icon := '';
+ MainMenuItems[3].Position := 100001;
+ MainMenuItems[3].Proc := MainMenuGetContactList;
+
+ MainMenuItems[4].Name := WideStringToString(GetLangStr('CheckMD5Hash'), CP_ACP);
+ MainMenuItems[4].Icon := '';
+ MainMenuItems[4].Position := 100002;
+ MainMenuItems[4].Proc := MainMenuCheckMD5Hash;
+
+ MainMenuItems[5].Name := WideStringToString(GetLangStr('CheckAndDeleteMD5Hash'), CP_ACP);
+ MainMenuItems[5].Icon := '';
+ MainMenuItems[5].Position := 100003;
+ MainMenuItems[5].Proc := MainMenuCheckAndDeleteMD5Hash;
+
+ MainMenuItems[6].Name := WideStringToString(GetLangStr('UpdateContactListButton'), CP_ACP);
+ MainMenuItems[6].Icon := '';
+ MainMenuItems[6].Position := 100004;
+ MainMenuItems[6].Proc := MainMenuUpdateContactList;
+
+ MainMenuItems[7].Name := WideStringToString(GetLangStr('CheckUpdateButton'), CP_ACP);
+ MainMenuItems[7].Icon := '';
+ MainMenuItems[7].Position := 100004;
+ MainMenuItems[7].Proc := MainMenuCheckUpdate;
+
+ MainMenuItems[8].Name := WideStringToString(GetLangStr('SettingsButton'), CP_ACP);
+ MainMenuItems[8].Icon := '';
+ MainMenuItems[8].Position := 200000;
+ MainMenuItems[8].Proc := MainMenuSettings;
+
+ MainMenuItems[9].Name := WideStringToString(GetLangStr('AboutButton'), CP_ACP);
+ MainMenuItems[9].Icon := '';
+ MainMenuItems[9].Position := 300000;
+ MainMenuItems[9].Proc := MainMenuAbout;
+end;
+
+{ }
+procedure RebuildMainMenu;
+var
+ I: Integer;
+ Mi: TCListMenuItem;
+begin
+ //
+ MenuMainItemsInit;
+ //
+ for I := Low(MenuHandle) to High(MenuHandle) do
+ begin
+ ZeroMemory(@Mi, SizeOf(Mi));
+ Mi.cbSize := SizeOf(Mi);
+ Mi.flags := CMIM_FLAGS;
+ Mi.flags := Mi.flags or CMIM_NAME;
+ Mi.szName.a := pAnsiChar(AnsiString(MainMenuItems[I].Name));
+ CallService(MS_CLIST_MODIFYMENUITEM, MenuHandle[I], Windows.LPARAM(@Mi));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - RebuildMainMenu: ' + 'MainMenuName = ' + MainMenuItems[I].Name, 2);
+ end;
+end;
+
+{ }
+{$ifdef DELPHIXE_UP}
+function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuSync(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+begin
+ Result := 0;
+ OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '002');
+end;
+
+{ }
+{$ifdef DELPHIXE_UP}
+function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuExportAllHistory(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+begin
+ Result := 0;
+ if ExportFormDestroy then
+ ChildExport := TExportForm.Create(nil);
+ if not ChildExport.Showing then
+ ChildExport.Show
+ else
+ ChildExport.BringFormToFront(ChildExport);
+end;
+
+{ }
+{$ifdef DELPHIXE_UP}
+function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuGetContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+var
+ hContact: Cardinal;
+ ContactProto, ContactID, ContactName, GroupName: AnsiString;
+ AccountCount: Integer;
+ AccountName: ^PPROTOACCOUNT;
+begin
+ //
+ hContact := CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while hContact <> 0 do
+ begin
+ ContactProto := GetContactProto(hContact);
+ ContactID := GetContactID(hContact, ContactProto);
+ ContactName := GetContactDisplayName(hContact, '', True);
+ GroupName := GetDBStr(hContact , 'CList' , 'Group' , GetLangStr('ContactNotInTheList'));
+ if ContactName = '' then
+ ContactName := TranslateW('Unknown Contact');
+ if ContactID = '' then
+ ContactID := TranslateW('Unknown Contact');
+ if not ((MatchStrings(LowerCase(ContactProto), 'skype*')) or (ContactID = TranslateW('Unknown Contact')) or MatchStrings(LowerCase(ContactProto), 'metacontacts*')) then
+ WriteInLog(ProfilePath, Format('%s;%s;%s;%d', [ContactID, ContactName, GroupName, StrContactProtoToInt(ContactProto)]), 3);
+ hContact := CallService(MS_DB_CONTACT_FINDNEXT, hContact, 0);
+ end;
+ AccountCount := 0;
+ // ProtoList.csv
+ if (CallService(MS_PROTO_ENUMACCOUNTS, Integer(@AccountCount), Integer(@AccountName)) = 0) and (AccountCount <> 0) then
+ begin
+ while AccountCount > 0 do
+ begin
+ if not((AccountName^.szModuleName = 'MetaContacts') or (MatchStrings(LowerCase(AccountName^.szModuleName), 'skype*'))) then
+ //if not MatchStrings(LowerCase(AccountName^.szModuleName), 'skype*') then
+ WriteInLog(ProfilePath, Format('%s;%s;%d;%s;%s;%s', [AccountName^.szModuleName, GetMyContactID(AccountName^.szModuleName), StrContactProtoToInt(AccountName^.szProtoName), GetMyContactDisplayName(AccountName^.szModuleName), '', '']), 4);
+ Inc(AccountName);
+ Dec(AccountCount);
+ end;
+ end;
+ //
+ if ContactListLogOpened then
+ CloseLogFile(3);
+ if ProtoListLogOpened then
+ CloseLogFile(4);
+ Result := 0;
+ if (FileExists(ProfilePath + ContactListName)) and (FileExists(ProfilePath + ProtoListName)) then
+ MsgInf(htdPluginShortName, GetLangStr('SaveContactListCompleted'))
+ else
+ MsgInf(htdPluginShortName, GetLangStr('SaveContactListErr'));
+end;
+
+{ MD5- }
+{$ifdef DELPHIXE_UP}
+function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuCheckMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+begin
+ Result := 0;
+ OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '0050');
+end;
+
+{ MD5- }
+{$ifdef DELPHIXE_UP}
+function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuCheckAndDeleteMD5Hash(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+begin
+ Result := 0;
+ OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '0051');
+end;
+
+{ }
+{$ifdef DELPHIXE_UP}
+function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuUpdateContactList(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+begin
+ Result := 0;
+ if FileExists(ProfilePath+ContactListName) then
+ OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '007')
+ else
+ MsgInf(htdPluginShortName, Format(GetLangStr('SendUpdateContactListErr'), [ContactListName]));
+end;
+
+{ }
+{$ifdef DELPHIXE_UP}
+function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuCheckUpdate(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+var
+ WinName: String;
+begin
+ // HistoryToDBUpdater
+ WinName := 'HistoryToDBUpdater';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater ,
+ begin
+ WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater ,
+ begin
+ if FileExists(PluginPath + 'HistoryToDBUpdater.exe') then
+ begin
+ //
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBUpdater.exe'), PWideChar(' "'+ProfilePath+'"'), nil, SW_SHOWNORMAL);
+ end
+ else
+ MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_UPDATER'), [PluginPath + 'HistoryToDBUpdater.exe']));
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '0040');
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '0040');
+end;
+
+{ }
+{$ifdef DELPHIXE_UP}
+function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuSettings(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+var
+ WinName: String;
+begin
+ Result := 0;
+ // HistoryToDBViewer
+ WinName := 'HistoryToDBViewer';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer ,
+ begin
+ WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer ,
+ begin
+ if FileExists(PluginPath + 'HistoryToDBViewer.exe') then
+ begin
+ //
+ StopWatch;
+ WriteCustomINI(ProfilePath, 'SettingsFormRequestSend', '1');
+ StartWatch(ProfilePath, FILE_NOTIFY_CHANGE_LAST_WRITE, False, @ProfileDirChangeCallBack);
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" 4'), nil, SW_SHOWNORMAL);
+ end
+ else
+ MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe']));
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '005');
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '005');
+end;
+
+{ }
+{$ifdef DELPHIXE_UP}
+function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: LPARAM): int_ptr; cdecl;
+{$ELSE}
+function MainMenuAbout(wParam: wParam; lParam: lParam; lParam1: integer): integer; cdecl;
+{$endif DELPHIXE_UP}
+begin
+ Result := 0;
+ AboutForm.Show;
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr
new file mode 100644
index 0000000000..3f59234df9
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dpr
@@ -0,0 +1,935 @@
+{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+library MirandaNGHistoryToDB;
+
+{$I Global.inc}
+
+uses
+ madExcept,
+ madLinkDisAsm,
+ madListHardware,
+ madListProcesses,
+ madListModules,
+ m_api,
+ Windows,
+ SysUtils,
+ XMLIntf,
+ XMLDoc,
+ ShellApi,
+ WideStrUtils,
+ JclStringConversions,
+ Contacts in 'Contacts.pas',
+ Database in 'Database.pas',
+ Menu in 'Menu.pas',
+ About in 'About.pas',
+ MsgExport in 'MsgExport.pas' {ExportForm},
+ Global in 'Global.pas',
+ FSMonitor in 'FSMonitor.pas',
+ MapStream in 'MapStream.pas';
+
+// use it to make plugin unicode-aware
+{$DEFINE UNICODE}
+
+// tell Miranda about this plugin ExVersion
+function MirandaPluginInfoEx(mirandaVersion:DWORD): PPLUGININFOEX; cdecl;
+begin
+ PluginInfo.cbSize:= SizeOf(TPLUGININFOEX);
+ PluginInfo.shortName:= htdPluginShortName;
+ PluginInfo.version:= htdVersion;
+ PluginInfo.description:= htdDescription_EN;
+ PluginInfo.author:= htdAuthor_EN;
+ PluginInfo.authorEmail:= htdAuthorEmail;
+ PluginInfo.copyright:= htdCopyright_EN;
+ PluginInfo.homepage:= htdHomePageURL;
+ PluginInfo.flags:= UNICODE_AWARE;
+ PluginInfo.uuid:= MIID_HISTORYTODBDLL;
+ Result := @PluginInfo;
+end;
+
+var
+ {$ifdef REPLDEFHISTMOD}
+ PluginInterfaces: array[0..1] of TGUID;
+ {$else}
+ PluginInterfaces: array[0..0] of TGUID;
+ {$endif REPLDEFHISTMOD}
+
+ PluginStatus: Boolean = False;
+ StartExport: Boolean = False;
+ StartUpdate: Boolean = False;
+ DefaultINICopy: Boolean = False;
+
+ HookModulesLoad,
+ HookBuildMenu,
+ HookContactMenu,
+ HookSystemHistoryMenu,
+ {$ifdef REPLDEFHISTMOD}
+ HookShowMainHistory,
+ {$endif REPLDEFHISTMOD}
+ HookEventAdded,
+ //HookTTBLoaded,
+ HookShowHistoryAPI,
+ HookShowContactHistoryAPI,
+ HookShowVersionAPI: THandle;
+ //hTTBButton: THandle = 0;
+ DialogMainWindow: HWND = 0;
+
+const
+ hLangpack: THANDLE = 0;
+
+function OnModulesLoad(awParam:WPARAM; alParam:LPARAM): Integer; cdecl; forward;
+function OnBuildContactMenu(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; forward;
+function OnEventAdded(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; forward;
+//function OnTTBLoaded(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; forward;
+function OpenHistoryWindow(wParam:WPARAM;lParam:LPARAM): Integer; cdecl; forward;
+
+// tell Miranda about supported interfaces
+function MirandaPluginInterfaces:PMUUID; cdecl;
+begin
+ {$ifdef REPLDEFHISTMOD}
+ PluginInterfaces[0]:=MIID_UIHISTORY;
+ PluginInterfaces[1]:=MIID_LAST;
+ {$else}
+ PluginInterfaces[0]:=MIID_LAST;
+ {$endif REPLDEFHISTMOD}
+ Result := @PluginInterfaces;
+end;
+
+{ }
+function OpenHistoryWindow(wParam: WPARAM; lParam: LPARAM): Integer; cdecl;
+var
+ ContactProto, ContactID, ContactName: AnsiString;
+ MyContactName, MyContactID: AnsiString;
+ ProtoType: Integer;
+ WinName: String;
+begin
+ Result := 0;
+ ContactProto := GetContactProto(wParam);
+ ContactID := GetContactID(wParam, ContactProto);
+ ContactName := GetContactDisplayName(wParam, '', True);
+ MyContactName := GetMyContactDisplayName(ContactProto);
+ MyContactID := GetMyContactID(ContactProto);
+ if ContactID = '' then
+ ContactID := TranslateW('Unknown Contact');
+ if ContactName = '' then
+ ContactName := TranslateW('Unknown Contact');
+ if MyContactID = '' then
+ MyContactID := TranslateW('Unknown Contact');
+ if MyContactName = '' then
+ MyContactName := TranslateW('Unknown Contact');
+ // .
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName, 2);
+ //
+ ProtoType := StrContactProtoToInt(ContactProto);
+ // N
+ WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')';
+ if SearchMainWindow(pWideChar(WinName)) then
+ begin
+ // :
+ // :
+ // 008|0|UserID|UserName|ProtocolType
+ // :
+ // 008|2|ChatName
+ OnSendMessageToOneComponent(WinName, '008|0|'+ContactID+'|'+ContactName+'|'+IntToStr(ProtoType));
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: - 008|0|'+ContactID+'|'+ContactName+'|'+IntToStr(ProtoType), 2);
+ end
+ else
+ begin
+ if FileExists(PluginPath + 'HistoryToDBViewer.exe') then
+ begin
+ if MatchStrings(LowerCase(ContactProto), 'skype*') then // Skype
+ begin
+ // ( -)
+ Glogal_History_Type := 2;
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: ' + PluginPath + 'HistoryToDBViewer.exe' + ' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactName+'"', 2);
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactName+'"'), nil, SW_SHOWNORMAL);
+ end
+ else
+ begin
+ // ( IM-)
+ Glogal_History_Type := 0;
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - PluginContactMenuCommand: ' + PluginPath + 'HistoryToDBViewer.exe' + ' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactID+'" "'+ContactName+'" '+IntToStr(ProtoType), 2);
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactID+'" "'+ContactName+'" '+IntToStr(ProtoType)), nil, SW_SHOWNORMAL);
+ end;
+ end
+ else
+ MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe']));
+ end;
+end;
+
+{ }
+function OnBuildContactMenu(awParam: WPARAM; alParam: LPARAM): Integer; cdecl;
+var
+ MenuItem: TCLISTMENUITEM;
+ ContactProto, ContactID, ContactName: AnsiString;
+begin
+ Result := 0;
+ ContactProto := GetContactProto(awParam);
+ //
+ ZeroMemory(@MenuItem, SizeOf(MenuItem));
+ MenuItem.cbSize := SizeOf(MenuItem);
+ MenuItem.flags := CMIM_FLAGS;
+ if (ContactProto = MyAccount) or
+ MatchStrings(LowerCase(ContactProto), 'icq*') or
+ MatchStrings(LowerCase(ContactProto), 'jabber*') or
+ MatchStrings(LowerCase(ContactProto), 'aim*') or
+ MatchStrings(LowerCase(ContactProto), 'irc*') or
+ MatchStrings(LowerCase(ContactProto), 'msn*') or
+ MatchStrings(LowerCase(ContactProto), 'yahoo*') or
+ MatchStrings(LowerCase(ContactProto), 'gadu*') or
+ MatchStrings(LowerCase(ContactProto), 'skype*') or
+ MatchStrings(LowerCase(ContactProto), 'vkonta*') then
+ begin //
+ ContactID := GetContactID(awParam, ContactProto);
+ ContactName := GetContactDisplayName(awParam, '', True);
+ if ContactName = '' then
+ ContactName := TranslateW('Unknown Contact');
+ if ContactID = '' then
+ ContactID := TranslateW('Unknown Contact');
+ // .
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ MenuItem.flags := MenuItem.flags or CMIM_NAME;
+ MenuItem.szName.a := pAnsiChar(AnsiString(Format(WideStringToString(GetLangStr('ShowContactHistory'), CP_ACP), [ContactName, ContactID])));
+ CallService(MS_CLIST_MODIFYMENUITEM, HookContactMenu, lParam(@MenuItem));
+ if EnableDebug then //
+ WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnBuildContactMenu: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto, 2);
+ end
+ else //
+ begin
+ MenuItem.flags := MenuItem.flags or CMIF_HIDDEN;
+ CallService(MS_CLIST_MODIFYMENUITEM, HookContactMenu, lParam(@MenuItem));
+ if EnableDebug then //
+ begin
+ ContactID := GetContactID(awParam, ContactProto);
+ ContactName := GetContactDisplayName(awParam, '', True);
+ if ContactName = '' then
+ ContactName := TranslateW('Unknown Contact');
+ if ContactID = '' then
+ ContactID := TranslateW('Unknown Contact');
+ // .
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnBuildContactMenu: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto, 2);
+ end;
+ end;
+end;
+
+{ }
+function OnEventAdded(wParam: WPARAM; lParam: LPARAM): Integer; cdecl;
+var
+ ContactProto, ContactID, ContactName: AnsiString;
+ MyContactName, MyContactID: AnsiString;
+ BlobSize, ProtoType: Integer;
+ DBEventInfo: TDBEventInfo;
+ msgA: PAnsiChar;
+ msgW: PChar;
+ msgLen, LenW: Cardinal;
+ I: Integer;
+ Msg_RcvrNick, Msg_RcvrAcc, Msg_SenderNick, Msg_SenderAcc, Msg_Text, MD5String: WideString;
+ Date_Str, MsgStatus: String;
+ InsertSQLData, EncInsertSQLData, WinName: String;
+ ASize: Integer;
+ hContact: THandle;
+begin
+ Result := 0;
+ ZeroMemory(@DBEventInfo, SizeOf(DBEventInfo));
+ DBEventInfo.cbSize := SizeOf(DBEventInfo);
+ DBEventInfo.pBlob := nil;
+ BlobSize := CallService(MS_DB_EVENT_GETBLOBSIZE, lParam, 0);
+ GetMem(DBEventInfo.pBlob, BlobSize);
+ DBEventInfo.cbBlob := BlobSize;
+ if (CallService(MS_DB_EVENT_GET, lParam, Integer(@DBEventInfo)) = 0) and (DBEventInfo.eventType = EVENTTYPE_MESSAGE and EVENTTYPE_URL) then
+ begin
+ //
+ msgA := PAnsiChar(DBEventInfo.pBlob);
+ msgW := nil;
+ msgLen := lstrlenA(PAnsiChar(DBEventInfo.pBlob)) + 1;
+ if msgLen > DBEventInfo.cbBlob then
+ msgLen := DBEventInfo.cbBlob;
+ if Boolean(DBEventInfo.flags and DBEF_UTF) then
+ begin
+ SetLength(Msg_Text, msgLen);
+ LenW := Utf8ToWideChar(PChar(Msg_Text), msgLen, msgA, msgLen - 1, CP_ACP);
+ if Integer(LenW) > 0 then
+ SetLength(Msg_Text, LenW - 1)
+ else
+ Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1);
+ end
+ else
+ begin
+ LenW := 0;
+ if DBEventInfo.cbBlob >= msgLen * SizeOf(Char) then
+ begin
+ msgW := PChar(msgA + msgLen);
+ for i := 0 to ((DBEventInfo.cbBlob - msgLen) div SizeOf(Char)) - 1 do
+ if msgW[i] = #0 then
+ begin
+ LenW := i;
+ Break;
+ end;
+ end;
+ if (LenW > 0) and (LenW < msgLen) then
+ SetString(Msg_Text, msgW, LenW)
+ else
+ Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1);
+ end;
+ //
+ hContact := wParam;
+ ContactProto := GetContactProto(hContact);
+ ProtoType := StrContactProtoToInt(ContactProto);
+ // ,
+ // ..
+ if ProtoType = 15 then
+ Exit;
+ //
+ ContactID := GetContactID(hContact, ContactProto);
+ ContactName := GetContactDisplayName(hContact, '', True);
+ //
+ MyContactName := GetMyContactDisplayName(ContactProto);
+ MyContactID := GetMyContactID(ContactProto);
+ // .
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ ProtoType := StrContactProtoToInt(ContactProto);
+ // End
+ if ContactID = '' then
+ ContactID := TranslateW('Unknown Contact');
+ if ContactName = '' then
+ ContactName := TranslateW('Unknown Contact');
+ if MyContactID = '' then
+ MyContactID := TranslateW('Unknown Contact');
+ if MyContactName = '' then
+ MyContactName := TranslateW('Unknown Contact');
+ // MyContactID ContactName
+ //
+ {if (ProtoType = 15) and (MyContactID = TranslateW('Unknown Contact')) and (MyContactName <> TranslateW('Unknown Contact')) then
+ MyContactID := MyContactName;
+ if (ProtoType = 15) and (ContactName = TranslateW('Unknown Contact')) and (ContactID <> TranslateW('Unknown Contact')) then
+ ContactName := ContactID;}
+ // , ..
+ Msg_SenderNick := PrepareString(pWideChar(AnsiToWideString(MyContactName, CP_ACP)));
+ Msg_SenderAcc := PrepareString(pWideChar(AnsiToWideString(MyContactID, CP_ACP)));
+ Msg_SenderNick := WideStringToUTF8(Msg_SenderNick);
+ Msg_SenderAcc := WideStringToUTF8(Msg_SenderAcc);
+ Msg_RcvrNick := PrepareString(pWideChar(AnsiToWideString(ContactName, CP_ACP)));
+ Msg_RcvrAcc := PrepareString(pWideChar(AnsiToWideString(ContactID, CP_ACP)));
+ Msg_RcvrNick := WideStringToUTF8(Msg_RcvrNick);
+ Msg_RcvrAcc := WideStringToUTF8(Msg_RcvrAcc);
+ Msg_Text := WideStringToUTF8(PrepareString(pWideChar(Msg_Text)));
+ MD5String := Msg_RcvrAcc + FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + Msg_Text;
+ if (DBType = 'oracle') or (DBType = 'oracle-9i') then
+ Date_Str := FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp))
+ else
+ Date_Str := FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp));
+ if MatchStrings(LowerCase(ContactProto), 'skype*') then
+ begin
+ // ( )
+ if (DBEventInfo.flags and DBEF_SENT) = 0 then
+ MsgStatus := '0' //
+ else
+ MsgStatus := '1'; //
+ //
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2);
+ if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- CHAT_MSG_LOG_ORACLE
+ InsertSQLData := Format(CHAT_MSG_LOG_ORACLE, [DBUserName, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)])
+ else
+ InsertSQLData := Format(CHAT_MSG_LOG, [DBUserName, MsgStatus, Date_Str, Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]);
+ end
+ else
+ begin
+ // ( )
+ if (DBEventInfo.flags and DBEF_SENT) = 0 then
+ MsgStatus := '1' //
+ else
+ MsgStatus := '0'; //
+ //
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2);
+ if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- MSG_LOG_ORACLE
+ InsertSQLData := Format(MSG_LOG_ORACLE, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_Text, EncryptMD5(MD5String)])
+ else
+ InsertSQLData := Format(MSG_LOG, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, Date_Str, Msg_Text, EncryptMD5(MD5String)]);
+ end;
+ // MMF
+ if SyncMethod = 0 then
+ begin
+ WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')';
+ if SearchMainWindow(pWideChar(WinName)) then
+ begin
+ EncInsertSQLData := EncryptStr(InsertSQLData);
+ ASize := 2*Length(EncInsertSQLData);
+ with FMap do
+ begin
+ Clear;
+ WriteBuffer(@ASize,Sizeof(Integer));
+ WriteBuffer(PChar(EncInsertSQLData),ASize);
+ end;
+ // ,
+ OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '010');
+ end
+ else
+ WriteInLog(ProfilePath, InsertSQLData, 0);
+ end
+ else // SQL-
+ WriteInLog(ProfilePath, InsertSQLData, 0);
+ //
+ if SyncMethod = 2 then
+ begin
+ if (SyncInterval > 4) and (SyncInterval < 8) then
+ begin
+ Inc(MessageCount);
+ if (SyncInterval = 5) and (MessageCount = 10) then
+ begin
+ OnSendMessageToAllComponent('002');
+ MessageCount := 0;
+ end;
+ if (SyncInterval = 6) and (MessageCount = 20) then
+ begin
+ OnSendMessageToAllComponent('002');
+ MessageCount := 0;
+ end;
+ if (SyncInterval = 7) and (MessageCount = 30) then
+ begin
+ OnSendMessageToAllComponent('002');
+ MessageCount := 0;
+ end;
+ end;
+ if SyncInterval = 9 then
+ begin
+ Inc(MessageCount);
+ if MessageCount = SyncMessageCount then
+ begin
+ OnSendMessageToAllComponent('002');
+ MessageCount := 0;
+ end;
+ end;
+ end;
+ end;
+end;
+
+{function OnTTBLoaded(awParam: WPARAM; alParam: LPARAM): Integer; cdecl;
+var
+ TTB: TTBButtonV2;
+begin
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnTTBLoaded', 2);
+ if hTTBButton <> 0 then
+ begin
+ if ServiceExists(MS_TTB_REMOVEBUTTON)>0 then
+ begin
+ CallService(MS_TTB_REMOVEBUTTON, WPARAM(hTTBButton),0);
+ hTTBButton := 0;
+ end;
+ end;
+ if ShowPluginButton then
+ begin
+ if ServiceExists(MS_TTB_ADDBUTTON) > 0 then
+ begin
+ ZeroMemory(@TTB, SizeOf(TTB));
+ TTB.cbSize := SizeOf(TTB);
+ TTB.pszServiceUp := MHTD_SHOWSERVICE;
+ TTB.pszServiceDown:= MHTD_SHOWSERVICE;
+ TTB.hIconUp := LoadImage(hInstance, 'ICON_0', IMAGE_ICON, 16, 16, 0);
+ TTB.hIconDn := ttb.hIconUp;
+ TTB.dwFlags := TTBBF_VISIBLE;
+ TTB.name := htdDBName;
+ hTTBButton := CallService(MS_TTB_ADDBUTTON, WPARAM(@TTB), 0);
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnTTBLoaded: .', 2);
+ end;
+ end;
+ Result := 0;
+end;}
+
+{ C MS_MHTD_SHOWHISTORY
+ m_historytodb.inc }
+function HTDBShowHistory(wParam { 0 } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl;
+var
+ WinName: String;
+begin
+ Result := 0;
+ // HistoryToDBViewer
+ WinName := 'HistoryToDBViewer';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer ,
+ begin
+ WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBViewer ,
+ begin
+ if FileExists(PluginPath + 'HistoryToDBViewer.exe') then
+ begin
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'"'), nil, SW_SHOWNORMAL);
+ end
+ else
+ MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe']));
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '0040');
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '0040');
+end;
+
+{ C MS_MHTD_SHOWCONTACTHISTORY
+ m_historytodb.inc }
+function HTDBShowContactHistory(wParam { hContact } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl;
+begin
+ Result := OpenHistoryWindow(wParam, 0);
+end;
+
+{ C MS_MHTD_GETVERSION
+ m_historytodb.inc }
+function HTDBGetVersion(wParam { 0 } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl;
+begin
+ Result := htdVersion;
+end;
+
+function OnModulesLoad(awParam{0}:WPARAM; alParam{0}:LPARAM):integer; cdecl;
+var
+ Mi: TCListMenuItem;
+ //{$ifdef REPLDEFHISTMOD}
+ Si: TCListMenuItem;
+ //{$endif REPLDEFHISTMOD}
+ AutoCoreLang, UpdTmpPath, WinName: String;
+ I: Byte;
+ MenuMainService: PAnsiChar;
+ //IMUPD: TUpdate;
+begin
+ // -
+ MsgLogOpened := False;
+ ErrLogOpened := False;
+ DebugLogOpened := False;
+ ContactListLogOpened := False;
+ ProtoListLogOpened := False;
+ ImportLogOpened := False;
+ //
+ EncryptInit;
+ //
+ if FileExists(ExtractFilePath(ParamStr(0))+'Langpack_russian.txt') then
+ AutoCoreLang := 'Russian'
+ else
+ AutoCoreLang := 'English';
+ //
+ OnSendMessageToAllComponent('003');
+ //
+ if FileExists(PluginPath + DefININame) then
+ begin
+ if FileExists(ProfilePath + ININame) then
+ RenameFile(ProfilePath + ININame, ProfilePath + ININame + '.' + FormatDateTime('ddmmyyhhmmss', Now));
+ if CopyFileEx(PChar(PluginPath + DefININame), PChar(ProfilePath + ININame), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then
+ begin
+ DefaultINICopy := True;
+ if FileExists(ProfilePath + ININame) then
+ DeleteFile(PluginPath + DefININame);
+ end;
+ end;
+ //
+ if (GetDBInt(htdDBName, 'FirstRun.FirstActivate', 0) = 0) or (DefaultINICopy) then
+ begin
+ if AutoCoreLang = 'Russian' then
+ begin
+ case MessageBox(DialogMainWindow, PWideChar(' ' + htdPluginShortName + '.' + #13 +
+ ' .' + #13 +
+ ' ?'), PWideChar(htdPluginShortName),36) of
+ 6: StartExport := True; //
+ 7: StartExport := False; //
+ end;
+ end
+ else
+ begin
+ case MessageBox(DialogMainWindow, PWideChar('The first time you activate the plugin ' + htdPluginShortName + '.' + #13 +
+ 'To work correctly, check your plug-in connection to the database.' + #13 +
+ 'Do you want to start exporting the history?'), PWideChar(htdPluginShortName),36) of
+ 6: StartExport := True; //
+ 7: StartExport := False; //
+ end;
+ end;
+ end;
+ //
+ if GetDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 0) = 0 then
+ begin
+ if AutoCoreLang = 'Russian' then
+ begin
+ //MsgInf(htdPluginShortName, ' ' + htdPluginShortName + '.' + #13 + ' .' + #13 + ' ' + htdPluginShortName + '.')
+ case MessageBox(DialogMainWindow, PWideChar(' ' + htdPluginShortName + '.' + #13 +
+ ' .' + #13 +
+ ' ?'), PWideChar(htdPluginShortName),36) of
+ 6: StartUpdate := True; //
+ 7: StartUpdate := False; //
+ end;
+ end
+ else
+ begin
+ //MsgInf(htdPluginShortName, 'The first time you activate the plugin ' + htdPluginShortName + '.' + #13 + 'To work correctly, check your plug-in connection to the database.' + #13 + 'Thank you for using the plugin ' + htdPluginShortName + '.');
+ case MessageBox(DialogMainWindow, PWideChar('The first time you activate the plugin ' + htdPluginShortName + '.' + #13 +
+ 'To work correctly, the plugin must run the update plugin via the Internet.' + #13 +
+ 'Do you want to start the update process?'), PWideChar(htdPluginShortName),36) of
+ 6: StartUpdate := True; //
+ 7: StartUpdate := False; //
+ end;
+ end;
+ end;
+ //
+ if AutoCoreLang <> DefaultLanguage then
+ begin
+ CoreLanguage := AutoCoreLang;
+ WriteCustomINI(ProfilePath, 'DefaultLanguage', CoreLanguage);
+ end
+ else
+ CoreLanguage := DefaultLanguage;
+ //
+ LangDoc := NewXMLDocument();
+ CoreLanguageChanged;
+ // IM
+ WriteCustomINI(ProfilePath, 'IMClientType', htdIMClientName);
+ WriteCustomINI(ProfilePath, 'IMClientPlatformType', htdPlatform);
+ //
+ WriteCustomINI(ProfilePath, 'SettingsFormRequestSend', '0');
+ // About Export
+ if not Assigned(AboutForm) then
+ AboutForm := TAboutForm.Create(nil);
+ ExportFormDestroy := True;
+ // API -
+ HookShowHistoryAPI := CreateServiceFunction(MS_MHTD_SHOWHISTORY, @HTDBShowHistory);
+ // API -
+ HookShowContactHistoryAPI := CreateServiceFunction(MS_MHTD_SHOWCONTACTHISTORY, @HTDBShowContactHistory);
+ // API -
+ HookShowVersionAPI := CreateServiceFunction(MS_MHTD_GETVERSION, @HTDBGetVersion);
+ //
+ MenuMainItemsInit;
+ //
+ FillChar(Mi, SizeOf(Mi), 0);
+ Mi.cbSize := SizeOf(Mi);
+ Mi.szPopupName.a := '&' + htdPluginShortName;
+ Mi.popupPosition := 500000;
+ Mi.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0);
+ Mi.flags := 0;
+ for I := Low(MainMenuItems) to High(MainMenuItems) do
+ begin
+ if MainMenuItems[I].Icon = '' then
+ Mi.hIcon := 0
+ else
+ Mi.hIcon := LoadImage(hInstance, pChar(MainMenuItems[I].Icon), IMAGE_ICON, 16, 16, 0);
+ Mi.szName.a := pAnsiChar(AnsiString(MainMenuItems[I].Name));
+ MenuMainService := pAnsiChar(AnsiString(Format('%s/MainMenuCommand%d', [htdPluginShortName, I])));
+ //if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - Load: ' + 'MenuMainName = ' + MenuMainItems[I].Name + ' | MenuMainService = ' + MenuMainService, 2);
+ MainMenuHandle[I] := CreateServiceFunctionParam(MenuMainService, @MainMenuItems[I].Proc, I);
+ Mi.pszService := MenuMainService;
+ Mi.Position := MainMenuItems[I].Position;
+ MenuHandle[I] := CallService(MS_CLIST_ADDMAINMENUITEM, 0, Windows.LPARAM(@Mi));
+ end;
+ //
+ //{$ifdef REPLDEFHISTMOD}
+ FillChar(Si, SizeOf(Si), 0);
+ Si.cbSize := SizeOf(Si);
+ Si.Position := 500060000;
+ Si.szName.a := pAnsiChar(AnsiString(Format(WideStringToString(GetLangStr('IMButtonCaption'), CP_ACP), [htdPluginShortName])));
+ Si.pszService := MS_MHTD_SHOWHISTORY;//MS_HISTORY_SHOWCONTACTHISTORY;
+ Si.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0);;
+ HookSystemHistoryMenu := CallService(MS_CLIST_ADDMAINMENUITEM,0,LPARAM(@Si));
+ //{$endif REPLDEFHISTMOD}
+ //
+ CreateServiceFunction(htdPluginShortName+'/ContactMenuCommand', @OpenHistoryWindow);
+ Mi.pszContactOwner := nil; //
+ Mi.cbSize := SizeOf(Mi);
+ Mi.position := 1000090000;
+ Mi.flags := 0;
+ Mi.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0);
+ Mi.szName.a := pAnsiChar(WideStringToString(GetLangStr('ShowOneContactHistory'), CP_ACP));
+ Mi.pszService := htdPluginShortName+'/ContactMenuCommand';
+ HookContactMenu := CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, LPARAM(@Mi));
+ //
+ HookBuildMenu := HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnBuildContactMenu);
+ //
+ HookEventAdded := HookEvent(ME_DB_EVENT_ADDED, OnEventAdded);
+ //
+ {$ifdef REPLDEFHISTMOD}
+ HookShowMainHistory := CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY, @OpenHistoryWindow);
+ {$endif REPLDEFHISTMOD}
+ // TopToolBar
+ //HookTTBLoaded := HookEvent(ME_TTB_MODULELOADED, OnTTBLoaded);
+ // Register in updater
+ {if Boolean(ServiceExists(MS_UPDATE_REGISTER)) then
+ begin
+ ZeroMemory(@IMUPD,SizeOf(IMUPD));
+ IMUPD.cbSize := SizeOf(IMUPD);
+ IMUPD.szComponentName := htdPluginShortName;
+ IMUPD.pbVersion := @hppVersionStr[1];
+ IMUPD.cpbVersion := Length(hppVersionStr);
+ // File listing section
+ //IMUPD.szUpdateURL = UPDATER_AUTOREGISTER;
+ IMUPD.szUpdateURL := htdFLUpdateURL;
+ IMUPD.szVersionURL := htdFLVersionURL;
+ IMUPD.pbVersionPrefix := htdFLVersionPrefix;
+ IMUPD.cpbVersionPrefix := Length(htdFLVersionPrefix);
+ // Alpha-beta section
+ IMUPD.szBetaUpdateURL := htdUpdateURL;
+ IMUPD.szBetaVersionURL := htdVersionURL;
+ IMUPD.pbBetaVersionPrefix := htdVersionPrefix;
+ IMUPD.cpbBetaVersionPrefix := Length(htdVersionPrefix);
+ IMUPD.szBetaChangelogURL := htdChangelogURL;
+ CallService(MS_UPDATE_REGISTER, 0, LPARAM(@IMUPD));
+ end;}
+ // dbeditor
+ CallService(MS_DBEDIT_REGISTERSINGLEMODULE, WPARAM(PAnsiChar(htdDBName)), 0);
+ {
+ FILE_NOTIFY_CHANGE_FILE_NAME = $00000001;//
+ FILE_NOTIFY_CHANGE_DIR_NAME = $00000002;//
+ FILE_NOTIFY_CHANGE_ATTRIBUTES = $00000004;//
+ FILE_NOTIFY_CHANGE_SIZE = $00000008;//
+ FILE_NOTIFY_CHANGE_LAST_WRITE = $00000010;//
+ FILE_NOTIFY_CHANGE_LAST_ACCESS = $00000020;//
+ FILE_NOTIFY_CHANGE_CREATION = $00000040;//
+ FILE_NOTIFY_CHANGE_SECURITY = $00000100;//
+ }
+ StartWatch(ProfilePath, FILE_NOTIFY_CHANGE_LAST_WRITE, False, @ProfileDirChangeCallBack);
+ // MMF
+ if SyncMethod = 0 then
+ FMap := TMapStream.CreateEx('HistoryToDB for ' + htdIMClientName + ' ('+MyAccount+')',MAXDWORD,2000);
+ //
+ PluginStatus := True;
+ // .
+ MessageCount := 0;
+ //
+ WriteDBInt(htdDBName, 'FirstRun.FirstActivate', 1);
+ // HistoryToDBUpdater.exe
+ UpdTmpPath := GetUserTempPath + 'IMHistory\';
+ if FileExists(UpdTmpPath + 'HistoryToDBUpdater.exe') then
+ begin
+ // HistoryToDBUpdater
+ WinName := 'HistoryToDBUpdater';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater ,
+ begin
+ WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')';
+ if SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater ,
+ OnSendMessageToOneComponent(WinName, '009');
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '009');
+ Sleep(800);
+ //
+ if DeleteFile(PluginPath + 'HistoryToDBUpdater.exe') then
+ begin
+ if CopyFileEx(PChar(UpdTmpPath + 'HistoryToDBUpdater.exe'), PChar(PluginPath + 'HistoryToDBUpdater.exe'), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then
+ begin
+ DeleteFile(UpdTmpPath + 'HistoryToDBUpdater.exe');
+ if CoreLanguage = 'Russian' then
+ MsgInf(htdPluginShortName, Format(' %s .', ['HistoryToDBUpdater.exe']))
+ else
+ MsgInf(htdPluginShortName, Format('Update utility %s successfully updated.', ['HistoryToDBUpdater.exe']));
+ end;
+ end
+ else
+ begin
+ DeleteFile(UpdTmpPath + 'HistoryToDBUpdater.exe');
+ if CoreLanguage = 'Russian' then
+ MsgDie(htdPluginShortName, Format(' %s .', [PluginPath + 'HistoryToDBUpdater.exe']))
+ else
+ MsgDie(htdPluginShortName, Format('Error update utility %s', [PluginPath + 'HistoryToDBUpdater.exe']));
+ end;
+ end;
+ // HistoryToDBUpdater.exe
+ if FileExists(PluginPath + 'HistoryToDBUpdater.upd') then
+ begin
+ // HistoryToDBUpdater
+ WinName := 'HistoryToDBUpdater';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater ,
+ begin
+ WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')';
+ if SearchMainWindow(pWideChar(WinName)) then // HistoryToDBUpdater ,
+ OnSendMessageToOneComponent(WinName, '009');
+ end
+ else //
+ OnSendMessageToOneComponent(WinName, '009');
+ Sleep(800);
+ //
+ if DeleteFile(PluginPath + 'HistoryToDBUpdater.exe') then
+ begin
+ if CopyFileEx(PChar(PluginPath + 'HistoryToDBUpdater.upd'), PChar(PluginPath + 'HistoryToDBUpdater.exe'), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then
+ begin
+ DeleteFile(PluginPath + 'HistoryToDBUpdater.upd');
+ if CoreLanguage = 'Russian' then
+ MsgInf(htdPluginShortName, Format(' %s .', ['HistoryToDBUpdater.exe']))
+ else
+ MsgInf(htdPluginShortName, Format('Update utility %s successfully updated.', ['HistoryToDBUpdater.exe']));
+ end;
+ end
+ else
+ begin
+ DeleteFile(PluginPath + 'HistoryToDBUpdater.upd');
+ if CoreLanguage = 'Russian' then
+ MsgDie(htdPluginShortName, Format(' %s .', [PluginPath + 'HistoryToDBUpdater.exe']))
+ else
+ MsgDie(htdPluginShortName, Format('Error update utility %s', [PluginPath + 'HistoryToDBUpdater.exe']));
+ end;
+ end;
+ //
+ if StartUpdate then
+ begin
+ if FileExists(PluginPath + 'HistoryToDBUpdater.exe') then
+ begin
+ //
+ WriteDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 1);
+ //
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBUpdater.exe'), PWideChar(' "'+ProfilePath+'"'), nil, SW_SHOWNORMAL);
+ end
+ else
+ MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_UPDATER'), [PluginPath + 'HistoryToDBUpdater.exe']));
+ end
+ else
+ begin
+ //
+ if GetDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 0) = 0 then
+ WriteDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 1); //
+ end;
+ //
+ if StartExport then
+ begin
+ if ExportFormDestroy then
+ ChildExport := TExportForm.Create(nil);
+ if Assigned(ChildExport) then
+ begin
+ if not ChildExport.Showing then
+ ChildExport.Show
+ else
+ ChildExport.BringFormToFront(ChildExport);
+ end;
+ end;
+ // , HistoryToDBSync
+ if not StartUpdate then
+ begin
+ if FileExists(PluginPath + 'HistoryToDBSync.exe') then
+ begin
+ WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')';
+ if not SearchMainWindow(pWideChar(WinName)) then // HistoryToDBSync for QIP ,
+ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBSync.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'"'), nil, SW_SHOWNORMAL)
+ end
+ else
+ begin
+ if CoreLanguage = 'Russian' then
+ MsgInf(htdPluginShortName, Format(' %s .' + #13 + ' .', [PluginPath + 'HistoryToDBSync.exe']))
+ else
+ MsgInf(htdPluginShortName, Format('The history synchronization program %s not found.' + #13 + 'Begin the process of updating the plugin.', [PluginPath + 'HistoryToDBSync.exe']));
+ end;
+ end;
+ Result := 0;
+end;
+
+function Load():Integer; cdecl;
+var
+ ProfileName, TmpProfilePath: String;
+ Str: PAnsiChar;
+begin
+ CallService(MS_LANGPACK_REGISTER,WPARAM(@hLangpack),LPARAM(@PluginInfo));
+ //
+ hppCodepage := CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
+ if (hppCodepage = CALLSERVICE_NOTFOUND) or (hppCodepage = CP_ACP) then
+ hppCodepage := GetACP();
+ // -
+ MetaContactsEnabled := Boolean(ServiceExists(MS_MC_GETMOSTONLINECONTACT));
+ if MetaContactsEnabled then
+ begin
+ Str := pAnsiChar(CallService(MS_MC_GETPROTOCOLNAME, 0, 0));
+ if Assigned(Str) then
+ MetaContactsProto := AnsiString(Str)
+ else
+ MetaContactsEnabled := False;
+ end;
+ //
+ SetLength(DllPath, MAX_PATH);
+ SetLength(DllPath, GetModuleFileNameW(hInstance, @DllPath[1], MAX_PATH));
+ PluginPath := ExtractFilePath(DllPath);
+ // (USERNAME\USERNAME.dat)
+ SetLength(TmpProfilePath, MAX_PATH);
+ CallService(MS_DB_GETPROFILEPATH, MAX_PATH, lParam(@TmpProfilePath[1]));
+ SetLength(TmpProfilePath, StrLen(pAnsiChar(@TmpProfilePath[1])));
+ TmpProfilePath := pAnsiChar(TmpProfilePath) + PathDelim;
+ //
+ SetLength(ProfileName, MAX_PATH);
+ CallService(MS_DB_GETPROFILENAME, MAX_PATH, lParam(@ProfileName[1]));
+ SetLength(ProfileName, StrLen(pAnsiChar(@ProfileName[1])));
+ // USERNAME.dat
+ TmpProfilePath := TmpProfilePath + ExtractFileNameEx(TmpProfilePath+pAnsiChar(ProfileName), False) + PathDelim;
+ if DirectoryExists(TmpProfilePath) then
+ ProfilePath := TmpProfilePath
+ else
+ ProfilePath := ExtractFilePath(DllPath);
+ //
+ LoadINI(ProfilePath);
+ // ,
+ MyAccount := ExtractFileNameEx(pAnsiChar(ProfileName), False);
+ WriteCustomINI(ProfilePath, 'MyAccount', MyAccount);
+ //
+ HookModulesLoad := HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoad);
+ Result := 0;
+end;
+
+function Unload: int; cdecl;
+var
+ I: Byte;
+begin
+ Result := 0;
+ if PluginStatus then
+ begin
+ //
+ StopWatch;
+ if Assigned(AboutForm) then FreeAndNil(AboutForm);
+ if Assigned(ExportForm) then FreeAndNil(ExportForm);
+ //
+ for I := Low(MainMenuHandle) to High(MainMenuHandle) do
+ begin
+ DestroyServiceFunction(MainMenuHandle[I]);
+ DestroyServiceFunction(MenuHandle[I]);
+ end;
+ {$ifdef REPLDEFHISTMOD}
+ DestroyServiceFunction(HookShowMainHistory);
+ {$endif REPLDEFHISTMOD}
+ DestroyServiceFunction(HookShowHistoryAPI);
+ DestroyServiceFunction(HookShowContactHistoryAPI);
+ DestroyServiceFunction(HookShowVersionAPI);
+ //{$ifdef REPLDEFHISTMOD}
+ UnhookEvent(HookSystemHistoryMenu);
+ //{$endif REPLDEFHISTMOD}
+ UnhookEvent(HookContactMenu);
+ //UnhookEvent(HookTTBLoaded);
+ UnhookEvent(HookEventAdded);
+ UnhookEvent(HookBuildMenu);
+ UnhookEvent(HookModulesLoad);
+ //
+ OnSendMessageToAllComponent('003');
+ // -
+ if MsgLogOpened then
+ CloseLogFile(0);
+ if ErrLogOpened then
+ CloseLogFile(1);
+ if DebugLogOpened then
+ CloseLogFile(2);
+ if ContactListLogOpened then
+ CloseLogFile(3);
+ if ProtoListLogOpened then
+ CloseLogFile(4);
+ //
+ EncryptFree;
+ // MMF
+ if Assigned(FMap) then
+ FMap.Free;
+ // .
+ LangDoc.Active := False;
+ end;
+end;
+
+exports
+ MirandaPluginInfoEx,
+ MirandaPluginInterfaces,
+ Load,
+ Unload;
+
+begin
+end.
+
diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj
new file mode 100644
index 0000000000..3fc30e6265
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.dproj
@@ -0,0 +1,226 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{E69B7AEB-9B0F-45CB-A345-314CBE1E2449}</ProjectGuid>
+ <MainSource>MirandaNGHistoryToDB.dpr</MainSource>
+ <Base>True</Base>
+ <Config Condition="'$(Config)'==''">Release</Config>
+ <AppType>Library</AppType>
+ <FrameworkType>None</FrameworkType>
+ <DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+ <ProjectVersion>14.4</ProjectVersion>
+ <Platform Condition="'$(Platform)'==''">Win32</Platform>
+ <TargetedPlatforms>3</TargetedPlatforms>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
+ <Base_Win32>true</Base_Win32>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
+ <Base_Win64>true</Base_Win64>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+ <Cfg_1>true</Cfg_1>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
+ <Cfg_1_Win32>true</Cfg_1_Win32>
+ <CfgParent>Cfg_1</CfgParent>
+ <Cfg_1>true</Cfg_1>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
+ <Cfg_1_Win64>true</Cfg_1_Win64>
+ <CfgParent>Cfg_1</CfgParent>
+ <Cfg_1>true</Cfg_1>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+ <Cfg_2>true</Cfg_2>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base)'!=''">
+ <VerInfo_Locale>1049</VerInfo_Locale>
+ <DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;Winapi;Vcl;$(DCC_Namespace)</DCC_Namespace>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ <DCC_E>false</DCC_E>
+ <DCC_F>false</DCC_F>
+ <DCC_ImageBase>00400000</DCC_ImageBase>
+ <DCC_S>false</DCC_S>
+ <GenDll>true</GenDll>
+ <DCC_K>false</DCC_K>
+ <DCC_N>false</DCC_N>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_Win32)'!=''">
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
+ <Debugger_CWD>C:\Program Files\QIP Infium\</Debugger_CWD>
+ <Debugger_HostApplication>C:\Program Files\QIP Infium\infium.exe</Debugger_HostApplication>
+ <Debugger_DebugSourcePath>C:\Program Files\QIP Infium\;$(Debugger_DebugSourcePath)</Debugger_DebugSourcePath>
+ <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base_Win64)'!=''">
+ <DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1)'!=''">
+ <DCC_DebugInformation>false</DCC_DebugInformation>
+ <DCC_IOChecking>false</DCC_IOChecking>
+ <DCC_AssertionsAtRuntime>false</DCC_AssertionsAtRuntime>
+ <DCC_UnitSearchPath>..\..\include\delphi;..\..\plugins\ExternalAPI\delphi;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
+ <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+ <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+ <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
+ <Debugger_CWD>C:\Program Files\Miranda NG</Debugger_CWD>
+ <Debugger_HostApplication>C:\Program Files\Miranda NG\Miranda32.exe</Debugger_HostApplication>
+ <Debugger_DebugSourcePath>C:\Program Files\Miranda NG;$(Debugger_DebugSourcePath)</Debugger_DebugSourcePath>
+ <PostBuildEvent><![CDATA[copy_langs.bat
+$(PostBuildEvent)]]></PostBuildEvent>
+ <DCC_BplOutput>..\..\bin10\Release\Plugins\</DCC_BplOutput>
+ <DCC_DcpOutput>..\..\bin10\Release\Obj\hpp\</DCC_DcpOutput>
+ <DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols>
+ <DCC_Define>madExcept;$(DCC_Define)</DCC_Define>
+ <DCC_MapFile>3</DCC_MapFile>
+ <DCC_DebugInformation>true</DCC_DebugInformation>
+ <VerInfo_MajorVer>2</VerInfo_MajorVer>
+ <VerInfo_MinorVer>5</VerInfo_MinorVer>
+ <VerInfo_Keys>CompanyName=http://www.im-history.ru;FileDescription=MirandaNGHistoryToDB;FileVersion=2.5.0.0;InternalName=MirandaNGHistoryToDB;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=MirandaNGHistoryToDB.dll;ProductName=MirandaNGHistoryToDB;ProductVersion=2.5.0.0;Comments=http://www.im-history.ru</VerInfo_Keys>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <Manifest_File>None</Manifest_File>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <DCC_DcuOutput>..\..\bin10\Release\Obj\hpp\</DCC_DcuOutput>
+ <DCC_ExeOutput>..\..\bin10\Release\Plugins\</DCC_ExeOutput>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
+ <PostBuildEvent><![CDATA[copy_langs.bat
+$(PostBuildEvent)]]></PostBuildEvent>
+ <DCC_BplOutput>..\..\bin10\Release64\Plugins\</DCC_BplOutput>
+ <DCC_DcpOutput>..\..\bin10\Release64\Obj\hpp\</DCC_DcpOutput>
+ <DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols>
+ <DCC_Define>madExcept;$(DCC_Define)</DCC_Define>
+ <DCC_MapFile>3</DCC_MapFile>
+ <DCC_DebugInformation>true</DCC_DebugInformation>
+ <VerInfo_MajorVer>2</VerInfo_MajorVer>
+ <VerInfo_MinorVer>5</VerInfo_MinorVer>
+ <VerInfo_Keys>CompanyName=http://www.im-history.ru;FileDescription=MirandaNGHistoryToDB;FileVersion=2.5.0.0;InternalName=MirandaNGHistoryToDB;LegalCopyright=Michael Grigorev;LegalTrademarks=http://www.im-history.ru;OriginalFilename=MirandaNGHistoryToDB.dll;ProductName=MirandaNGHistoryToDB;ProductVersion=2.5.0.0;Comments=http://www.im-history.ru</VerInfo_Keys>
+ <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
+ <Manifest_File>None</Manifest_File>
+ <VerInfo_Locale>1033</VerInfo_Locale>
+ <DCC_DcuOutput>..\..\bin10\Release64\Obj\hpp\</DCC_DcuOutput>
+ <DCC_ExeOutput>..\..\bin10\Release64\Plugins\</DCC_ExeOutput>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2)'!=''">
+ <DCC_MapFile>3</DCC_MapFile>
+ <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+ <DCC_Optimize>false</DCC_Optimize>
+ <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+ </PropertyGroup>
+ <ItemGroup>
+ <DelphiCompile Include="$(MainSource)">
+ <MainSource>MainSource</MainSource>
+ </DelphiCompile>
+ <DCCReference Include="Contacts.pas"/>
+ <DCCReference Include="Database.pas"/>
+ <DCCReference Include="Menu.pas"/>
+ <DCCReference Include="About.pas"/>
+ <DCCReference Include="MsgExport.pas">
+ <Form>ExportForm</Form>
+ </DCCReference>
+ <DCCReference Include="Global.pas"/>
+ <DCCReference Include="FSMonitor.pas"/>
+ <DCCReference Include="MapStream.pas"/>
+ <BuildConfiguration Include="Debug">
+ <Key>Cfg_2</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Base">
+ <Key>Base</Key>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Release">
+ <Key>Cfg_1</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ </ItemGroup>
+ <Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+ <Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+ <ProjectExtensions>
+ <Borland.Personality>Delphi.Personality.12</Borland.Personality>
+ <Borland.ProjectType>VCLApplication</Borland.ProjectType>
+ <BorlandProject>
+ <Delphi.Personality>
+ <Source>
+ <Source Name="MainSource">MirandaNGHistoryToDB.dpr</Source>
+ </Source>
+ <VersionInfo>
+ <VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+ <VersionInfo Name="AutoIncBuild">False</VersionInfo>
+ <VersionInfo Name="MajorVer">1</VersionInfo>
+ <VersionInfo Name="MinorVer">0</VersionInfo>
+ <VersionInfo Name="Release">0</VersionInfo>
+ <VersionInfo Name="Build">0</VersionInfo>
+ <VersionInfo Name="Debug">False</VersionInfo>
+ <VersionInfo Name="PreRelease">False</VersionInfo>
+ <VersionInfo Name="Special">False</VersionInfo>
+ <VersionInfo Name="Private">False</VersionInfo>
+ <VersionInfo Name="DLL">False</VersionInfo>
+ <VersionInfo Name="Locale">1049</VersionInfo>
+ <VersionInfo Name="CodePage">1251</VersionInfo>
+ </VersionInfo>
+ <VersionInfoKeys>
+ <VersionInfoKeys Name="CompanyName"/>
+ <VersionInfoKeys Name="FileDescription"/>
+ <VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="InternalName"/>
+ <VersionInfoKeys Name="LegalCopyright"/>
+ <VersionInfoKeys Name="LegalTrademarks"/>
+ <VersionInfoKeys Name="OriginalFilename"/>
+ <VersionInfoKeys Name="ProductName"/>
+ <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="Comments"/>
+ </VersionInfoKeys>
+ <Parameters>
+ <Parameters Name="HostApplication">C:\Program Files\QIP Infium\infium.exe</Parameters>
+ <Parameters Name="DebugSourceDirs">C:\Program Files\QIP Infium\</Parameters>
+ <Parameters Name="DebugCWD">C:\Program Files\QIP Infium\</Parameters>
+ </Parameters>
+ <Excluded_Packages>
+ <Excluded_Packages Name="$(BDSBIN)\dcloffice2k170.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
+ <Excluded_Packages Name="$(BDSBIN)\dclofficexp170.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
+ </Excluded_Packages>
+ </Delphi.Personality>
+ <Platforms>
+ <Platform value="OSX32">False</Platform>
+ <Platform value="Win32">True</Platform>
+ <Platform value="Win64">True</Platform>
+ </Platforms>
+ </BorlandProject>
+ <ProjectFileVersion>12</ProjectFileVersion>
+ </ProjectExtensions>
+ <PropertyGroup Condition="'$(Config)'=='Release' And '$(Platform)'=='Win32'">
+ <PreBuildEvent/>
+ <PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
+ <PreLinkEvent/>
+ <PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
+ <PostBuildEvent>copy_langs.bat</PostBuildEvent>
+ <PostBuildEventIgnoreExitCode>False</PostBuildEventIgnoreExitCode>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Release' And '$(Platform)'=='Win64'">
+ <PreBuildEvent/>
+ <PreBuildEventIgnoreExitCode>False</PreBuildEventIgnoreExitCode>
+ <PreLinkEvent/>
+ <PreLinkEventIgnoreExitCode>False</PreLinkEventIgnoreExitCode>
+ <PostBuildEvent>copy_langs.bat</PostBuildEvent>
+ <PostBuildEventIgnoreExitCode>False</PostBuildEventIgnoreExitCode>
+ </PropertyGroup>
+</Project>
diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes
new file mode 100644
index 0000000000..1fcb334c1d
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.mes
@@ -0,0 +1,163 @@
+[GeneralSettings]
+MesVersion=4
+HandleExceptions=1
+LinkInCode=1
+AppendMapFileToBinary=1
+NoOwnMadExceptSettings=0
+CheckFileCrc=1
+CheckForFrozenMainThread=0
+FreezeTimeout=60000
+ReportLeaks=0
+WindowsLogo=0
+CrashOnBuffer=0
+CrashOnUnderrun=0
+AutomaticallySaveBugReport=1
+AutoSaveBugReportIfNotSent=1
+AutomaticallyMailBugReport=0
+AutoMailProgressBox=0
+CopyBugReportToClipboard=0
+SuspendAllRunningThreads=0
+ShowPleaseWaitBox=1
+PleaseWaitIcon=plwait1
+AutomaticallyContinueApplication=0
+AutomaticallyRestartApplication=0
+AutomaticallyCloseApplication=0
+SendInBackground=1
+SendHelper=196608
+Send32Icon=send321
+UploadViaHttp=0
+HttpServer=
+HttpSsl=0
+HttpPort=0
+HttpAccount=
+HttpPassword=
+UploadToFogBugz=0
+UploadToBugZilla=0
+UploadToMantis=0
+BugTrackerAccount=
+BugTrackerPassword=
+BugTrackerProject=
+BugTrackerArea=
+BugTrackerAssignTo=
+MailAsSmtpServer=0
+MailAsSmtpClient=0
+SmtpServer=
+SmtpSsl=0
+SmtpTls=0
+SmtpPort=0
+SmtpAccount=
+SmtpPassword=
+MailViaMapi=1
+MailViaMailto=1
+MailAddress=sleuthhound@gmail.com
+BugReportFile=bugreport.txt
+AttachBugReport=1
+AttachBugReportFile=1
+DeleteBugReportFile=1
+BugReportSendAs=bugreport.txt
+BugReportZip=
+ScreenShotDepth=8
+ScreenShotAppOnly=0
+ScreenShotSendAs=screenshot.png
+ScreenShotZip=
+AdditionalAttachments=
+AppendBugReports=1
+BugReportFileSize=100000
+DontSaveDuplicateExceptions=1
+DontSaveDuplicateFreezings=1
+DuplicateExceptionDefinition=1
+DuplicateFreezeDefinition=2
+ShowExceptionBox=1
+OkBtnText=&OK
+DetailsBtnText=&Details
+PleaseWaitTitle=Information
+PleaseWaitText=Please wait a moment...
+BugTrackerTitle=%25appname%25, %25exceptMsg%25
+BugTrackerDescr=error details: %0d%0a%25errorDetails%25
+MailSubject=bug report
+MailBody=please find the bug report attached
+SendBoxTitle=Sending bug report...
+PrepareAttachMsg=Preparing attachments...
+MxLookupMsg=Searching for mail server...
+ConnectMsg=Connecting to server...
+SendMailMsg=Sending mail...
+FieldsMsg=Setting fields...
+SendAttachMsg=Sending attachments...
+SendFinalizeMsg=Finalizing...
+MailFailureMsg=Sorry, sending the bug report didn't work.
+VersionVariable=
+[ExceptionBox]
+ShowButtonMailBugReport=1
+ShowButtonSaveBugReport=0
+ShowButtonPrintBugReport=0
+ShowButtonShowBugReport=1
+ShowButtonContinueApplication=1
+ShowButtonRestartApplication=1
+ShowButtonCloseApplication=1
+IconButtonSendBugReport=send1
+IconButtonSaveBugReport=save1
+IconButtonPrintBugReport=print1
+IconButtonShowBugReport=show1
+IconButtonContinueApplication=continue1
+IconButtonCantContinueApplication=cantContinue1
+IconButtonRestartApplication=restart1
+IconButtonCloseApplication=close1
+FocusedButton=0
+SendAssistant=SendAssistant
+SaveAssistant=SaveAssistant
+PrintAssistant=PrintAssistant
+AutomaticallyShowBugReport=0
+NoOwnerDrawButtons=0
+BigExceptionIcon=big1
+TitleBar=%25appname%25
+ExceptionMessage=An error occurred in the application.
+FrozenMessage=The application seems to be frozen.
+BitFaultMsg=The file "%25modname%25" seems to be corrupt!
+MailBugReportText=send bug report
+SaveBugReportText=save bug report
+PrintBugReportText=print bug report
+ShowBugReportText=show bug report
+ContinueApplicationText=continue application
+RestartApplicationText=restart application
+CloseApplicationText=close application
+[BugReport]
+ListThreads=1
+ListModules=1
+ListHardware=1
+ShowCpuRegisters=1
+ShowStackDump=1
+Disassembly=1
+HideUglyItems=0
+ShowRelativeAddrs=1
+ShowRelativeLines=1
+FormatDisassembly=0
+LimitDisassembly=5
+EnabledPlugins=modules|processes|hardware
+[Filters]
+Filter1ExceptionClasses=EDBEditError
+Filter1DontCreateBugReport=1
+Filter1DontCreateScreenshot=1
+Filter1DontSuspendThreads=1
+Filter1DontCallHandlers=1
+Filter1ShowBox=3
+Filter1Assis=
+Filter2ExceptionClasses=
+Filter2DontCreateBugReport=0
+Filter2DontCreateScreenshot=0
+Filter2DontSuspendThreads=0
+Filter2DontCallHandlers=0
+Filter2ShowBox=0
+Filter2Assis=
+GeneralDontCreateBugReport=0
+GeneralDontCreateScreenshot=0
+GeneralDontSuspendThreads=0
+GeneralDontCallHandlers=0
+GeneralShowBox=0
+GeneralAssis=
+[Assistants]
+Assistant1=SendAssistant|Send Assistant|ContactForm|DetailsForm|ScrShotForm
+Assistant2=SaveAssistant|Save Assistant|ContactForm|DetailsForm
+Assistant3=PrintAssistant|Print Assistant|ContactForm|DetailsForm
+Forms1=TPF0%0eTMEContactForm%0bContactForm%07Message%0c%13%00%00%00Contact Information%08MinWidth%04%00%00%00%00%08OnAction%0c%1b%00%00%00madExcept.HandleContactForm%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c%0a%00%00%00your name:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%08NameEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%09%0aOutputName%0c%0c%00%00%00contact name%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%08INVLabel%06Label2%07Caption%0c%0b%00%00%00your email:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%09EmailEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00contact email%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%0bINVCheckBox%08MemCheck%07Caption%0c%0b%00%00%00remember me%07Checked%08%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%00
+Forms2=TPF0%0eTMEDetailsForm%0bDetailsForm%07Message%0c%0d%00%00%00Error Details%08MinWidth%04%00%00%00%00%08OnAction%0c%00%00%00%00%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c'%00%00%00in which situation did the error occur?%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%0bDetailsMemo%07Colored%09%07Enabled%09%05Lines%04%09%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00error details%0aOutputType%07%0dnvoOwnSection%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%00
+Forms3=TPF0%0eTMEScrShotForm%0bScrShotForm%0dActiveControl%07%0bContinueBtn%07Message%0c%18%00%00%00Screenshot Configuration%08MinWidth%04%00%00%00%00%08OnAction%0c%1e%00%00%00madExcept.HandleScreenshotForm%05Timer%04%fa%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%0bINVCheckBox%0bAttachCheck%07Caption%0c%25%00%00%00attach a screenshot to the bug report%07Checked%09%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%08INVImage%0aScrShotImg%06Border%09%09Clickable%09%07Enabled%09%04File%0c%00%00%00%00%06Height%04%00%00%00%00%07Spacing%04%00%00%00%00%05Width%04%00%00%00%00%00%00%08INVLabel%06Label1%07Caption%0c%15%00%00%00(click to edit image)%07Enabled%09%07Spacing%04%00%00%00%00%00%00%00
diff --git a/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.res b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.res
new file mode 100644
index 0000000000..e7d67124de
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/MirandaNGHistoryToDB.res
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/MsgExport.dfm b/plugins/MirandaNGHistoryToDB/MsgExport.dfm
new file mode 100644
index 0000000000..1a244adc27
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/MsgExport.dfm
@@ -0,0 +1,4447 @@
+object ExportForm: TExportForm
+ Left = 0
+ Top = 0
+ ActiveControl = Page1
+ BorderIcons = [biSystemMenu, biMinimize]
+ BorderStyle = bsSingle
+ Caption = 'MirandaNGHistoryToDB - '#1069#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080
+ ClientHeight = 266
+ ClientWidth = 561
+ Color = clBtnFace
+ Font.Charset = DEFAULT_CHARSET
+ Font.Color = clWindowText
+ Font.Height = -11
+ Font.Name = 'Tahoma'
+ Font.Style = []
+ Icon.Data = {
+ 0000010001001010000001000000680400001600000028000000100000002000
+ 0000010020000000000000040000000000000000000000000000000000000000
+ 0000000000000000000000000000FF1F2A000000000000000000000000000000
+ 00000000000000000000FF1F2A00000000000000000000000000000000000000
+ 00000000000000000000FF1F2A00FEEFA900FF1F2A00CDCDCD00CDCDCD00CDCD
+ CD00CDCDCD00FF1F2A00FEEFA900FF1F2A000000000000000000000000000000
+ 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F
+ 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000
+ 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FECF4D00FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A0000000000FF1F
+ 2A00FEEFA900FFE55F00FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A000000
+ 0000FF1F2A00FEEFA900FFE55F00FFE55F00FFE55F00FFD35000FFCA4800FFCC
+ 4A00FFD35000FFE55F00FFE55F00FFE55F00FEEFA900FF1F2A00000000000000
+ 000000000000FF1F2A00FEEFA900FFE55F00FF1F2A00FF1F2A00FF1F2A00FF1F
+ 2A00FF1F2A00FF1F2A00FFE55F00FEEFA900FF1F2A0000000000000000000000
+ 000000000000C1BDB600FF1F2A00FEEFA900FF1F2A00C1B7AF00D2BEB900D2BE
+ B900D2BEB900FF1F2A00FEEFA900FF1F2A00C1BDB60000000000000000000000
+ 000000000000BAB7AF00A39A8F00FF1F2A00CAC1B800DFD5CC00FAE2DF00F7DB
+ D900DFD5CC00CAC1B800FF1F2A00A39A8F00BAB7AF0000000000000000000000
+ 000000000000B1AB9F00C9C2B900CFC7BF00D5CCC400DCD3CA00E8DDD500E4D6
+ CF00E4D6CF00D5CCC400CFC7BF00C9C2B900B1AB9F0000000000000000000000
+ 000000000000B0AB9E00C7C0B600CCC4BB00D3C9C100DAD0C700EBE1DA00E4D9
+ D100DDD2CA00DBCDC500DDCAC400DBC4BF00C1ADA40000000000000000000000
+ 000000000000AFAA9D00C8C1B700E8E3DB00F5F0E800FDF8F200FBF7F000FCF7
+ F100FDF8F200F7F0EA00ECE3DC00CDC3BB00B2AA9E0000000000000000000000
+ 000000000000AEA89C00FBF5EF00EEE7DE00E0D8CE00DDD5CC00DDD4CB00DDD4
+ CB00DDD5CC00E0D7CE00EDE6DE00FBF6EF00AEA89C0000000000000000000000
+ 000000000000AFA99D00E1D8CE00E1D7CE00DFD6CC00DFD5CB00DFD5CB00DFD5
+ CB00DFD5CB00DFD6CC00E1D7CE00E1D8CE00AFA99D0000000000000000000000
+ 000000000000D9D9D900B6B0A400D6CFC400E6DED500EFE7DD00EEE6DC00EEE6
+ DC00EFE7DD00E6DED500D6CFC400B6B0A400D9D9D90000000000000000000000
+ 00000000000000000000D9D9D900C4C0B700AEA99C00AEA89C00AEA89C00AEA8
+ 9C00AEA89C00AEA99C00C4C0B700D9D9D900000000000000000000000000F7EF
+ FFFFE007FFFFC003FFFF8001FFFF0000FFFF8001FFFFC003FFFFC003FFFFC003
+ FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFC003FFFFE007FFFF}
+ OldCreateOrder = False
+ Position = poDesktopCenter
+ OnClose = FormClose
+ OnCloseQuery = FormCloseQuery
+ OnCreate = FormCreate
+ OnShow = FormShow
+ PixelsPerInch = 96
+ TextHeight = 13
+ object IMExportWizard: TJvWizard
+ Left = 0
+ Top = 0
+ Width = 561
+ Height = 266
+ ActivePage = Page1
+ ButtonBarHeight = 42
+ ButtonStart.Caption = 'To &'#1055#1077#1088#1074#1072#1103' '#1089#1090#1088#1072#1085#1080#1094#1072
+ ButtonStart.NumGlyphs = 1
+ ButtonStart.Width = 85
+ ButtonLast.Caption = 'To &'#1055#1086#1089#1083#1077#1076#1085#1103#1103' '#1089#1090#1088#1072#1085#1080#1094#1072
+ ButtonLast.NumGlyphs = 1
+ ButtonLast.Width = 85
+ ButtonBack.Caption = '< &'#1053#1072#1079#1072#1076
+ ButtonBack.NumGlyphs = 1
+ ButtonBack.Width = 75
+ ButtonNext.Caption = '&'#1044#1072#1083#1077#1077' >'
+ ButtonNext.NumGlyphs = 1
+ ButtonNext.Width = 75
+ ButtonFinish.Caption = '&'#1042#1099#1081#1090#1080
+ ButtonFinish.NumGlyphs = 1
+ ButtonFinish.Width = 75
+ ButtonCancel.Caption = #1054#1090#1084#1077#1085#1072
+ ButtonCancel.NumGlyphs = 1
+ ButtonCancel.ModalResult = 2
+ ButtonCancel.Width = 75
+ ButtonHelp.Caption = '&'#1055#1086#1084#1086#1097#1100
+ ButtonHelp.NumGlyphs = 1
+ ButtonHelp.Width = 75
+ ShowRouteMap = False
+ OnFinishButtonClick = IMExportWizardFinishButtonClick
+ OnCancelButtonClick = IMExportWizardCancelButtonClick
+ DesignSize = (
+ 561
+ 266)
+ object Page1: TJvWizardWelcomePage
+ Header.Height = 100
+ Header.Title.Color = clNone
+ Header.Title.Text = #1044#1086#1073#1088#1086' '#1087#1086#1078#1072#1083#1086#1074#1072#1090#1100' '#1074' '#1084#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080
+ Header.Title.Anchors = [akLeft, akTop, akRight]
+ Header.Title.Font.Charset = DEFAULT_CHARSET
+ Header.Title.Font.Color = clWindowText
+ Header.Title.Font.Height = -16
+ Header.Title.Font.Name = 'Tahoma'
+ Header.Title.Font.Style = [fsBold]
+ Header.Subtitle.Color = clNone
+ Header.Subtitle.Text =
+ #1044#1072#1085#1085#1099#1081' '#1084#1072#1089#1090#1077#1088' '#1087#1086#1084#1086#1078#1077#1090' '#1042#1072#1084' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1090#1100' '#1080#1089#1090#1086#1088#1080#1102' Miranda '#1074#1086' '#1074#1085#1077#1096 +
+ #1085#1102#1102' '#1073#1072#1079#1091' '#1076#1072#1085#1085#1099#1093'. '#1069#1082#1089#1087#1086#1088#1090' '#1073#1091#1076#1077#1090' '#1087#1088#1086#1080#1079#1074#1077#1076#1077#1085' '#1074' '#1092#1072#1081#1083' '#1092#1086#1088#1084#1072#1090#1072' sql-ins' +
+ 'ert. '#1055#1088#1080' '#1089#1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1080' '#1101#1090#1080' '#1076#1072#1085#1085#1099#1077' '#1073#1091#1076#1091#1090' '#1087#1077#1088#1077#1076#1072#1085#1099' '#1074' '#1073#1072#1079#1091' '#1076#1072#1085#1085#1099#1093'.'
+ Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom]
+ Header.Subtitle.Font.Charset = DEFAULT_CHARSET
+ Header.Subtitle.Font.Color = clWindowText
+ Header.Subtitle.Font.Height = -11
+ Header.Subtitle.Font.Name = 'Tahoma'
+ Header.Subtitle.Font.Style = []
+ Header.ShowDivider = False
+ Image.Alignment = iaCenter
+ Image.Layout = ilCenter
+ EnabledButtons = [bkBack, bkNext, bkFinish, bkCancel]
+ WaterMark.Color = clCaptionText
+ WaterMark.Image.Picture.Data = {
+ 07544269746D617086080200424D86080200000000003600000028000000C800
+ 0000DE000000010018000000000050080200120B0000120B0000000000000000
+ 0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2
+ C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685
+ 61C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6F0D2C6F0
+ D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4E5B19BE5B19BE5B19B
+ F8E9E2FFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE5B19BF0D2C6FFFFFFFFFF
+ FFFFFFFFF0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6F0
+ D2C6F0D2C6F0D2C6F0D2C6E5B19BC75828E5B19BFFFFFFFBF4F1E5B19BE5B19B
+ E5B19BF8E9E2F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFBF4F1E9BCA9E5B19BE5B19BECC7B7FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6E5B19BE5B19BECC7B7F8E9E2F0D2
+ C6FBF4F1FFFFFFFBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0
+ D2C6FFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFF4DED4F0D2C6
+ FFFFFFFFFFFFFBF4F1F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C75828C75828DA9070
+ FFFFFFFFFFFFFBF4F1D68561C75828C75828C75828C75828C75828F4DED4FFFF
+ FFE1A68CC75828C75828C75828C75828C75828DA9070FFFFFFFFFFFFC75828D6
+ 8561FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C75828C75828
+ C75828C75828C75828E5B19BFBF4F1CB6336C75828C75828C75828CB6336C758
+ 28D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9CB
+ 6336C75828C75828C75828C75828DA9070FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFD68561C75828C75828C75828C75828C75828CB6336E5B19BFFFF
+ FFFFFFFFE5B19BC75828C75828C75828C75828CB6336C75828F0D2C6FFFFFFF0
+ D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFF
+ E5B19BC75828DA9070FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFF0D2
+ C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFD68561C75828F0D2C6F0D2C6ECC7B7D27953C75828E9BCA9FFFFFFE5B1
+ 9BC75828DA9070F8E9E2FFFFFFE9BCA9CE6E45F0D2C6F0D2C6C75828CB6336EC
+ C7B7FFFFFFF4DED4DD9B7ED68561FFFFFFFFFFFFC75828D68561FFFFFFFFFFFF
+ FFFFFFFFFFFFF4DED4CE6E45C75828E9BCA9F0D2C6F0D2C6E5B19BC75828DD9B
+ 7EF8E9E2E5B19BC75828DD9B7EFFFFFFF8E9E2DD9B7EC75828D68561FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1CB6336CB6336E9BCA9FFFFFF
+ F8E9E2DD9B7ED68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685
+ 61C75828E5B19BF0D2C6F0D2C6E5B19BCB6336C75828ECC7B7FFFFFFCB6336CB
+ 6336F4DED4FFFFFFE9BCA9CE6E45C75828F0D2C6FFFFFFF0D2C6C75828E5B19B
+ FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFE5B19BC75828C758
+ 28E5B19BFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFF0D2C6C75828C75828FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758
+ 28FFFFFFFFFFFFFFFFFFECC7B7C75828E5B19BFFFFFFCE6E45C75828FBF4F1FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828ECC7B7FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFE9BCA9C75828E1A68CFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFE5B19BC7
+ 5828ECC7B7FFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFE9BCA9C75828E1A68CFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FF
+ FFFFFFFFFFFFFFFFE9BCA9C75828D68561FFFFFFC75828D27953FFFFFFFFFFFF
+ FFFFFFE5B19BC75828F0D2C6FFFFFFF0D2C6C75828E5B19BF8E9E2C75828CE6E
+ 45FFFFFFD68561C75828FFFFFFFFFFFFE5B19BC75828C75828C75828F0D2C6FF
+ FFFFD68561C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BE5B19BE1
+ A68CCE6E45CB6336F4DED4FFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFD68561C75828F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6FFFF
+ FFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB6336CB
+ 6336FFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFF0D2C6C75828CB6336E1A68C
+ E5B19BF0D2C6C75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFF
+ F0D2C6C75828D68561FFFFFFD68561C75828D68561E5B19BECC7B7DD9B7EC758
+ 28F0D2C6FFFFFFF0D2C6C75828E5B19BDD9B7EC75828C75828E9BCA9D68561C7
+ 5828FFFFFFFFFFFFE5B19BC75828E5B19BCB6336CB6336FBF4F1D68561C75828
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFD68561C75828D68561D68561CE6E45C75828E5B19B
+ FFFFFFFFFFFFC75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685
+ 61C75828C75828C75828C75828C75828C75828C75828FFFFFFFFFFFFC75828D6
+ 8561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9070C75828F0D2C6FFFFFF
+ F0D2C6C75828E5B19BFFFFFFFFFFFFECC7B7D27953C75828C75828C75828C758
+ 28D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828EC
+ C7B7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFF8E9E2D27953C75828E5B1
+ 9BFFFFFFFBF4F1DD9B7ECB6336C75828C75828C75828C75828F0D2C6FFFFFFF0
+ D2C6C75828D68561C75828D68561CE6E45CE6E45D27953C75828FFFFFFFFFFFF
+ E5B19BC75828F0D2C6E9BCA9C75828D27953D68561C75828FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFD68561C75828FFFFFFFFFFFFFFFFFFD27953CB6336FFFFFFFFFFFFD279
+ 53C75828F4DED4FFFFFFFFFFFFFFFFFFF8E9E2FBF4F1E1A68CC75828F0D2C6FF
+ FFFFFFFFFFFFFFFFCE6E45C75828FFFFFFFFFFFFC75828D68561FFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFF0D2C6C75828E5B1
+ 9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6C75828D68561FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7C75828DA9070FFFFFFFFFFFF
+ FFFFFFFFFFFFF4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685
+ 61C75828C75828C75828C75828C75828C75828D68561FBF4F1FFFFFFFFFFFFFF
+ FFFFFFFFFFFBF4F1F0D2C6DD9B7EC75828F0D2C6FFFFFFF0D2C6C75828C75828
+ C75828F8E9E2E9BCA9C75828C75828C75828FFFFFFFFFFFFE5B19BC75828F0D2
+ C6FFFFFFDD9B7EC75828C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758
+ 28E5B19BE5B19BE1A68CC75828CB6336FFFFFFFFFFFFECC7B7C75828CE6E45E9
+ BCA9F0D2C6DD9B7EC75828F0D2C6F8E9E2CB6336CB6336E9BCA9F0D2C6DA9070
+ C75828DD9B7EFFFFFFFFFFFFC75828CE6E45E5B19BE5B19BE5B19BE5B19BF8E9
+ E2FFFFFFF0D2C6C75828D68561E5B19BDD9B7EC75828E5B19BFFFFFFFFFFFFE1
+ A68CE1A68CECC7B7F0D2C6DA9070C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFD27953C75828DD9B7EF0D2C6E9BCA9CE6E45D685
+ 61FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828DD9B7EE5
+ B19BE1A68CCB6336CE6E45F4DED4FFFFFFFFFFFFF4DED4DA9070E5B19BF0D2C6
+ E9BCA9CB6336C75828F8E9E2FFFFFFF0D2C6C75828C75828DD9B7EFFFFFFFFFF
+ FFCE6E45C75828C75828FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFBF4F1D2
+ 7953C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C7
+ 5828CE6E45E9BCA9FFFFFFFFFFFFFFFFFFE9BCA9CB6336C75828C75828C75828
+ CE6E45F8E9E2FFFFFFECC7B7CB6336C75828C75828C75828D27953FBF4F1FFFF
+ FFFFFFFFC75828C75828C75828C75828C75828C75828F0D2C6FFFFFFF0D2C6C7
+ 5828C75828C75828C75828C75828E5B19BFFFFFFFFFFFFD68561C75828C75828
+ C75828C75828D27953FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFBF4F1D68561C75828C75828C75828C75828E5B19BFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFE9BCA9
+ C75828DA9070FFFFFFFFFFFFF0D2C6C75828C75828C75828C75828C75828E9BC
+ A9FFFFFFFFFFFFF0D2C6C75828C75828F8E9E2FFFFFFFFFFFFE9BCA9C75828C7
+ 5828FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFF8E9E2CB6336C75828
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6F0D2C6F4DED4FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF0D2C6F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F0D2C6F4DED4FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF8E9E2F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFE9BCA9C75828D68561FFFF
+ FFFFFFFFFFFFFFFFFFFFF0D2C6F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD685
+ 61C75828D27953D68561D68561C75828C75828E5B19BFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CD68561D68561D6
+ 8561D68561DA9070E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFF8E9E2F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2
+ C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7CE6E45C75828C758
+ 28DA9070E9BCA9E5B19BF8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7C758
+ 28DA9070FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFE5B19BE5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE9BCA9
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFBF4F1CB6336C75828DA9070E1A68CE1A68CE5B19BC7
+ 5828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828F8E9E2FF
+ FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFDA9070C75828F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB6336CB6336FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFF4DED4E5B1
+ 9BE5B19BE5B19BECC7B7FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7E5
+ B19BDD9B7EC75828CE6E45FFFFFFFFFFFFFFFFFFF8E9E2C75828CE6E45FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1ECC7B7E5B19BE5B19BE5B19BECC7
+ B7FFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFF0
+ D2C6F0D2C6FBF4F1FFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFF
+ FFFFFFE5B19BC75828E5B19BE5B19BE5B19BE9BCA9FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFECC7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFE9BCA9C75828DD
+ 9B7EFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE5B19BF4DED4FFFFFF
+ FFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE9BCA9F8E9E2F0D2C6F8E9E2FFFF
+ FFFFFFFFF0D2C6F0D2C6E9BCA9E5B19BE5B19BF4DED4FFFFFFFFFFFFFFFFFFFB
+ F4F1F0D2C6F0D2C6E5B19BE5B19BE5B19BF8E9E2FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFECC7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFFFFFFFF8E9E2F0D2C6FBF4
+ F1FFFFFFFFFFFFFFFFFFDD9B7EC75828E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFBF4F1F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6
+ F4DED4FFFFFFFFFFFFFFFFFFF4DED4E5B19BE5B19BE5B19BE5B19BF8E9E2FFFF
+ FFFFFFFFFFFFFFFFFFFFF0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6F0
+ D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C75828C758
+ 28C75828C75828FFFFFFFFFFFFFBF4F1D68561C75828C75828C75828C75828C7
+ 5828C75828E5B19BFFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828C75828
+ C75828DD9B7EFFFFFFFFFFFFFFFFFFDA9070C75828F0D2C6FFFFFFFFFFFFFFFF
+ FFFFFFFFE9BCA9C75828C75828C75828C75828C75828C75828CE6E45F4DED4FF
+ FFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFDD9B7EC75828D27953FBF4F1
+ FFFFFFFFFFFFECC7B7C75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758
+ 28C75828C75828C75828C75828D27953F8E9E2FFFFFFFFFFFFF4DED4CE6E45C7
+ 5828C75828C75828C75828C75828F4DED4FFFFFFCB6336CB6336FBF4F1FFFFFF
+ FFFFFFFFFFFFE5B19BC75828C75828C75828C75828E1A68CFFFFFFFFFFFFF0D2
+ C6C75828C75828C75828C75828CB6336C75828E5B19BFFFFFFFFFFFFC75828C7
+ 5828C75828C75828C75828C75828E5B19BFFFFFFFFFFFFF0D2C6C75828C75828
+ C75828C75828C75828CB6336ECC7B7FFFFFFFFFFFFF4DED4CE6E45C75828C758
+ 28C75828C75828C75828F4DED4FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFF
+ FFFFF4DED4C75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828
+ D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFF
+ FFCE6E45C75828C75828C75828C75828C75828C75828E1A68CFFFFFFFFFFFFFF
+ FFFFC75828C75828FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828E5B19BFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6DD9B7EC75828DD9B7EF0D2C6FF
+ FFFFFFFFFFD68561C75828D27953ECC7B7FFFFFFFBF4F1E9BCA9CB6336D68561
+ FFFFFFF8E9E2CB6336C75828DD9B7EF8E9E2FFFFFFECC7B7CB6336C75828E5B1
+ 9BFFFFFFFFFFFFECC7B7C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC7
+ 5828DD9B7EF4DED4FFFFFFFBF4F1E5B19BC75828CB6336FFFFFFFFFFFFE5B19B
+ C75828F0D2C6FFFFFFDD9B7EC75828D27953FBF4F1FFFFFFFFFFFFFFFFFFDD9B
+ 7EC75828C75828E9BCA9FFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFBF4F1FB
+ F4F1E5B19BC75828D68561FFFFFFFFFFFFD68561C75828DD9B7EF8E9E2FBF4F1
+ E9BCA9CE6E45F0D2C6FFFFFFE1A68CC75828E9BCA9FFFFFFFFFFFFFFFFFFF8E9
+ E2F4DED4FFFFFFF0D2C6C75828C75828F8E9E2FFFFFFDA9070C75828E9BCA9FF
+ FFFFF0D2C6D68561C75828E5B19BFFFFFFFFFFFFC75828CE6E45F4DED4FFFFFF
+ F0D2C6D27953C75828F0D2C6FFFFFFF0D2C6C75828DA9070F8E9E2FFFFFFE9BC
+ A9CB6336CB6336FBF4F1FFFFFFD68561C75828DD9B7EF8E9E2FBF4F1E9BCA9CE
+ 6E45F0D2C6FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFD27953
+ C75828F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFC75828CE6E45E9
+ BCA9FBF4F1FFFFFFF0D2C6D27953C75828E5B19BFFFFFFFFFFFFC75828C75828
+ FFFFFFFFFFFFFFFFFFD68561C75828C75828E5B19BFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFECC7B7C75828
+ CB6336FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1E9BCA9FFFFFFE1A68CC758
+ 28DA9070FFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828FBF4F1FFFFFFFF
+ FFFFCB6336CB6336FBF4F1FFFFFFFFFFFFFFFFFFF0D2C6F4DED4FFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFFFFE5B19BC75828E5B19BDD9B
+ 7EC75828D27953FBF4F1FFFFFFFFFFFFFFFFFFF8E9E2C75828CB6336C75828D2
+ 7953FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD27953
+ C75828F8E9E2F8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF4DED4C75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFD68561C75828F0D2C6FFFFFFD68561C75828FBF4F1FFFFFFFFFFFFF0D2C6
+ C75828E5B19BFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFECC7B7C758
+ 28DD9B7EFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFE1A68CC75828E9
+ BCA9F8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ E5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFF
+ FFFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFF0D2C6F8E9E2FF
+ FFFFF0D2C6C75828D68561FFFFFFFFFFFFE5B19BFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFECC7B7C75828D68561FFFFFFFFFFFFC75828C75828FFFFFFFFFFFFF0D2
+ C6C75828C75828C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFE1A68CC75828E1A68CFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFD68561C75828ECC7B7FFFFFFFFFFFFE1A68CC75828
+ E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9
+ E2CB6336C75828F0D2C6FFFFFFE5B19BC75828C75828C75828D27953FBF4F1FF
+ FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BD68561C75828F4DED4FFFFFF
+ FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6F0D2
+ C6C75828DD9B7EF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFFFFFFFD2
+ 7953C75828F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828
+ F0D2C6FFFFFFE5B19BC75828CE6E45E5B19BE9BCA9E5B19BC75828E5B19BFFFF
+ FFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFF0
+ D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BF0D2C6C75828
+ DD9B7EF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFE5B19BC75828F0D2
+ C6FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1C75828CE6E45FFFFFFFFFFFFFFFFFFFF
+ FFFFF0D2C6C75828D68561FFFFFFF0D2C6C75828D68561FFFFFFF0D2C6C75828
+ D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CC758
+ 28D68561FFFFFFFFFFFFC75828C75828FFFFFFFFFFFFDA9070C75828D68561C7
+ 5828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758
+ 28E5B19BFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFC75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFF4DED4C75828D68561FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF8E9E2E9BCA9E5B19BD68561C75828C75828CE6E45FF
+ FFFFFFFFFFE5B19BC75828CB6336C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFCE6E45C75828F8E9E2E9BCA9C75828DD9B7EFFFFFFFFFFFFE5B19BC758
+ 28F0D2C6FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6F0D2C6C75828C75828C7
+ 5828C75828C75828C75828C75828E5B19BFFFFFFFFFFFFE5B19BC75828E5B19B
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFF
+ FFE5B19BCE6E45C75828C75828C75828C75828E5B19BFFFFFFFFFFFFC75828D6
+ 8561FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFF0D2C6C75828E5B19B
+ FFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BF0D2C6C75828C75828C75828C758
+ 28C75828C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFDA9070C75828F0D2C6FFFFFFFFFFFFFFFFFFF0D2C6C75828
+ D68561FFFFFFD68561C75828C75828F4DED4F0D2C6C75828D68561FFFFFFFFFF
+ FFFFFFFFFFFFFFF0D2C6E5B19BDD9B7ECE6E45C75828C75828E9BCA9FFFFFFFF
+ FFFFC75828C75828FFFFFFF8E9E2C75828D68561E5B19BC75828E5B19BFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFF
+ FFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFC75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758
+ 28E5B19BFFFFFFFFFFFFFFFFFFD27953C75828F8E9E2FFFFFFFFFFFFFFFFFFE1
+ A68CC75828C75828C75828C75828CB6336DD9B7EFBF4F1FFFFFFFFFFFFE5B19B
+ C75828ECC7B7D27953C75828DD9B7EFFFFFFFFFFFFFFFFFFECC7B7C75828DD9B
+ 7EFFFFFFFFFFFFCE6E45C75828FBF4F1FFFFFFE5B19BC75828F0D2C6FFFFFFFF
+ FFFFFFFFFFD27953C75828F8E9E2FBF4F1C75828D68561FFFFFFFFFFFFFFFFFF
+ E9BCA9C75828E5B19BFFFFFFFFFFFFFBF4F1C75828CE6E45FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF0D2C6E5B19BC75828E5B19BFFFFFFFFFFFFC75828D68561FFFFFFFFFFFF
+ FFFFFFECC7B7C75828DD9B7EFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFF
+ FFE1A68CC75828E9BCA9FBF4F1C75828D68561FFFFFFFFFFFFFFFFFFE9BCA9C7
+ 5828E5B19BFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ ECC7B7C75828DD9B7EFFFFFFFFFFFFFFFFFFF0D2C6C75828D68561F8E9E2C758
+ 28D27953C75828DD9B7EF0D2C6C75828D68561FFFFFFFFFFFFF4DED4CE6E45C7
+ 5828C75828C75828C75828D27953ECC7B7FFFFFFFFFFFFFFFFFFC75828C75828
+ FFFFFFDD9B7EC75828ECC7B7E5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFDA9070C75828
+ E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB6336C758
+ 28F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828E5B19BFFFFFFFF
+ FFFFFFFFFFE9BCA9C75828E1A68CFFFFFFFFFFFFF0D2C6C75828C75828E1A68C
+ F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FBF4
+ F1D27953C75828DD9B7EFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFE5
+ B19BC75828E5B19BFFFFFFE5B19BC75828CB6336E1A68CF0D2C6DA9070C75828
+ D68561FFFFFFFFFFFFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9
+ E2FFFFFFFFFFFFFFFFFFDD9B7EC75828ECC7B7FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFD68561C75828F0D2C6FFFFFFFFFFFFD68561E5B19BF0D2C6ECC7B7D27953
+ C75828E9BCA9FFFFFFFFFFFFC75828C75828D68561E9BCA9ECC7B7CE6E45C758
+ 28F0D2C6FFFFFFF0D2C6C75828C75828DD9B7EECC7B7E5B19BCB6336CB6336FB
+ F4F1FFFFFFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9E2FFFFFF
+ E5B19BC75828C75828D68561E5B19BD68561FFFFFFFFFFFFFFFFFFCE6E45C758
+ 28FBF4F1FFFFFFFFFFFFF0D2C6C75828D68561DD9B7EC75828F0D2C6DD9B7EC7
+ 5828E9BCA9C75828D68561FFFFFFFFFFFFD68561C75828D27953E9BCA9F0D2C6
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C75828F8E9E2C75828CE6E
+ 45FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9070C75828E9BCA9FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFCE6E45C75828F4DED4FFFFFFFFFFFFFFFFFFFBF4F1
+ C75828CE6E45FFFFFFFFFFFFE5B19BC75828E1A68CFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFBF4F1D27953C7
+ 5828E1A68CF8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFBF4F1C75828CE6E45
+ FFFFFFE5B19BC75828D68561C75828C75828C75828CE6E45F4DED4FFFFFFFFFF
+ FFFBF4F1DA9070C75828C75828C75828C75828E9BCA9FFFFFFFFFFFFFFFFFFFF
+ FFFFECC7B7C75828DD9B7EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828
+ F0D2C6FFFFFFFFFFFFC75828C75828C75828C75828C75828DD9B7EFFFFFFFFFF
+ FFFFFFFFC75828CE6E45CB6336C75828C75828C75828E1A68CFFFFFFFFFFFFF0
+ D2C6C75828D27953C75828C75828C75828CB6336E9BCA9FFFFFFFFFFFFFBF4F1
+ DA9070C75828C75828C75828C75828E9BCA9FFFFFFFFFFFFE5B19BC75828E1A6
+ 8CCE6E45C75828C75828FFFFFFFFFFFFFFFFFFE1A68CC75828E9BCA9FFFFFFFF
+ FFFFF0D2C6C75828D27953C75828CE6E45FFFFFFF0D2C6C75828D27953C75828
+ D68561FFFFFFFFFFFFC75828C75828FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFC75828C75828DD9B7EC75828E9BCA9FFFFFFE5B19BC7
+ 5828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758
+ 28E5B19BFFFFFFFFFFFFFBF4F1CB6336C75828E9BCA9FFFFFFFFFFFFFFFFFFFF
+ FFFFE5B19BD68561FFFFFFE9BCA9C75828CB6336F4DED4FFFFFFFFFFFFFFFFFF
+ DD9B7EC75828CE6E45FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828ECC7
+ B7FFFFFFE5B19BC75828DA9070FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6E1A68CFF
+ FFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF8E9E2F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+ E9E2F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45
+ C75828FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFF
+ FFFFFFFFF4DED4F0D2C6F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFC75828D6
+ 8561FFFFFFF0D2C6F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19B
+ FBF4F1F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2
+ C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFF8E9E2C75828D27953FFFFFFFFFFFFF0D2C6C75828
+ C75828C75828E9BCA9FFFFFFFFFFFFD68561C75828C75828D68561FFFFFFFFFF
+ FFCB6336C75828F4DED4FFFFFFFFFFFFFFFFFFFBF4F1E1A68CF4DED4FFFFFFFF
+ FFFFC75828C75828C75828CE6E45FFFFFFFFFFFFE5B19BC75828E5B19BFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561CE6E45C75828CE6E45D68561FF
+ FFFFFFFFFFE9BCA9C75828C75828D27953E5B19BDD9B7ECE6E45C75828D68561
+ FFFFFFFFFFFFDD9B7EC75828CB6336DD9B7EE5B19BD27953C75828CB6336F4DE
+ D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECC7B7C75828DA9070FFFFFFFBF4F1CB
+ 6336C75828D27953E5B19BE1A68CCE6E45C75828D68561FFFFFFFFFFFFE5B19B
+ C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CC75828E5B19BFFFF
+ FFFFFFFFD68561D68561CB6336C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFD27953C75828F4DED4FFFFFFF0D2C6C75828C75828CE6E45FFFF
+ FFFFFFFFFFFFFFE9BCA9C75828C75828D68561FFFFFFFFFFFFE5B19BC75828CB
+ 6336DD9B7EE5B19BDA9070C75828C75828F0D2C6FFFFFFFFFFFFC75828C75828
+ C75828E9BCA9FFFFFFFFFFFFE5B19BC75828E5B19BFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFD68561D68561D68561D68561D68561FFFFFFFFFFFFFFFFFF
+ F4DED4DD9B7ECB6336C75828C75828CE6E45E1A68CF8E9E2FFFFFFFFFFFFFFFF
+ FFE9BCA9D27953C75828C75828CB6336DD9B7EF8E9E2FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFCE6E45C75828FBF4F1FFFFFFFBF4F1DD9B7ECB6336
+ C75828C75828CE6E45DA9070ECC7B7FFFFFFFFFFFFE5B19BC75828F0D2C6FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2C75828D27953FFFFFFFFFFFFD68561D6
+ 8561D68561D68561F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BC
+ A9C75828E1A68CFFFFFFF4DED4D68561D68561E9BCA9FFFFFFFFFFFFFFFFFFFF
+ FFFFDA9070D68561E1A68CFFFFFFFFFFFFFFFFFFECC7B7D27953C75828C75828
+ C75828D68561E1A68CFBF4F1FFFFFFFFFFFFD68561D68561DA9070FFFFFFFFFF
+ FFFFFFFFE9BCA9D68561E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFF4DED4F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFF0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+ F4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F4DED4FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6F4DED4FFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFB
+ F4F1F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B19BE5B19B
+ F4DED4FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF4DED4E5B19BE5B19BE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFC75828D2
+ 7953E9BCA9E5B19BE5B19BF8E9E2FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F8E9E2
+ FFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FBF4F1F0D2C6F0D2C6FFFFFFFFFF
+ FFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF8E9E2F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFF
+ FFFFFFFFFFFFECC7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFFFFFFFE5B19BC758
+ 28E5B19BE5B19BE5B19BE9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC
+ C7B7E5B19BE5B19BE9BCA9F8E9E2FFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFFFF
+ FFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFFF4DED4F0D2C6FFFFFFFFFFFFFFFF
+ FFFFFFFFF0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFECC7B7E5B19BE5B19BE9
+ BCA9FBF4F1FFFFFFFBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFF0D2C6F0D2C6
+ FBF4F1FBF4F1F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFF8E9E2F0D2C6FBF4F1FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6F0D2C6F0
+ D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFD68561C75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828D68561
+ FFFFFFFFFFFFFFFFFFE1A68CC75828C75828C75828C75828C75828E5B19BFFFF
+ FFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFDD9B7EC75828C7
+ 5828C75828C75828CB6336F4DED4FFFFFFFFFFFFC75828C75828C75828C75828
+ C75828C75828E5B19BFFFFFFFFFFFFF0D2C6C75828CE6E45FBF4F1FFFFFFFFFF
+ FFE5B19BC75828F0D2C6FBF4F1D27953C75828E5B19BFFFFFFFFFFFFE5B19BC7
+ 5828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828
+ F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFF4DED4CE6E45C758
+ 28C75828C75828C75828C75828F4DED4FFFFFFE5B19BC75828C75828C75828C7
+ 5828C75828D27953F8E9E2FFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828
+ C75828C75828F4DED4FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD685
+ 61C75828FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFC75828D6
+ 8561FFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828C75828CB6336FFFFFF
+ F0D2C6C75828E5B19BFFFFFFFFFFFFDD9B7EC75828D27953FBF4F1F0D2C6C758
+ 28CE6E45FBF4F1FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C75828C75828DA9070
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561
+ C75828C75828F0D2C6FFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFF0D2
+ C6C75828D27953F0D2C6FFFFFFF0D2C6D68561E5B19BFFFFFFFFFFFFF0D2C6C7
+ 5828E5B19BFFFFFFFFFFFFFFFFFFF0D2C6C75828D27953F4DED4FBF4F1E5B19B
+ C75828D68561FFFFFFFFFFFFC75828CE6E45F4DED4FFFFFFF0D2C6D27953C758
+ 28F0D2C6FFFFFFF0D2C6C75828C75828D68561FFFFFFFFFFFFE5B19BC75828F0
+ D2C6FFFFFFF8E9E2CB6336C75828F0D2C6FFFFFFE5B19BC75828F0D2C6FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFF
+ FFFFFFFFD68561C75828FFFFFFFFFFFFD68561C75828DD9B7EF8E9E2FBF4F1E9
+ BCA9CE6E45F0D2C6FFFFFFE5B19BC75828E5B19BFBF4F1FBF4F1E5B19BC75828
+ D68561FFFFFFFFFFFFD68561C75828DD9B7EF8E9E2FBF4F1E9BCA9CE6E45F0D2
+ C6FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFF
+ FFFFD68561C75828C75828F0D2C6FFFFFFFFFFFFC75828D68561FFFFFFFFFFFF
+ D68561C75828E5B19BFBF4F1FBF4F1E5B19BCB6336FFFFFFF0D2C6C75828E5B1
+ 9BFFFFFFDD9B7EC75828D27953FBF4F1FFFFFFF0D2C6C75828C75828D68561FF
+ FFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFD68561C75828F0D2C6F0D2C6ECC7B7D27953C75828E9BCA9FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828CE6E
+ 45FFFFFFFFFFFFF0D2C6C75828D68561FFFFFFFFFFFFDD9B7EC75828ECC7B7FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFF
+ FFFFFFFFFFFFDD9B7EC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828F8E9
+ E2FFFFFFC75828D68561FFFFFFFFFFFFFFFFFFECC7B7C75828DD9B7EFFFFFFF0
+ D2C6C75828C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFF
+ F4DED4C75828CB6336FBF4F1E5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C7
+ 5828FFFFFFF8E9E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD27953C75828F8E9E2F8E9
+ E2C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC7
+ 5828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFFFFFFD68561C75828
+ C75828CB6336FBF4F1FFFFFFC75828D68561FFFFFFF8E9E2C75828D27953FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BE9BCA9C75828D2
+ 7953FBF4F1FFFFFFFFFFFFF0D2C6C75828C75828C75828E5B19BFFFFFFE5B19B
+ C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758
+ 28FFFFFFFFFFFFFFFFFFECC7B7C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828D68561C75828E5B19BFFFFFFF0
+ D2C6C75828D68561FFFFFFFFFFFFD68561C75828FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFD685
+ 61C75828FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFC75828D6
+ 8561FFFFFFFFFFFFFFFFFFFFFFFFC75828D68561FFFFFFF0D2C6C75828E1A68C
+ D27953C75828F0D2C6E5B19BC75828F0D2C6FFFFFFFFFFFFE5B19BCB6336C758
+ 28C75828C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFF0D2C6
+ C75828DD9B7EF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFE5B19BC758
+ 28F0D2C6FFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6F0D2C6C75828DD9B7EF0
+ D2C6F0D2C6F0D2C6F0D2C6F0D2C6F8E9E2FFFFFFE5B19BC75828F0D2C6FFFFFF
+ FFFFFFFFFFFFD68561C75828FFFFFFFFFFFFD68561C75828E9BCA9C75828D685
+ 61FFFFFFC75828D68561FFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFF0D2C6C75828CE6E45C75828CB6336F4DED4FFFFFFFFFFFF
+ FFFFFFF0D2C6C75828E1A68CD27953C75828F0D2C6E5B19BC75828F0D2C6FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BE5B19BE1
+ A68CCE6E45CB6336F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFD68561C75828ECC7B7CB6336CB6336FBF4F1F0D2C6C75828D68561
+ FFFFFFFFFFFFD68561C75828FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFF
+ FFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFC75828D68561FFFFFFFFFFFF
+ FFFFFFFFFFFFC75828D68561FFFFFFF0D2C6C75828E5B19BF4DED4CB6336CB63
+ 36DD9B7EC75828F0D2C6FFFFFFF0D2C6C75828D27953ECC7B7F0D2C6DD9B7EC7
+ 5828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828
+ F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFF0D2C6C75828C75828C758
+ 28C75828C75828C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFF
+ FFFFFFFFFFE5B19BC75828F0D2C6F0D2C6C75828C75828C75828C75828C75828
+ C75828C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD685
+ 61C75828FFFFFFFFFFFFD68561C75828FFFFFFDD9B7EC75828E1A68CC75828D6
+ 8561FFFFFFF0D2C6C75828E1A68CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ F0D2C6C75828D27953CB6336CB6336F4DED4FFFFFFFFFFFFFFFFFFF0D2C6C758
+ 28E5B19BF4DED4CB6336CB6336DD9B7EC75828F0D2C6FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFD68561C75828D68561D68561CE6E45C75828E5B19B
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561
+ C75828F0D2C6E9BCA9C75828DD9B7EF0D2C6C75828D68561FFFFFFFFFFFFE1A6
+ 8CC75828E5B19BFFFFFFFFFFFFFFFFFFFBF4F1F8E9E2FFFFFFFFFFFFF0D2C6C7
+ 5828E5B19BFFFFFFFFFFFFFFFFFFE1A68CC75828E9BCA9FFFFFFFFFFFFFFFFFF
+ CE6E45C75828FBF4F1FFFFFFC75828D68561FFFFFFFFFFFFFFFFFFECC7B7C758
+ 28DD9B7EFFFFFFF0D2C6C75828E5B19BFFFFFFE9BCA9C75828C75828C75828F0
+ D2C6FFFFFFE5B19BC75828ECC7B7FFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828F0D2C6FFFFFFFFFF
+ FFFFFFFFD68561C75828FFFFFFFBF4F1C75828D68561FFFFFFFFFFFFFFFFFFE9
+ BCA9C75828E5B19BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD27953
+ C75828F8E9E2FBF4F1C75828D68561FFFFFFFFFFFFFFFFFFE9BCA9C75828E5B1
+ 9BFFFFFFE5B19BC75828F0D2C6FFFFFFFFFFFFFFFFFFD68561C75828FFFFFFFF
+ FFFFD68561C75828FFFFFFFBF4F1D27953C75828C75828D68561FFFFFFFBF4F1
+ C75828CE6E45FBF4F1FFFFFFFFFFFFFFFFFFF4DED4FFFFFFF0D2C6C75828E5B1
+ 9BF0D2C6C75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828E5B19BFFFFFFE9
+ BCA9C75828C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFD68561C75828FFFFFFFFFFFFFFFFFFD27953CB6336FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFF
+ FFD68561C75828E5B19BC75828D68561FFFFFFFFFFFFF8E9E2CB6336CB6336E5
+ B19BF0D2C6E5B19BCB6336E5B19BE5B19BE5B19BDD9B7EC75828D68561E5B19B
+ E5B19BF0D2C6F8E9E2C75828CB6336E9BCA9F0D2C6DA9070C75828DD9B7EFFFF
+ FFFFFFFFC75828C75828D68561E9BCA9E9BCA9CB6336C75828F0D2C6FFFFFFF0
+ D2C6C75828E5B19BFFFFFFFFFFFFDD9B7EC75828C75828F0D2C6FFFFFFE9BCA9
+ C75828CE6E45E5B19BE5B19BD68561C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFE5B19BC75828DD9B7EE5B19BE5B19BE5B19BCE6E45C7
+ 5828FFFFFFFFFFFFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9E2
+ FFFFFFE5B19BC75828CB6336E1A68CF0D2C6DA9070C75828D68561FFFFFFFFFF
+ FFE1A68CC75828DA9070F0D2C6E9BCA9CB6336C75828F8E9E2FFFFFFE5B19BC7
+ 5828DD9B7EE5B19BE5B19BE5B19BCE6E45C75828FFFFFFFFFFFFD68561C75828
+ FFFFFFFFFFFFF4DED4CB6336C75828D68561FFFFFFFFFFFFE1A68CC75828D685
+ 61ECC7B7ECC7B7D68561C75828FFFFFFF0D2C6C75828E5B19BFFFFFFD27953C7
+ 5828DD9B7EE9BCA9FFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFDD9B7EC75828
+ C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C758
+ 28E5B19BE5B19BE1A68CC75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828F0D2C6FFFFFFF0D2C6C75828CB
+ 6336C75828D68561FFFFFFFFFFFFFFFFFFF4DED4CE6E45C75828C75828C75828
+ CB6336ECC7B7C75828C75828C75828C75828C75828C75828C75828E5B19BFFFF
+ FFE9BCA9CB6336C75828C75828C75828D68561FBF4F1FFFFFFFFFFFFC75828CE
+ 6E45CE6E45C75828C75828C75828E1A68CFFFFFFFFFFFFF0D2C6C75828E5B19B
+ FFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFFFFFFFFFFE5B19BCB6336C758
+ 28C75828C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFE5B19BC75828C75828C75828C75828C75828C75828C75828FFFFFFFFFFFF
+ FBF4F1DA9070C75828C75828C75828C75828E9BCA9FFFFFFFFFFFFE5B19BC758
+ 28D68561C75828C75828C75828CE6E45F4DED4FFFFFFFFFFFFFBF4F1DA9070C7
+ 5828C75828C75828C75828E9BCA9FFFFFFFFFFFFE5B19BC75828C75828C75828
+ C75828C75828C75828C75828FFFFFFFFFFFFD68561C75828FFFFFFFFFFFFFFFF
+ FFECC7B7C75828D68561FFFFFFFFFFFFFFFFFFE1A68CC75828C75828C75828C7
+ 5828D68561FFFFFFF0D2C6C75828E5B19BFFFFFFF4DED4D27953C75828D68561
+ FFFFFFF0D2C6C75828E5B19BFFFFFFFFFFFFFFFFFFD27953C75828F0D2C6FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828C75828C75828C7
+ 5828CE6E45E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFD68561C75828F0D2C6FFFFFFFFFFFFDD9B7EC75828C75828D68561
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F0D2C6FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+ D2C6F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6
+ F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9
+ E2F0D2C6F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0
+ D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F0D2C6
+ FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F0D2C6F8E9E2FFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561
+ C75828F0D2C6FFFFFFFFFFFFF8E9E2CB6336C75828D68561FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1A68CD68561F4DED4FFFF
+ FFFFFFFFFFFFFFE5B19BD68561E1A68CFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD
+ FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFD
+ FDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDFEFEFEFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC
+ FCFCF7F7F7F1F1F1ECECECE5E5E5DEDEDED7D7D7D0D0D0CBCCCCC9C9C9C5C5C5
+ C7C8C8CACBCBCCCCCCD1D1D1D8D8D8DFDFDFE6E6E6EEEEEEF4F4F4F8F8F8FBFB
+ FBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFCFCFCF9F9F9F9F9F9F7F7F7F6
+ F6F6F6F6F6F7F7F7F6F6F6FAFAFAFBFBFBF9F9F9F8F8F7F7F7F6F8F8F7F8F8F7
+ F8F8F7F8F8F7F8F8F7F8F8F7F8F8F7F8F8F7F8F8F7F9F8F8F9F8F8F9F8F8F9F8
+ F8F9F8F8F9F8F8FBFBFBFFFFFFFBFBFBF8F8F8FAFAFAFBFBFBFCFCFCFCFCFCFD
+ FDFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9
+ F9F4F5F5F0F1F1F0F1F0F1F2F2F5F6F5FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F7F2F2F5F3F3F6F3F3F6F3
+ F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6
+ F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F3F3F6F2F2F5F9F9FAFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFEFEFEFBFBFBF7F7F7EFEFEFE7E7E7DEDEDED5D5D5CCCCCC
+ C3C3C3BABABAB2B2B2AFAFAFADAFAFAD9F97BC8265CC7A56C3805FB09A8CABAA
+ A9AAABABAFAFAFB4B4B4BCBCBCC5C5C5CFCFCFD7D7D7E0E0E0E8E8E8F0F0F0F7
+ F7F7FCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFCFCFCF9F9F9F6F6F6F4F4F4F1F1F1F0F0F0EBEBEBE8E8E8E5E5E5E4E4E4
+ E5E6E6E6E6E6DDD5D0DBBEAFD8B39FD8B39FD8B3A0D8B3A0D9B3A1D9B3A1D9B4
+ A1D9B4A1D9B4A1D9B4A1DAB5A2D9B4A2D9B5A1D9B5A1D9B5A2D9B3A0D9B3A0DE
+ C1B2E3DAD5EDEDEDEEEEEEEEEEEEF1F1F1F3F3F3F4F4F4F5F5F5F6F6F6F8F8F8
+ FBFBFBFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFCFCFCFAFAFAF5F5F5EEEEEEE5E5E5CBCCCCA8ADAB85938C6D85795F7E6F5C
+ 7C6D607E706F867B899690B0B4B2D9D9D9ECECECEFEFEFF6F6F6FAFAFAFEFEFE
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFBFBDC96765825A587C6161856160836060835D5E835E5D82
+ 5B5B815A5B805A5A7F59577F56577D56567D56567D55557C54557D54547E5454
+ 7D52527C54547D54547D53517C4D4B73807D93E1E0E5FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F7F7
+ EFEFEFE7E7E7DEDEDED4D4D4CCCCCCC1C1C1BABABAB1B1B1ADADADABABABABAB
+ ABAEAFAFAFA29ACF8661EA7B48EE814BEC7D49D87F54B29A8DAFAFAFABACACAB
+ ABABABABABAEAEAEB4B4B4BCBCBCC4C4C4CFCFCFD7D7D7E1E1E1EAEAEAF2F2F2
+ F9F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFD
+ FDFDFDFDFDFDFDFDFDFCFCFCFCFCFCFBFBFBE9E9E9CFCFCFDADBDCBFA396E688
+ 59E88552EA844FEA844EEA844FEB844FEB854FED8550EC8550EC864FEC864FEC
+ 8550EB854FEC8650ED8650EC8651ED8750ED8650ED8650ED8953E79063D0B6A8
+ E3E3E3E2E2E2E4E4E4E7E7E7E9E9E9E9E9E9ECECECEEEEEEF3F3F3F8F8F8FDFD
+ FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7E9E9E9CD
+ CDCDB8B8B8848C8842715B307B5930865F33916734956A35966B349469318D63
+ 2F845D327A59527665919694BCBCBCDDDDDDEFEFEFFBFBFBFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEADABB9
+ 4C497375719E7E7BB1726FAD6C6BA86867A66362A55E5FA05A599D56559C5051
+ 9D4B4B994747964444964140923D3E8F3B3B8F39388F36368D33328A28288620
+ 1F82211F8426258525226D545174D7D7DCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAF2F2F2EAEAEAE0E0E0D8D8D8CDCD
+ CDC5C5C5BCBCBCB2B2B2ADADADACACACACACACACACADADAFB0B1A8A3CD8966EE
+ 844DEA9C5DEEB86EECA863EB8750D8865BAFA29AB0B2B3ADADAEACACACACACAC
+ ACACACAEAEAEB4B4B4BFBFBFC8C8C8D1D1D1DADADAE4E4E4EDEDEDF4F4F4FCFC
+ FCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFE6E6E6C5C6C7BFB0A7E58D5EED854EE5824DE5824DE6
+ 824DE6844EE7844EE7844EE7854FE7854FE7854FE7854FE7854EE7854EE7854E
+ E7854EE7844FE7854EE7854EE5834EE6844EEE8850E48F5FCAB8ADD3D3D4D6D6
+ D6D8D8D8DBDBDBDFDFDFE4E4E4E8E8E8EEEEEEF4F4F4FAFAFAFDFDFDFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7A4B1AB929995747B77377A5B
+ 32936731916734976B389E733BA3763DA6793CA5783AA175369C7035986C3597
+ 6B3C70588083818F9C95D2D6D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFECCCAD257557A8C89B95F5CAA1C1B
+ 8117167E1D1B831E1A821C19811B1A7E17177D1212790F10760E0F7713137B14
+ 157C0D0E760A0C750B0B750A0B750B0B760908760A097B1C1B851F1E85212087
+ 292792222274676581EAE9ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFEFEFEF9F9F9F1F1F1E7E7E7DEDEDED5D5D5CDCDCDC3C3C3BABABAB1B1B1AC
+ ACACACACACADADADACACACAEAFB0B1ADAAC29175EC854FF3B46BFBEC8FFEFC9D
+ FDF595F5C374F29053CE8E6AB1A9A3AFB0B1ADADADADADADACACACACACACACAC
+ ACB4B4B4BDBDBDC6C6C6CECECED8D8D8E1E1E1EAEAEAF3F3F3FCFCFCFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFE2E2E2C3C5C6B89784F98E52E6864FE88850E78750E88850E98850E98A51
+ E98A51E98951E98951E98A51E98A51EA8B52EA8B52EA8B52E98B52EA8A51E98B
+ 51E98B51E98851E98A51EA8951F58E52C79374C8C9C9CECFD0D1D1D1D6D6D6DB
+ DBDBE2E2E2E7E7E7ECECECF4F4F4F9F9F9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFCFCFC699E8355826C507162308D63339469318F643394
+ 69379B703AA0753EA5793EA6783BA175389B7035986E379C7031815C57746644
+ 8E6ABCCBC3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF4F4F77F7E9979759F6F6BB21010770F0F740E0D7708047408
+ 03730A037208007200006E07077318177A1B187B100A75000070090A74141479
+ 1312791313791111781C1C7C6B69A9B4B3D2A4A4CA4948940B0B7B28278E2321
+ 5FB9B8C4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF3F3F3EB
+ EBEBE0E0E0D7D7D7CFCFCFC6C6C6BCBCBCB4B4B4ADADADACACACADADADADADAD
+ AEAFAFB0AEADBD9882E98853F4B068FCF191FFFF9BFFFA97FFFF99FEFA95F7BF
+ 71F38E54C79679AFACA9ADADAEADADADADADADACACACACACACAEAEAEB6B6B6C0
+ C0C0C8C8C8D1D1D1DADADAE3E3E3EDEDEDF6F6F6FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFEFEFEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFFE4E4E4C5C7C8
+ B3907CFD9455E98B52EB8D52EB8D53EB8E54ED8E54EC8F54EC8E54EC8F54EE90
+ 55ED9055ED9055ED8F55EE9055EE9055ED8F54EE9055ED9054EC8F54ED8F55EC
+ 8F54EB8E53F99557CA8D67CACBCBD0D1D1D4D3D3D9D9D9DFDFDFE5E5E5EAEAEA
+ F0F0F0F7F7F7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFEFEFE6DA28933805A30694E2C875E309066308E6434946A379C6F3BA1743F
+ A5783EA4773AA174389B7036966B35976C2B805A2C6E4F389568C5D4CCFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+ F4F78181A28986AE413F963A3A8DAEABCE8684B81312790D0E760F0E7600006F
+ 242383918FBFC2C0DA8785B81D1A7C16147A8381B7AEACD0B2B0D2AAA8CC9E9C
+ C5A9A7CCE0DDEDFAF6FDE1DDEF7775B00A0B76211F8B26256AB4B5C4FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBF1F1F1EAEAEADFDFDFD6D6D6
+ CDCDCDC5C5C5BBBBBBB3B3B3AEAEAEADADADADADADACACADB0B1B1B59E90E68E
+ 5DF3A361FBE68AFFFF9AFFF693FFF592FFF592FFFC96FDED8DF8B068E78F59B4
+ 9783A6A6A6ACADAEADADADACACACACACACADADADB5B5B5BFBFBFC7C7C7D0D0D0
+ DADADAE2E2E2ECECECF5F5F5FEFEFEFFFFFFFFFFFFFFFFFFFEFEFEF9F9F9FAFA
+ FAFCFCFCFCFCFCF9F9F9F6F6F6F4F4F4F1F1F1F0F0F0EFEFEFEEEEEEEEEEEEEE
+ EEEEEFEFEFEEEEEEEEEEEEEEEEEEEEEEEEF0F0F0F0F0F0F2F2F2F5F5F5F8F8F8
+ FBFBFBFDFDFDFBFBFBF9F9F9FCFCFCFFFFFFE6E6E6CACCCDB79580FF9A59EC90
+ 54EE9055EE9255EF9357EF9257EF9357F09457EF9357F09458F19558F19558F0
+ 9657F19558F19558F09457F09557F09457EF9457EF9357EF9357EF9256FD9B59
+ C8906BD1D3D4D6D7D7D7D7D7DDDDDDE3E3E3EAEAEAEFEFEFF5F5F5FCFCFCFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F2F164A38629
+ 81582A63472D835C3191662F8D64339369389A6F3AA0733CA3763DA578399D72
+ 36996E34946B34966C287B56216F4B35996AB0C5BAFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F88A88A78C89B1
+ 3E3C9555539EF3F1F9B7B5D60D0C7602026F00006D262483A5A2CBFDF9FEC7C5
+ E0454597000069414293DCD9EBEAE6F3C0BFDAD1CFE3F5F1FAF6F3FAD7D4E8B9
+ B6D5E3E0EFC1C0DB2425851614852E2C6EB8B8C6FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFCFCFCF3F3F3ECECECE1E1E1D8D8D8D0D0D0C7C7C7BEBE
+ BEB6B6B6ADADADACACACACADADAFB0B1B2A59BE19666F9A05EFAD580FFFD98FF
+ F593FFF595FFF99AFFF494FFF08FFFFA95FDE086FAA863E0915DA9988AAEB0B0
+ ADAEAEADADADACACACAFAFAFB8B8B8BFBFBFCACACAD3D3D3DDDDDDE6E6E6F0F0
+ F0F6F6F6FCFCFCFBFBFBF5F5F5EFEFEFE8E8E8E6E6E6E4E4E4E0E0E0DBDBDBD1
+ D1D1CACACAC3C3C3BBBBBBB7B7B7B4B4B4B4B4B4B3B3B3B3B3B3B3B3B3B3B3B3
+ B4B4B4B3B3B3B3B3B3B6B6B6BABABABEBEBEC7C7C7CECECED7D7D7DEDEDEE2E2
+ E2E5E5E5E7E7E7F1F1F1E3E3E3D1CFCECC9F7FFE9C5BEF9557F09558F09758F2
+ 9859F2985AF29859F29859F3995AF39A5BF39A5BF39A5BF49959F49A5AF49A5B
+ F39A5BF29A5AF39A5AF39A5AF2985AF3995AF1985AFD9E5CD3986ED7D6D5E0E1
+ E1E2E2E2E8E8E8EDEDEDF4F4F4F9F9F9FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2DDD753A07B2D9165206745257752
+ 34946832916732926836966C35966B389A7036996E399D72389B7034966C3191
+ 6822734F26785334A16E8DB3A0FCFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F88B89A8918EB545449C54529DE6E4
+ F0ACACD0090A7600006C2D2C87AEACD0F1EEF8B2B0D32B2A8400006A00006C4A
+ 4C99DCDAECBBB7D63534887C7BB2D5D3E7C8C6DF5C5BA13B3B8ED4D3E6C9C7DE
+ 2B2A881A1688302E70B8B8C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF9F9F9F1F1F1E7E7E7DEDEDED5D5D5CDCDCDC4C4C4BCBCBCB2B2B2AD
+ ADADAEAEAFB1ABA5D89A70FFA35FFACC79FEF794FFF492FFF190FFF89AFFFEA1
+ FFF89AFFF191FFF291FFF694FED37EFFA963DE9E6EB1A9A1AFB1B2ACACACADAD
+ ADB4B4B4BEBEBEC5C5C5D0D0D0D9D9D9DFDFDFE3E3E3E6E6E6E9E9E9E8E8E8DE
+ DEDED3D3D3CBCBCBC2C2C2BABABAB3B3B3ACACACA4A4A49E9E9E9C9C9C969696
+ 9191918E8E8E8C8C8C8B8B8B8B8B8B8D8D8D8E8E8E8D8D8D8C8C8C8B8B8B8B8B
+ 8B8D8D8D8F8F8F9393939B9B9B9D9D9DA2A2A2A8A8A8B1B1B1B9B9B9C2C2C2CC
+ CDCCD4D4D5D6CFCBE4A980FC9E5DF49C5BF39B5BF49C5CF59D5CF59E5DF59E5C
+ F59E5DF69F5DF6A05EF6A05EF6A05EF69F5DF7A05EF79F5EF7A05EF69F5DF69F
+ 5DF69E5DF69F5DF69E5DF59D5CF89E5DF6AB73E5DBD3F4F4F4F3F3F3F8F8F8FA
+ FAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFCBD9D24EA07A319B6C27785423714C2F8C63389B703698
+ 6D3B9E73399C713EA17636976D3EA4773A9E723293692D865F2676512B845D35
+ A67283A996FAFBFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF5F5F88B8AA99493B84A48A056539FDDDCEBC6C7DF7775B172
+ 71AEAFADD1EBE8F4D9D7EA9C9AC7615FA4302C8900006B464796DBD8EAB5B2D5
+ 201F802D2D8842429432328C00006D2B2B87D4D2E7C4C3DC2928861D1A8A312F
+ 72B8B7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB
+ FBFBF2F2F2E9E9E9E1E1E1D8D8D8CECECEC6C6C6BEBEBEB5B5B6B2AFAEC79F7F
+ F89E5EFDC274FFF191FFF492FFEE8FFFF697FFFC9DFFFC9DFFFB9DFFF798FFEE
+ 8FFFF190FEED8EFEC878FFAA65CEA17EB1AEABAFB0B1B7B7B7C2C2C2CACACAD0
+ D0D0D1D1D1D1D1D1D1D1D1D2D2D2D6D6D6D4D4D4CBCBCBBDBDBDB2B2B2A8A8A8
+ A1A1A19B9B9B9797979595959393938B8B8B8686868080807777777171716B6B
+ 6B6464646666666C6C6C7171716E6E6E6767676363636767676F6F6F7474747C
+ 7C7C8383838A8A8A909090949494959595969696979797959595A2A4A5CBC5C0
+ E0A87EFEA661F6A05EF7A15EF8A15EF8A15EF8A35FF8A460FAA460F9A560F9A4
+ 60F9A561F9A561F9A560F9A661F9A461FAA561F9A660FAA460FAA360F9A460F9
+ A460F8A35FF8A25FFFB77AEFE6DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFD2DDD754A580339D6E348F663289602579543393693BA0743FA57942AA7D44
+ AE8042AB7D41A97B3BA2742E8B622C835B349066318E6635A6758CB9A3FBFDFC
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+ F5F88D8CAD9895BA4D4BA05755A1D8D5E7E6E5EFEDECF3F1F1F6EDEDF5E4E2EF
+ E1E0EDE4E2EFE8E6F27372B000006A464495DDD9EABBB8D91D1D7F00006A0000
+ 6F00007100006E3B3A8ED5D3E7C4C3DC2728871F1D8A333172B8B8C7FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDF9F9F9
+ F2F2F2EAEAEADFDFDFD5D5D5CFD0D0CCCDCDC4AA95F6A163FDB96DFFE88CFFF4
+ 93FFEC8EFFF293FFFB9BFFFB9CFFFA9AFFFB9BFFFB9AFFF293FFEA8DFEED8FFE
+ E68BFFC171F8A665C5AA92C5C4C3C5C6C6CACACACFCFCFD0D0D0CECECED0D0D0
+ D6D6D6D6D6D6C8C8C8B8B8B8AAAAAAA5A5A5A5A5A5A4A4A4A0A0A09A9A9A9595
+ 959292928D8D8D8585857F7F7F7979797373736B6B6B6464645D5D5D5F5F5F65
+ 65656A6A6A6969696161615D5D5D6161616868687070707777777C7C7C848484
+ 8A8A8A8D8D8D8383838383838080807C7D7D7E8081A5A09BCF9D73FFAD65FAA4
+ 60FBA561FCA762FCA762FCA762FCA763FDA864FCA863FCA863FCA863FCA964FD
+ A964FCA964FCA864FCA963FCA964FCA863FDA863FCA863FCA762FCA763FCA763
+ FFB97DFAF2EAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7EBE961A98837
+ A7743491683D9C702D845B2A835B36986D399E723DA37741A87B40A97B3EA578
+ 379C702D885E36916639986C3392693AAC79A4C4B4FEFEFEFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F88E8DAE9B98BB
+ 5553A55F5CA6E6E1ECCAC6E06F6DB16A68AD6968AE6462AB6462AAABABD1F2F3
+ F8807DB700006F474698DEDCEBB7B5D714147A00006900007000006E0000652B
+ 2B87D3D1E7C4C3DC27278623218C373574B8B8C7FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF7F7
+ F7F2F2F2F6F7F7D5C9BDF9B272FFB56AFDDD86FFF192FFEB8EFEEF91FFFA99FF
+ FD9CFFFB9AFFFA99FFFA99FFFC9AFFF998FFED91FEE78DFEED90FDDE85FFBA6D
+ F5AE71D5C3B2E4E4E3DEDFDFDBDBDBDADADADBDBDBD3D3D3BFBFBFA7A7A79E9E
+ 9EAFAFAFB0B0B0ABABABABABABA6A6A6A0A0A09B9B9B9595958F8F8F8A8A8A83
+ 83837D7D7D7878787272726B6B6B6464645E5E5E5F5F5F6565656A6A6A686868
+ 6262625E5E5E6060606767677070707676767B7B7B8181818A8A8A8888887272
+ 72727272757575747475737577877E73D19A66FFAE64FCA862FCAA64FCAA63FC
+ AA63FDAB64FDAB65FDAB64FCAA63FDAB65FCAA64FCAB64FDAC65FDAC65FDAB64
+ FCAA64FCAA64FCAB65FDAB65FCAB64FCAA63FCA963FDAA64FCB275FFEBD9FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF89B39F39AF7834976D3D9C71
+ 399569287F58308F66399E72399D723CA1763EA5783CA276329168318D633A9A
+ 6E35916938A6754CAE80D1DAD6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F8908EB09D9CBE6461B06D6AB0EAE8
+ F0C3C1DB4A479A3F3B94413E983B38943936919895C4F2F1F67F7DB70000764C
+ 4A9EDDDCEBC5C6DF5555A04140954644984544953F3D8F6160A4D9D8E9C4C2DC
+ 2C298827238F393777B8B8C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBE5E0F8
+ C28AFFB76CFDD480FFED90FEE98EFEEA8FFFF797FFFC9AFFFB98FFFA98FFFB99
+ FFFA99FFFB99FFFB99FFF697FEE98EFEE58CFEE98FFED681FFB76BF9BD84E1D8
+ CFEBECECDEDEDED2D2D2B3B3B39B9B9B8C8C8C8585858181819D9D9DB2B2B2AB
+ ABABA5A5A5A1A1A19D9D9D9898989393938E8E8E8A8A8A8383837D7D7D787878
+ 7373736B6B6B6464645E5E5E5F5F5F6565656A6A6A6767676262625E5E5E6161
+ 616868687070707575757B7B7B8282828A8A8A89898973737373737376767678
+ 787976797D958573E3A164FFAE64FDAD67FCAD66FDAD66FDAD66FCAD66FCAD65
+ FCAC65FCAC65FDAD65FCAC64FCAC64FDAD65FDAD66FDAC65FCAC65FDAD65FCAE
+ 65FCAC65FDAD65FCAD66FDAD66FCAD64FCB16EFEE0C7FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFCFD9D44FAD8039AB7837946B3B996E3590652F8B
+ 6137996E389A6E35956B37996E35966B3390643694683391683392693CB87F88
+ B19CF6F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF6F5F89190B29F9DC06D69B57B77B7F2F0F3F3F2F3DFDDE8DD
+ DBE8DADBE9DAD9E8D9D6E6EBE7F0F9F5F77B79B50000723C3995DBD9E8F3F3F6
+ DEDEECDDDDECDFDDECDEDEEBDCDAEADDDCEBF7F6FBC2C0DB2626862E2C913C3A
+ 77B8B8C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF9F6F7C59AFFB167FDCA79FEE88F
+ FEE68DFEE88EFFF395FFFA99FFF998FFF898FFF798FFF898FFF998FFF898FFF8
+ 98FFF898FFF193FEE48CFEE48DFEE68EFECA7AFFB76AE3BA92D2CEC9B2B4B599
+ 9A9A8C8B8B8383838080807E7E7E7A7A7A7E7E7EA0A0A0AEAEAEA7A7A7A1A1A1
+ 9E9E9E9999999393938F8F8F8A8A8A8484847C7C7C7878787171716B6B6B6363
+ 635D5D5D5E5E5E6464646868686464645D5D5D5A5A5A5E5E5E6767676E6E6E76
+ 76767C7C7C82828288888881818174747474747476767676767672757992816F
+ E3A265FFB46AFCB66EFDB66FFCB56EFCB56EFCB36EFDB46EFDB46EFDB46EFCB3
+ 6DFDB26BFCB26AFCB26AFDB169FDB169FDAF67FCAE66FDAF67FCAE67FCAF66FC
+ AE67FCAE66FCAE66FDB473FEE4CCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFDFDFD9BBBAA3FB47D39A673359565338D5F287B51277B4F287F5025
+ 7B4E277E51287D522B7F5330895B31916339B17A59AD84D7DEDAFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+ F6F99190B3A3A0C17A76BA6661AEA39FCCA7A2CDA8A5CFA8A6CEA5A4CCA5A3CC
+ A2A0CC9A97C78583BB4A499D2A298C3938937370AF8C8ABE908EC1908FC18F8D
+ C18B8AC18B8BC08B8AC08583BC55539E14137E413E9C3E3C79B8B8C7FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFEFEFFDCB9FFB16BFDC073FEE48BFEE68EFEE48CFFEF92FFF8
+ 98FFF898FFF697FFF697FFF698FFF697FFF597FFF697FFF596FFF497FFF496FE
+ EB92FEE18BFEE38DFEE08BFFC576FAB36CC7A8868B8D8D808588838483828282
+ 7F7F7F7F7F7F7D7D7D797979848484A4A4A4ABABABA2A2A29D9D9D9898989191
+ 918C8C8C8686867F7F7F7575756F6F6F6868685F5F5F5555554E4E4E4F4F4F57
+ 57575C5C5C5B5B5B5858585656565D5D5D6565656D6D6D7171717E7E7E838383
+ 8484847E7E7E74747476767676767676777773767A918270E3A265FFB970FDBB
+ 77FDBB75FDBC75FDBB75FCBA75FDBB75FCBA75FDBB75FDBA73FDBA73FDBA73FD
+ B973FCB771FDB971FCB870FDB56EFCB56EFDB46BFDB168FCAF67FDB067FDB067
+ FCB571FEE2C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8
+ FAF986B89F39A9742B8B661D5E761B5A7F27667A336F7236726E31707725657E
+ 1A577F1F656C319E6C4DAA7CC2D5CCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F99391B6A8A5C4
+ 8B87C34B46A44844A148449F4943A047439F44409D3F3B9A3B3799322D952926
+ 8F6763ACA19ECAA6A3CC3F3C98120E8117158214128016148016148115128012
+ 0C8007037B00007611117F4F4DA2424179B7B7C7FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE2
+ C9FCB371FCBB71FDDD88FEE58DFEE18CFEE990FFF396FFF498FFF497FFF397FF
+ F397FFF598FFF397FFF297FFF296FFF297FFF296FEF297FFF196FEE78FFEDE8B
+ FEE28DFDDA87FFC272F0AE69AB93777F82847F81838180807F7F7F7F7F7F7F7F
+ 7F7D7D7D777777888888A4A4A4A1A1A19898989191918A8A8A8585858787878A
+ 8A8A8F8F8F9090908A8A8A8F8F8F9595958F8F8F9292929191919E9E9EC2C2C2
+ C3C3C3BDBDBDB1B1B1ACACACA3A3A39595959494949999999898987F7F7F7272
+ 7275757578787879797971767A998670EAA965FFBC73FCBE7AFDBD77FCBE78FD
+ BE78FCBD77FDBE77FCBE77FCBD77FCBD77FCBD77FDBD77FDBD76FDBC76FDBD76
+ FCBD76FCBC75FDBC75FDBB73FCB972FCB66EFDB46BFDB269FCB169FED7B4FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEFEE5E8FA4
+ 368AAE286AA4215E9F2660A0356BA23E71A53168A2235E9F2160A22D75A63892
+ B089A2AEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F99492B8A9A6C6918CC56661B0908C
+ C4A9A6D0AFADD4B4B2D6B3AFD5ABA6D2AFABD49C98C9544FA58784BEB5B2D390
+ 8CBF403C994F4BA09290C29693C39391C39A98C69896C48F8BC07E7AB64F4E9E
+ 1D1C86514FA449467BB8B7C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDDCFDBC7FFDB76CFED482FE
+ E38DFEDF8BFEE58EFEEE94FFF396FFF296FFF196FFF196FFF196FFF297FFF196
+ FFF096FEF096FFF196FFF196FFEF95FEEF95FEED94FEE28DFEDB89FEDF8CFED3
+ 82FFBF6EE3AB6A998C7A7A7F858081828080807F7F7F7F7F7F7D7D7D78787875
+ 75758A8A8AA1A1A1A7A7A7B4B4B4C0C0C0C6C6C6CECECED4D4D4DEDEDEE3E3E3
+ E3E3E3ECECECF6F6F6F3F3F3F5F5F5F2F2F2F3F3F3FFFFFFFFFFFFFFFFFFFBFB
+ FBF8F8F8F5F5F5F0F0F0E3E3E3D5D5D5C1C1C18B8B8B73737375757577777777
+ 787870747AA58B70F5B067FFBE76FDC17EFDC07BFDC07BFDC17BFDC07BFDC17B
+ FDC17AFDC07AFDC07AFCC079FCC079FDC079FDC079FDBF79FDBF78FDBF78FCBF
+ 78FDBF77FDBE77FDBE76FCBC74FCB66DFDB369FDD7B0FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF678BA63797DC3C9CD94299
+ CF4597CC4697CD4797CF4597CC4397CC4199CE3D9FE03488CC90A2AEFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF6F6F99594B9A8A4C89F99CCB9B6D8EFEEF6F0F0F7EFF0F7EF
+ F0F6EFEFF5F8F7F9FAF9FBAFACD34642A0736FB6AAA6CE5654A41B18883F3B98
+ BEBDD9FCFAF9EEEAF3E8E5EFE9E5EFE8E5EFEBE8F0DDD9E86965AC524EA34C49
+ 7EB8B8C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFF7EFFDC692FCB36AFDCF7FFEDF8CFEDE8BFDE08BFFEC93
+ FEEF95FFF096FFF096FFF096FEF095FEF095FEF096FEEF95FEEF95FFEE95FFEF
+ 96FFEF95FEED95FFED95FFEE95FEE892FEDC8BFEDA8AFEDD8AFFCD7DFFBC6DCF
+ A36F87857F7B7F838180807E7F7E7C7C7C7A7A7A7E7E7E878787979797C2C2C2
+ E5E5E5F2F2F2FBFBFBFEFEFEFEFEFEFEFEFEFBFBFBFDFDFDFBFBFBF4F4F4F3F3
+ F3F4F4F4F2F2F2F2F2F2F3F3F3F2F2F2EAEAEAE2E2E2E9E9E9F0F0F0FAFAFAFD
+ FDFDFCFCFCFBFBFBF1F1F0B0B0B09A9A9A8E8E8E82828279797971757BA68D70
+ F6B169FFC07AFDC380FDC37EFDC47EFDC47EFDC47EFDC47EFDC37EFDC37DFDC3
+ 7DFDC37DFDC37DFCC27CFCC27BFCC17BFDC17CFDC27BFDC27BFDC17AFDC17AFD
+ C07AFCC17AFDBF76FDB86CFDD8B1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF7F8F7A8B9B9397BA02E8FD9369AE547A5E75BB2EB65B9EB66
+ BBE962B7EB54AEEA41A2E43499E82980C63778909FB2ACF2F4F3FDFDFDFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+ F6F99695BBA9A4CAADA8D3D9D5E7FAF6FAEFEBF4EBE8F3EBE9F3F1F0F7EDEEF5
+ ADABD35E59AB6763B1716DB66D69B55B57AA5450A42D29913C3999B3B2D4F2F0
+ F4E7E5EEE0DDEBDFDCEAE4E2EDF6F3F68F8CC15B58A84F4E7EB7B8C7FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF6
+ FED2A6FDB36AFDC979FEDE8BFEDC8BFEDC8BFEE790FEED94FFEE95FEED95FEED
+ 95FFEE95FEED95FEED95FEED95FFEE96FFEE96FEEC95FEEC95FEEC95FFEC95FF
+ EB94FEEA94FFEA95FEE390FEDA8AFEDA8BFED889FFC879FABC6BBB9C737F8081
+ 7C7F828180808B8B8B9797979F9F9FA9A9A9B0B0B0C3C3C3EBEBEBF4F4F4E5E5
+ E5E1E1E1D8D8D8D3D3D3D0D0D0D1D1D1D0D0D0CACACAC9C9C9C8C8C8C8C8C8C8
+ C8C8C8C8C8C3C3C3C1C1C1BDBDBDBEBEBEC0C0C0C2C2C2C5C5C5CDCDCDD9D9DA
+ DBDBDDA9AAACA2A3A4A2A3A49E9FA09394967E838AA89175F5B46CFFC57EFDC6
+ 82FDC681FDC782FDC782FDC781FDC781FDC782FDC680FDC680FDC680FDC680FD
+ C57FFDC67FFDC67FFDC47FFDC57EFDC57EFDC47DFDC47DFDC47DFDC47CFDC27B
+ FDBB71FED4A6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFF2F08E
+ AA993D8D893391C53189AC308797338B9B469DB863B4DF6AB9E858ABD33D95AB
+ 3189992E889A328AB73593BF398772A1B4A8FCFDFCFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6F99896BDADA9CC
+ AAA6D2B8B5D7F3EFF6F6F2F6F2EDF5F7F3F8EAE7F1A7A2CF615CAD7D77BAD1CF
+ E49C9ACB514DA6605BAEBDBCDBA3A1CD2B2790302D93A3A0CAE6E5EEE9EAF0E4
+ E2ECEDEDF2D4D2E45B59A7615FAC565482B8B8C7FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFDD8B7FCB56CFDC275FED8
+ 89FEDB8BFED989FEE18FFFEB94FEEB94FFEB94FFEC95FEEB94FEEB95FFEC94FF
+ EC95FFEC95FEEB95FEEB96FEEB95FEEA95FFEB95FEE994FFEA94FEE794FEE894
+ FEE893FEDF8EFDD789FDD889FDD486FFC776F6B86AAD9879888B8F969799A2A2
+ A1AAAAAAABABABA7A7A79E9E9E959595A3A3A3C2C2C2C3C3C3BFBFBFBABABAB8
+ B8B8BBBBBBB9B9B9BBBBBBBBBBBBBBBBBBBABABABABABABBBBBBBDBDBDBABABA
+ A9A9A99D9D9D9A9A9A9999999898989696969293958F92958E8F8E8585858B8C
+ 8B9192919798989798988C9297B89E7FF8BB70FFCA82FDCA86FDCA86FDC985FD
+ CA86FDC985FDCA85FDCA85FDC984FDC984FDC984FDC984FDC983FDC983FDC882
+ FDC882FDC882FDC882FDC681FDC781FDC881FDC780FCC57FFDBF74FED19EFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD8E1DC4B9A732F986B2B8362
+ 298057258251248856298A612B8C77348F832A8C6E2689592183532881532B82
+ 5C2C87642D9867779C8AE9EDEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F6FA9997C0AFACCEAFA9D48D88C1C6C2
+ DEEBE8F2F2EDF4E1DFEEA8A3CF736CB38983BEDBD7E9FDF8F9A5A0CE655FAE6A
+ 63B0C6C2DEFCFCFEA7A5CF393396332D938B88BFD4D4E5E3E3ECCFCEE17773B5
+ 28248F726EB65A5884B7B7C7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFEE8CFFCBB76FDBE72FED284FED98AFED889FEDE8DFE
+ E793FEE893FEE894FEE894FEE994FFEA95FEEA94FFEA95FFEA95FEEA95FEE995
+ FFE995FEE894FEE994FEE894FEE894FEE793FEE793FEE693FEE693FEE592FDDB
+ 8CFDD588FED78AFECF84FFC472EAB56FAC9E8C989CA19A9A9C9393938C8C8C8A
+ 8A8A898989858585858585A2A2A2BDBDBDBCBCBCBCBCBCBDBDBDBDBDBDBCBCBC
+ BCBCBCBBBBBBBBBBBBBABABABABABAB9B9B9BDBDBDADADAD9090909090909090
+ 908F8F8F8D8D8D8A8B8B8A89869E8E7AB09573B19470AE9574AD9473AC9372B4
+ 9B79B7A181DCAD76FFC477FECC88FDCD8AFECC89FDCC88FDCC89FDCB87FECC88
+ FDCB87FDCA87FDCC87FDCC87FDCC87FDCC87FECC86FECB86FDCB85FDCC85FDCB
+ 85FDCA84FECA84FDCA83FDC983FDCA82FDC379FDC88BFEE7CBFEE4C7FEE4C6FE
+ E3C6FEE2C5FEE2C4FEECD8FFEEDBFEF2E4FFFEFDFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFDEE3E04F95742D95642A83572683572A93637EC2
+ A19ED4B540A5761C925D76BF98A2D5B84FA97F2287592982572A81562C93643E
+ 986C9CB4A8F5F7F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF7F6FA9C99C1B1AED0B6B0D68A85BF8F8BC2A5A1CDAEA9D19A
+ 95C87F79BB938FC5D8D4E7FDFAFBF3EFF5ACA6D0746EB57772B7C5C1DEF9F5FA
+ FAF7FBB0ABD3504BA43F3C9C5F5CAA6E69B14D48A02B278F2E2B927E78BB5D5B
+ 88B7B8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
+ F3E6FDC68AFDBC70FECE80FDD78AFDD689FDD98BFEE492FEE794FEE693FEE694
+ FEE793FEE793FEE794FFE795FFE795FEE794FEE894FEE794FEE794FEE694FEE6
+ 94FEE695FEE693FEE594FEE594FEE494FDE492FEE593FEE190FED68AFDD388FE
+ D58BFECD7FFFC371DEB275918C817C7F848282838181818383838787878A8A8A
+ 8A8A8A979797B6B6B6BEBEBEBDBDBDBDBDBDBCBCBCBBBBBBB9B9B9B8B8B8B8B8
+ B8B9B9B9B7B7B7B6B6B6BABABAA6A6A68B8B8B8F8F8F8F8F8F8D8D8D8B8C8D86
+ 898BBB9D78F5C887FCD59CFBC57FFAB665FAB668F9B869FAB96AFBBA6BFCB769
+ FEC379FECF8CFECF8DFDCE8BFDCE8BFDCE8BFDCF8BFDCE8AFDCF8BFECE8AFDCE
+ 8AFECE8AFECE8AFDCE89FDCE89FDCE89FDCD89FDCE88FDCD87FDCD87FDCD86FD
+ CC86FDCC87FECC86FDC77DFDC073FDC176FDC076FDBF74FDBF75FDBF74FDBA6C
+ FDC482FECE98FCC88CFEE0C0FFFDFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFDBE0DE4D8A6D2D906429845C248B5E6CBA95F4F0DDFFF8E2B4D7B779
+ BF96EDEED6FFFBE9BBDBC1369C712181572C835C2D96675F9A7CCCD7D1FAFBFB
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7
+ F7FA9D9AC1B2ADD0B9B3D89490C3928EC28E89C08C87C08984BF9691C5D6D1E7
+ F9F5F9F5F1F6EFEDF4B2AED5817CBB8581BCCCC9E2F3EFF7F8F3F9F9F3F7B2AE
+ D56D68B35752A84742A03F3A9D3A35983A3698837EC060608CB8B8C9FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF5FDD1A0FCBB6EFDCB7F
+ FED589FDD488FDD78AFEE190FEE493FEE493FEE493FEE594FEE593FEE693FEE6
+ 94FFE595FFE694FEE594FEE694FEE694FEE594FEE594FEE594FEE494FEE494FE
+ E394FEE394FEE293FDE292FEE192FEE394FEDE90FDD489FED289FED28AFECA7D
+ FFC56FC3A16F7D7C7A7B7E818382838585858686868787878787878C8C8CA8A8
+ A8B9B9B9B5B5B5B5B5B5B3B3B3B1B1B1B1B1B1B0B0B0AFAFAFAFAFAFAEAEAEAE
+ AEAEB2B2B2A1A1A18989898C8C8C8B8B8B888888858788848383E3AF71FFEABD
+ FFF5DFFFEAC5FFCA83FFC174FFC57AFFC57AFFC57AFDC277FDCA85FED291FED2
+ 90FDD18FFDD290FDD28FFDD18FFDD18EFDD28EFED28EFDD28EFDD18DFDD18DFD
+ D08CFDD08CFDD18CFDD08CFDD08BFDCF8AFDD08AFDD08AFDD08AFDCF8AFECF89
+ FDCE86FDCC84FDCC84FDCB83FDC980FDC77FFDC67BFDC880FFECD1FFFDFBFDE8
+ C5FDC685FFF7EEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFE8DB09E30
+ 9C6B2D8D632482582C9869BEE0C5F5E4C99A8A77C6BAA5EEE3C8A59683BDAA94
+ F5F5DC6AB7931A85572C855D2D93654C9370BAC9C1FCFDFCFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F6FA9D9AC1B1ADCF
+ BCB8D89A95C39C96C49C97C59894C4948FC3BFBADAF8F5F9F0EDF5F3EFF6EFEC
+ F4B3AFD48983BF8C87C0CCC8E1F4F1F7EFEBF4F7F2F7EAE7F19996C87C76B87D
+ 78B97771B76762AF5C56AC9491C864628DB9B8C9FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFEFDFEE0BCFDBB6DFDC576FDD185FDD185FED286FEDC
+ 8CFEE291FEE190FEE292FDE392FEE393FEE494FEE494FEE494FEE494FEE593FE
+ E493FEE495FEE494FEE494FEE494FEE394FEE393FEE294FEE293FEE193FEE192
+ FEE193FDDF90FEDE8FFEDF90FED88BFDCF86FDCF85FDCD82FFC875FBC36FAF99
+ 767D7F808081828484848585858484848484848484849E9E9EB4B4B4B0B0B0B1
+ B1B1B1B1B1B1B1B1B2B2B2B2B2B2B0B0B0B1B1B1B0B0B0AFAFAFB2B2B29B9B9B
+ 7E7E7E8484848484848484848283857F7E7EE2B070FFDEA6FFEFD6FFF5E1FEEC
+ CAFED69AFDD495FDD496FDD596FDD696FED594FED392FED493FED493FED593FE
+ D593FDD492FED592FDD491FDD491FDD491FDD390FDD390FDD490FDD38FFED38F
+ FED390FDD38EFDD28EFDD28DFED28DFDD28DFED18CFDD08CFDD08BFDD08BFDD0
+ 8BFED18CFDD08AFDCE87FDCF8BFEE9C5FFFEFBFFFEFCFEE3B9FDC683FFF6ECFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDF0EE70A78A34A46F2D8E6324855A
+ 349D70D8EBD5E3DECD555452A4A299F0ECDC6464618B887FFFFFEB80C19F1A88
+ 5A2B855D2E94673F976D9FB7ABF2F4F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F6FA9C99C1B0ADCFC0BBDCA09AC8A09B
+ C9A19CC89B97C59B98C5D2CFE4F9F9FAEDEDF4F3F3F7ECEBF4B2AFD28D87C08F
+ 88C0C9C4E0F3EFF6EFEBF4F1EDF5F4F0F6B2AFD3837DBC8782BE8882BF827DBC
+ 827CBCAAA6D1676390B9B8CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFEEDD9FDC37EFEC378FED48FFDD592FED490FEDB93FEE196FEE295FEE49AFD
+ E193FEE193FEE194FEE193FEE194FEE294FEE295FEE495FEE394FEE294FEE294
+ FEE294FEE294FEE194FEE194FEE094FDE093FDDF93FEDF92FEE094FEE099FEE2
+ 9DFEE29DFFE19CFED997FED394FED494FED290FFCE7CE7BB728D867A7B7C7F80
+ 80808080808080808181818080809A9A9AACACACA6A6A6A3A3A3A1A1A19C9C9C
+ 9999999696969292929090909090909393939797978282826A6A6A7272727575
+ 7577777777787A77787BE2B170FFD187FDE6C1FEF0D5FEF1DCFFE5BCFDD596FD
+ D494FDD697FDD697FED696FED696FED696FDD695FED695FED796FED795FDD795
+ FDD694FED794FDD794FED694FED694FDD693FED692FED592FDD693FDD591FDD4
+ 91FED591FDD490FDD490FDD38FFDD38FFDD38FFED28EFED28EFDD18DFDD18CFD
+ CE85FEE3B5FFFAF0FFFFFDFFFBF3FDD69AFDC57EFFF7EDFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFF3F6F4A6BAAF3F8E692F946825865C319D6ECFE7D4FAF2
+ E4C5BFB7E0DFDBFCFAF9CAC8C3D9D2C6FDFCEE7BC09F1887582B815C309A6B43
+ 966ED4DBD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF7F6FA9D99C1B2ADD0C4BEDEA49ECDA5A1CFA6A0CDA29DCB9F
+ 99C8C7C4DEF8F8F9F0EFF5F5F5F9E9E8F1AEAACF928DC0918DC2C0BEDBF2F1F6
+ F2EFF5F4F2F6EFEAF3A8A4CE8C87C1918CC3918AC38C85C18E88C2B5B0D66B69
+ 94BABACCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF5FED6A6FDC47AFE
+ DA9FFFE5B7FEE4B7FEE8BBFEEDC0FEEFC3FEEFC6FEEBB4FDE29BFEE093FEE094
+ FEE093FEE194FEE094FEE295FDE295FDE194FEE094FEE095FDE095FEE094FEE1
+ 94FEE093FEE094FEDF94FDDF93FEDF91FEE09AFEE7ADFFEDB7FFEEB7FFEEB7FF
+ EBB4FFE3B0FEDEACFEDFB0FFD898F9CB79AA967178787778787A7B7B7B7B7B7B
+ 7A7A7A7878788C8C8C9A9A9A9191918989898383837878787070706868686262
+ 625B5B5B5C5C5C6363636969696767676060606161616565656969696B6C6D6C
+ 6D6FD3A86EFFCB7CFEDBA3FEE9C5FEEFD5FFF1DBFEE3B7FDD798FDD899FED89B
+ FDD899FED899FED999FDD898FED899FDD999FED998FDD998FDD897FED997FED9
+ 98FED998FED998FDD996FED896FED896FDD896FDD795FED894FED895FED794FD
+ D693FDD792FDD692FDD692FED591FED491FDD490FDD289FDDEA9FFF8EBFFFDF7
+ FFFCF4FFF7E8FDD292FDC986FFF8F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFCED7D146A17636B47C2A8D6228956697CBB0FFFCF7FFFFFFFFFFFFFE
+ FBFBFFFFFFFFFFFFDCEBDE50AB841F8B5C319B6D37BD80589B7AE0E5E2FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6
+ F6F99A97C0B4AED0C7C2DFA8A3CDAAA6CFA9A5CFA9A3CFA29DCCAFA9D1E0DEEC
+ F5F5F8FBFCFCDDDAE9A6A1CB9B96C59994C3B2AFD1EDEDF3FBFBFBF3F3F8C9C6
+ DF9892C4948FC39591C5948FC3928DC4948FC6BCB7DA6E6B96B9B8CBFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6E9FDCD8EFDCC87FEE3B2FFE8C0FFECC8
+ FFF3D4FFF7DFFFFAECFFFDF3FEE9B6FEDE94FEDF93FEDF93FEDF94FEDF94FEE0
+ 94FEDF94FDDF94FDE094FEE094FEE095FDE095FEE094FEDF94FDDF93FEDE94FE
+ DE94FDDE93FEDC91FDE29AFCE2A7F3CC9AF1C795F4CF9AF7D5A0FAD8A2FBD8A4
+ FDDAA7FFD397FBC677BFA26D7C7B7777797B7B7B7B7979797676767373738484
+ 849191918989898282827C7C7C7777777171716969696262625C5C5C5D5D5D62
+ 62626B6B6B6B6B6B6363636464646868686C6C6C6D6D6F6C6E70C5A06BFFC879
+ FED694FEE0AAFFEBC7FFF1D6FFF1D9FEE3B2FDDA9AFEDC9EFDDB9DFDDB9DFEDB
+ 9DFDDB9CFEDB9DFDDB9CFDDB9CFEDB9CFDDB9BFDDB9BFEDB9AFEDC9BFEDC9BFD
+ DB9AFEDB9AFEDB9AFDDC9AFEDA98FEDA98FDDA98FEDA97FED997FDD995FDD995
+ FDD895FED895FED895FDD58FFDDCA0FEF5E0FFFCF5FFF9ECFFF9EAFFF4E0FDD0
+ 8EFED095FFFAF4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCED7D35D
+ A17F3BB77C34AE792A986A3BA0749AC7B0CCE4D7A1CCB882BCA1BFDCCFC1DDCD
+ 6DB4932B9A6B2FA9743DAD7740B77D88AD9BF4F6F5FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F9908DB8A7A2C8
+ D7D4E8AFAACFABA5CEADA8CFABA6CEA9A3CEA59FCAB4AFD2D2D1E5DBD9E8BAB5
+ D7A09BCAA09CCA9E9AC8A19DCAC4C1DCDBD9EAC6C2DC9E99C69793C29895C396
+ 91C49692C38D8ABEA29DCCC2BFDD5E5C88B5B3C6FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF4E7FDC888FCC179FDD090FDDAA3FEE6B6FFEDC5FFF4D6FFF9
+ ECFFFCF6FDDD9CFDD681FEDD94FEDD94FEDD94FDDD94FEDE94FEDE95FEDE95FE
+ DE95FDDE94FEDE95FEDE95FEDE94FEDE95FEDD95FEDC94FDDC94FEDC94FEDC94
+ FFDF96F9D387E9A469E49762EAA76CF0B374F6BF7BF9C681FCC480FEBE76FBBB
+ 6DC3A77383827E7C7D7F7C7C7C7B7B7B7878787373738686869393938A8A8A84
+ 84847D7D7D7979797373736A6A6A6464645D5D5D5E5E5E6565656C6C6C6D6D6D
+ 6565656565656969696C6C6C6D6D6E6D6E71CAA56DFFCA79FED693FDD897FDE2
+ B0FEEECBFFF1D6FFEFD3FEE1AAFEDC9EFDDD9FFDDD9FFEDD9FFEDD9FFEDE9FFE
+ DE9FFEDD9EFEDD9EFEDD9EFDDD9DFEDD9DFEDE9DFEDE9DFEDE9DFEDD9CFEDD9C
+ FEDE9CFDDC9BFDDC9AFDDC9AFEDC9AFDDB99FEDC99FEDB98FDDA98FDDA97FDD9
+ 93FEDC9DFFEFD0FFFAF1FFF8ECFFF6E4FEF4E0FFF2DCFECC85FED193FFFAF3FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E9E8CCDCD4B9D1C452AA81
+ 37C08529A671309A6B4AA67B33A37225A16C44A57941A176289B6B33B87F46B0
+ 7EA8CEBBC1D4CAD4DBD7FAFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDBDB8C77770A1D3D2EBDAD6EABEB8
+ D7B9B4D5B9B4D5B9B4D5B6B1D3B0ADD2B3AFD3B4AFD3AFA9D2AFAAD3B1ABD3B0
+ AAD2ABA6D1AAA5D1ADA9D3A8A2CFA6A1CDA9A4CFA8A3CDA6A0CBA4A0CAADA8D1
+ D5D1EB9C9BC0636186DFDEE4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+ E7FDC688FCB96FFDC47AFDD590FEE2A7FFE9B7FFF0CCFFF7E7FFFBF3FDD58DFD
+ D17DFDDE96FDDD95FDDC94FDDC94FEDC94FDDD94FDDD94FEDE95FEDE96FEDC94
+ FEDC94FEDC95FDDD95FDDD95FEDB95FEDB95FDDB93FDDB96FFDD94FBCC78ECA2
+ 5DE69256EB9F5DF0AA62F5B568F9BE6EFCBC6CFEB467FBB369C4A4738585807D
+ 7E7F7C7C7C7B7B7B7979797474748585859292928A8A8A8484847E7E7E797979
+ 7373736B6B6B6464645D5D5D5F5F5F6565656C6C6C7272726969696363636A6A
+ 6A6D6D6D6E6F706D6E71BE9D6DFDC978FFD793FED894FEDA99FDE6B5FFEECBFF
+ F3D8FFEFCCFEE2A9FEDEA2FEE1A3FDE0A4FDE0A2FEE1A3FEE0A2FDE0A2FEE0A2
+ FEDFA2FDDFA1FEDFA1FEE0A0FEE0A0FEE0A1FEDFA0FEDFA0FEDF9FFEDF9FFDDE
+ 9EFDDE9DFEDE9EFDDE9DFEDE9DFDDD9CFEDD9CFDDC98FDDC99FEECC6FFF9ECFF
+ F8EAFFF5E2FFF2D7FFF4DBFFF1D9FDCB83FDDAA6FFFCF8FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC8D2CD63AC8938BF822FAC
+ 782698692C9D6F30A072289B6B289B6C35B98144B280ADCABCFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF7F6F7A5A0BA7876ADBEBCD9D5D3E8D3D0E7D1CFE6D1
+ CFE7D1CEE6D1CEE6CDCAE3CCC8E4CECCE5D0CDE5D1CCE5D1CCE6D0CBE6CCC7E4
+ C7C5E1C9C8E3CECBE5CDCAE5CDC9E3CCC8E1CBC7DFCAC7DF9795BB5B5686C4C2
+ CEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E7FDC587FCB96FFE
+ C980FEDA95FEE1A8FFE7B9FFEDCCFFF8E6FFFCF3FDD48EFED07DFDDC96FEDC95
+ FEDC95FDDC94FEDC94FDDB94FDDB94FEDC95FEDC96FEDC94FEDC94FEDC95FEDB
+ 95FDDB95FEDB96FEDB95FDDA94FEDB97FEDB93FCCB7AEFA762E69459EB9D5EF0
+ A963F5B36AF9BF71FCC373FEB86BFBB067C4A0718483807D7E807C7C7C7A7A7A
+ 7878787777778888889393938A8A8A8484847E7E7E7979797272726A6A6A6363
+ 635C5C5C5E5E5E6464646A6A6A7474747171716767676969696D6D6D6F6F706D
+ 6F72A48F6DF5C475FFD78EFDD893FED892FEDC9AFFE7B6FFEFCAFFF3D9FEEDC8
+ FEE2A9FEE3A6FEE2A8FEE2A6FEE2A6FEE2A6FEE2A6FEE2A5FEE1A5FDE1A4FEE1
+ A5FEE2A4FEE2A4FEE2A5FEE2A4FEE2A3FEE2A2FEE2A2FDE2A1FDE1A2FEE1A1FE
+ E1A1FEDFA0FDE0A0FEDF9FFDDE9BFDE9BBFEF8E9FFF7E7FFF5E0FFF1D3FFEFCF
+ FFF3D7FFF0D0FDCF85FEECD2FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE3EBE77CB89B3BC48835AC7B33986F32
+ 986E339C7137B88240B380A7C4B6FDFEFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFF8F8FAB3AFC97A73A46D69A0746EA1726DA1726DA1726DA1736DA1
+ 736EA1736EA1736EA1726DA1716CA0706CA0706A9D6F699C6C699C6B67996A65
+ 96686496666294656292676191575483706B93CDCBD8FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4E7FDC585FDBB70FDCC81FDD794FEDEA6
+ FEE5B7FFEECCFFF8E6FFFBF2FDD28DFDCD7CFEDB95FDD995FDD994FEDA95FEDA
+ 96FDDA95FDDA95FDDA95FDDA96FEDA96FEDA95FDDA96FDDA96FEDA96FED996FD
+ D995FED995FDD999FED994FBC879EEA561E59256EB9A5CF1A663F6B069FABC6E
+ FDC272FFBF70FAB268C4A1708685817E7F817E7D7D7C7C7C7979797C7C7C8B8B
+ 8B9090908888888181817A7A7A7575756F6F6F6767676161615A5A5A5C5C5C61
+ 61616767676F6F6F7575756E6E6E6666666A6A6A6F6F6F6C70727C7872DB9E63
+ FBB36EF9C183FBC686FCC786FDCF94FEE0B5FEE8C8FFEED5FEE7C0FDDAA2FDDA
+ A3FDDBA4FEDCA4FEDDA5FDDDA4FDDDA4FEDDA4FEDDA3FEDEA4FDDFA4FEDFA4FE
+ DFA3FDE0A3FEE0A3FDE0A3FEE1A3FEE1A3FEE0A3FEE1A3FDE1A2FEE1A3FEE1A3
+ FEDF9EFFE6B2FFF6E2FFF8E8FFF5DEFFF2D2FFEFCAFFF0CFFFF2D4FFE2A6FDD7
+ 93FFFAF1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFD5DDD956A6803ACC8D37B58133A47637B68237C587
+ 75A78FF8F9F9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FEFEFED5D3DF8F8AAB746D927871967872977872977872977871977871977871
+ 97787297787197767195767093766F92756E92736C91716B8E706B8C70698B6E
+ 698A686384847D95D9D8E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF3E7FDC385FCBA6FFDCD82FDD694FDDEA8FEE7BAFEEFD0FEFA
+ EDFFFEF9FDD18EFDCC7CFDDA97FDD996FDD995FDD995FDD996FED996FDD996FD
+ D996FDD996FED996FED996FED996FED996FDD996FED896FDD895FED896FED899
+ FED895FCC879F0A661E69056EB995BF0A561F5AE67F9BA6DFCBF70FFBF70FBB3
+ 69D1AE7BA09E9B98999B9696969191918C8C8C8E8E8E9090908D8D8D8C8C8C86
+ 86868383837E7E7E7F7F7F8C8C8C8B8B8B8585858787878B8B8B8989898D8D8D
+ 8F8F8F8F8F8F9090908585857A7A7A7375767073769D7D66E88E51F6A366F6B5
+ 7BF8B97EFABA7EFDCA94FEDEB6FFE5C5FEEBD3FEDEB5FDD49FFDD5A2FDD6A3FD
+ D7A3FED8A4FDD9A3FDD9A3FEDAA4FDDAA3FEDCA4FEDCA4FEDCA4FEDDA4FEDDA4
+ FDDDA5FDDEA4FEDFA4FEDFA4FEDFA4FEE0A4FEE0A4FDDF9FFEE3AAFFF2D7FFF8
+ E6FFF5DEFEF1D2FFEEC6FFEEC7FFF1CFFEE6B1FDD283FEEDCCFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFBAC5BF46A87B3EC88D38C78B36C689609D81E0E4E2FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F3
+ F6EDECF0EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1EEEDF1ED
+ EDF1EDECF0EDECF0EDECF0EDECF0EDECF0EDECF0EDECEFECECEFEBEAEEF2F1F3
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2
+ E5FDBD80FCB76DFDC87FFDD18EFDD99FFEE1B0FEE8C3FEF2DAFFF6E5FDCB87FD
+ C97BFED897FED796FED796FDD896FDD896FDD796FDD796FDD796FED797FDD896
+ FDD896FED897FED797FDD796FED796FED796FED695FED899FED494FEC678F4AC
+ 64E78F56EA9659F1A25FF5AD67FAB86CFDBB6FFFBB6DFCAF65D9AB7CADAAA7A6
+ A7A9A7A7A7A8A8A8A6A6A6AEAEAEBCBCBCC4C4C4D6D6D6E0E0E0E8E8E8EAEAEA
+ EAEAEAF0F0F0F0F0F0EFEFEFF0F0F0F0F0F0EFEFEFEEEEEEEEEEEEEFEFEFEFEF
+ EFCFCFCFBCBCBCBDBDBDAAABAC9B9B9ABF9170EC8F54F4A569F5B279F8B479FB
+ B87BFCCB98FFDDB6FEE5C7FEE8D0FDDBB0FDD5A1FDD6A4FED7A5FDD8A5FDD7A5
+ FED9A5FDDAA5FDDAA6FEDBA5FEDBA5FEDCA6FEDDA5FEDDA5FDDDA6FEDEA5FDDE
+ A5FEDEA6FEDFA5FDDFA6FDDFA2FDE1A9FEEECDFFF6E2FFF3DBFFF0D0FEEAC0FE
+ EAC1FEECC6FFE8B8FED286FEDDA9FFFDF9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFB
+ FACBD3CFABC1B768B39063A384DCDFDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2E8FDBC84FDB067FC
+ B66CFCBA70FDBB74FCBD76FDC17AFDC37FFDC381FDB96FFDC47EFED194FDD093
+ FED092FDD093FED193FDD093FDD193FDD193FDD093FDD193FDD193FDD193FDD0
+ 93FDD093FED093FDD093FDCF92FED196FDCE91FDBB72F7A762F29858F59B59F9
+ A25EFCAA62FFAF65FFB065FFAC60FCA55ED7AC83B6B5B2B9BBBCCACACADCDCDC
+ EFEFEFF7F7F7FBFBFBFCFCFCFCFCFCFDFDFDFAFAFAF9F9F9F9F9F9F4F4F4F3F3
+ F3F4F4F4F3F3F3F4F4F4F4F4F4F4F4F4F5F5F5F1F1F1EDEDEDE3E3E3CACACAC2
+ C2C2BFC0C0BABDBFB7B6B4D69A71EF9153F2A66BF5AF75F8B275F9B87BFCCD9B
+ FEDCB4FEE6CAFEE7CBFEDAADFDD6A5FED8A8FED9A8FDD8A8FED9A7FEDAA8FEDA
+ A8FDDBA7FDDBA7FEDCA8FDDCA7FDDCA7FEDEA8FDDEA7FEDEA8FEDEA7FDDFA7FE
+ DFA6FEE0A7FEEBC6FFF3E0FFF2D7FFEFCDFEE8BDFEE8B9FEEAC0FEE6B7FDD38B
+ FDD394FFF7ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+ F6F3F1F5F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF9FEDCBFFDBC84FCB67AFCB67AFCB67B
+ FCB77BFCB97AFCB87AFDB06AFCAF66FDC384FDCC92FDCB90FDCA8FFDCA90FECB
+ 91FDCB91FDCB91FDCC91FDCB91FDCB91FDCC91FDCB91FDCB91FDCA90FDCA90FD
+ CA90FDCA90FDCD95FDC88EFDB16AF9A862EFA766EAA667EBA466EAA365E8A062
+ E79F62EEA465F0B37FDBCDBFE1E3E3F3F3F3F6F6F6F3F3F3F3F3F3EFEFEFE7E7
+ E7E2E2E2DBDBDBD4D4D4CCCCCCCACACAC8C8C8BFBFBFBEBEBEBFBFBFBFBFBFBF
+ BFBFC0C0C0C2C2C2C2C2C2C2C2C2C2C2C2C3C3C3B2B2B2A0A0A0A4A4A3AAAAAA
+ ADB2B5B7ABA1DD905DF39456F1A76DF4AD73F7B074F8BA7DFDCF9FFEDCB5FEE6
+ CAFEE5C6FED9ABFED7A9FDD9AAFED9AAFED9AAFEDAAAFEDBAAFDDBA9FDDBA9FE
+ DBA9FEDCAAFEDCAAFEDDAAFEDDA9FEDEA9FDDEA8FEDEA8FEDCA5FEE6BDFFF3DD
+ FFEFD4FFEDCDFFE8BBFEE4B3FEE6B9FEE8B9FED490FDCD83FFF0DDFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFDFCFFF8F3FFF2E8FFF2E7FFF3E8FFF3E8FFF4EBFFF2
+ E8FEC797FCAC65FDC283FDCC93FECB92FDCA90FDCA92FDCB92FECB92FECA92FE
+ CB93FDCB92FECB93FECB93FDCB93FDCB92FDCB92FDCA92FDCA91FDC891FDCC96
+ FDC88FFFB069EDA462B397779A90859B90829B8F829D9183A19487BFB5AAE2E5
+ E5EBEDF0E8E8E8E4E4E4DCDCDCD3D3D3CACACABFBFBFBBBBBBBCBCBCBCBCBCBC
+ BCBCBCBCBCBBBBBBBBBBBBBCBCBCBDBDBDBBBBBBBBBBBBBCBCBCBBBBBBBBBBBB
+ BCBCBCBBBBBBBDBDBDBEBEBEBDBDBDA8A8A89292929090908F90908E9295A690
+ 80E08853F1955AF2A56CF5AC71F5AD70F8BA80FCD0A3FDDAB5FEE6CBFEE3C3FD
+ D8ABFDD8ABFDDAACFDDAACFEDAACFDDBACFEDCACFEDCACFEDCACFDDDACFDDDAC
+ FDDDACFEDDABFEDDABFEDDABFDDDA8FFE3B6FFF0D7FEEFD3FEEBCAFEE5BBFEE0
+ ACFEE3B0FDE5B5FDD799FDC87EFEE9CBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCA3FDAA65FD
+ C184FDCB94FEC992FDC992FDC992FDCA92FEC992FECA92FECA92FDCA92FDCA93
+ FDCA93FDCA92FDC992FDC992FDC892FDC993FDC791FDC996FBC58EFFAC65E99E
+ 5FA1907E838A90878C908D9296989CA09BA0A4B3B7BBD0D2D6D1D2D3C5C5C5B7
+ B7B7B4B4B4B7B7B7B9B9B9BABABABCBCBCBCBCBCBCBCBCBCBCBCBBBBBBBBBBBB
+ BCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBCBABABAB9B9B9BABABABBBBBBBBBB
+ BBBBBBBBBEBEBEBCBCBC9F9F9F8D8D8D8C8C8C898A8C84898BA68570E3864FF0
+ 955BF0A26AF2A76BF4A96BF8BA82FBD0A3FCDBB4FDE8D0FDE1BEFDD9ACFDDAAE
+ FDDAAFFEDAAFFDDBAFFDDCAFFDDCAFFEDCAEFDDCAEFDDCAFFEDDAEFEDDAEFEDD
+ AEFEDEACFEE1B3FFF0D4FFEED2FEEAC7FEE3B9FEDCA6FEDEA9FEE1AEFDD89CFD
+ C478FEDFB8FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFC9C8C8BCBCBCBCBCBCBCBCBCBABABA
+ D0D0D0FAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDFBF7C79EFDA662FCBD80FDC891FDC58F
+ FCC58FFDC790FDC78FFDC690FDC790FDC790FDC690FDC690FDC890FCC690FCC5
+ 90FCC690FCC58FFBC48FFBC38EFAC593F8BF8BFDA560E9975BA28F7C898C8F92
+ 92939999999898989090919A9A9AACACACAFAFAFB0B0B0B4B4B4B7B7B7B8B8B8
+ BABABABABABABABABABABABAB9B9B9B8B8B8B6B6B6B6B6B6B7B7B7B5B5B5B4B4
+ B4B5B5B5B5B5B5B4B4B4B4B4B4B6B6B6B6B6B6B7B7B7B8B8B8B8B8B8B8B8B8BB
+ BBBBB3B3B39797978D8D8D8C8B8B86888B858686B18365E9864EEE965DEF9F66
+ F1A267F3A86BF7BC86FBCEA0FCDAB6FEE7CEFEDFBBFDD9AFFEDBB1FEDBB1FEDB
+ B1FEDCB1FEDCB1FDDCB0FEDDB0FEDDB0FEDDB0FDDDAFFEDEAEFEE0B2FEEBCCFF
+ EDD2FFE6C3FEE1B7FED9A3FDD8A1FDDCA9FED89EFDC47BFDD19CFFF9F2FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFEBEBEBA6A6A6A5A6A6A8A3A6ABA3A7AAA2A7A7A5A6A0A1A1C2C2C2FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFEFCFBF5C29BF79F5EF9B77CF9C48EFAC18CF9C18BF9C28CF9C2
+ 8CFAC28DFAC38DFAC38DF9C28CF9C28CFAC28CF9C28DF9C28CF8C28CF8C08BF7
+ BF8BF8BF8AF7C18FF5BB87FA9F5FE691579F8B78898C8E8D8D8D888888838383
+ 7A7A7A838383A8A8A8B4B4B4B4B4B4B6B6B6B7B7B7B8B8B8B8B8B8B7B7B7B7B7
+ B7B5B5B5B5B5B5B5B5B5B4B4B4B2B2B2B2B2B2B1B1B1B1B1B1B0B0B0B0B0B0B0
+ B0B0AFAFAFADADADAEAEAEB0B0B0B1B1B1B0B0B0B0B0B0B2B2B2B4B4B4A7A7A7
+ 8D8D8D86868687868682858788847FC1815AEC884CEC955DEE9D65F0A167F3A8
+ 6CF7BC89FBCEA2FDDCBAFEE8CFFDDDB9FEDAB2FEDCB4FEDCB4FDDCB3FDDCB3FE
+ DDB3FEDDB2FEDDB2FEDEB3FEDEB2FEDEB2FFE8C8FEECD1FDE5C1FEE1B6FDD79F
+ FDD49AFED7A2FED7A0FCC57FFDC383FFF2E4FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDDEDEDED2D2D2DCDCDCFFFFFFBFBFBFB9BA
+ BACDCCCDC1C9C5B9CDC2BACAC2C6C7C6CAC9C9AAAAAAFAFAFAF0F0F0D4D4D4D5
+ D5D5EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFC
+ FBF2BB97F3995AF5B078F5BD89F6BC88F6BC88F6BC87F6BB87F7BD89F7BC88F6
+ BC88F7BD89F5BD89F6BB89F5BB88F6BC89F6BB89F4BA88F5BB89F4B886F4BB8B
+ F3B584F6985AE28B54988572797D807978797575757878787C7C7C878787A9A9
+ A9B3B3B3B0B0B0B2B2B2B2B2B2B1B1B1B0B0B0B1B1B1B0B0B0AFAFAFB0B0B0B0
+ B0B0AEAEAEAEAEAEACACACADADADACACACACACACABABABACACACAAAAAAA9A9A9
+ AAAAAAAAAAAAABABABABABABACACACADADADADADADAEAEAE9E9E9E8787878282
+ 828483837B82868C8075D07E50EB864DEA935CED9960EF9B62F1A46AF6BB8AFA
+ CCA1FBDEBEFEE6CEFDDCB8FDDAB5FEDDB7FDDCB5FDDCB5FEDDB6FEDEB6FEDEB6
+ FEDEB5FEDEB4FFE6C4FFECD2FEE3BEFDDFB5FED59EFDCF93FDD299FED49BFDC5
+ 82FCBF7BFEEBD7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFE2E2E2A1A1A1AFAFAFA6A6A6F2F2F2B4B4B4C5C2C4BEC0BF91D2B06E
+ D9A376D6A4AAC8B8CBC4C7AAAAAAF5F5F5C3C3C3AFAFAFAAAAABADADAEFEFEFE
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFBF1B895EF9356F2
+ AB75F4B786F3B584F4B784F4B884F4B784F4B786F4B684F4B784F3B785F3B885
+ F3B785F3B684F4B685F3B585F3B685F2B685F2B382F1B787EEAF80F39256DC82
+ 4F887463686C6E7070707979787D7D7D7E7E7E878787A5A5A5ACACACAAAAAAAD
+ ADADACACACAAAAAAA8A8A8A8A8A8A9A9A9A8A8A8A9A9A9A8A8A8A6A6A6A5A5A5
+ A3A3A3A4A4A4A4A4A4A4A4A4A3A3A3A3A3A3A2A2A2A3A3A3A4A4A4A4A4A4A5A5
+ A5A6A6A6A5A5A5A5A5A5A5A5A5A6A6A6A7A7A79292927E7E7E7E7E7E7D7E7E76
+ 7C7E947A69D47B4CE9844EE89059EB935DEC955CF0A269F6BD8CF9C99DFADEC1
+ FCE6CCFCDCB8FCDCB8FDDDB9FDDDB8FEDDB8FEDFB9FDDFB7FDDEB6FEE3C1FFEA
+ D1FFE1BCFEDCAFFDD29DFDCA8CFDCC91FDCE94FDC583FDB974FEE3C8FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDBE
+ BEBED9D9D9B5B5B5F0F0F0AEAEAED0C7CBB2BFB968D09D44D9914DD89490C9AC
+ CCC4C8B0AFAFEAEAEAC3C3C3D1D1D1D5D5D6AAAAAAFBFBFBFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFBEFB694EB8C53EFA772F2B483F1B181
+ F2B281F2B281F1B281F1B282F1B281F2B281F1B281F1B281F3B181F2B181F1B1
+ 81F1B181F0B081F0B081EFAF7FEFB284ECAA7DF18D54D77B49836D5D6A6E7075
+ 75767A7A797B7B7B7979798181819E9E9EA5A5A5A1A1A1A3A3A3A3A3A3A2A2A2
+ A1A1A1A1A1A1A1A1A1A0A0A09F9F9F9A9A9A9696969090908C8C8C8A8A8A8686
+ 868383838383838686868989898888888787878A8A8A8F8F8F9393939898989B
+ 9B9B9C9C9C9B9B9B9C9C9C999999838383757575787878747677737576A0765E
+ DC7947E8844EE78B57E99059EA945BEFA56FF5BC8EF7C79FFBE0C6FCE4C9FADB
+ BAFCDCBBFDDCBAFDDDBAFEDEBBFEDEB8FEE0BEFEE9D0FEE1BEFEDAACFDD19DFD
+ C688FDC88AFDCB8EFDC686FDB56DFED1A7FFFDFBFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFDFDFDE5E5E5DDDDDDDFDFDFE1E1E1E3E3E3AEAEAEC3C3C4CCCCCDAFAFAF
+ F6F6F6AAAAAAD8CCD2A6BFB254CD9039D0853DCF877AC8A0CAC5C7BDB8BAD8D8
+ D8D8D8D8BDBDBDCACACAAAAAAAD8D8D8F9F9F9EEEEEEEDEDEDEDEDEDFAFAFAFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFEFCFBEDB392E6844FEBA06EEDAD7FEEAC7DEEAB7CEEAB7CEEAB
+ 7CEEAB7DEEAB7DEEAC7DEFAD7DEEAC7CEFAC7DEEAB7DEDAB7DEEAB7DECAA7CED
+ A97CECA87BECAB7FE9A477EC8650D577488871616D7173737374757575767676
+ 7474747B7B7B9595959B9B9B9898989A9A9A9B9B9B9A9A9A9B9B9B9A9A9A9797
+ 979393938D8D8D8686867F7F7F7979797272726B6B6B6666665F5F5F60606067
+ 67676969696B6B6B7474747B7B7B8181818888888E8E8E9595959999999D9D9D
+ 9E9E9E9F9F9F9696967A7A7A7070707170706E6F726F7070AA7254E47945E481
+ 4EE48854E88B57EA9059EEA470F4BB8DF7CAA3FBE4CDFBE0C6FBDBBCFBDCBEFC
+ DDBDFDDDBDFDDFBFFDE8CFFEE1C0FED6A8FECF9BFDC385FDC183FDC588FCC283
+ FDB36EFEC28CFFF5ECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFF1EFEDCBC1BAB1A095AE978AB29989B2998AAC9689B4A49ADDD6D1FEFE
+ FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9BEBEBEACACAC
+ ABABABA6A6A6A5A5A5A7A7A7B4B4B4C7C7C9CBCBCEB3B3B3EAEAEAADADADDBCE
+ D593BDA642C58039C77D39C77D61C28DC6C6C7C7C0C4C5C6C5E9E9E9B6B6B6CF
+ CFD0BABABCA8A8A8A4A4A4A3A3A3A2A2A2A7A7A8A7A7A7ECECECFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFB
+ FAEBAC8FE2804BE89A6BEAA77AEBA578EBA677EBA678EBA577EBA478EBA578EB
+ A578EBA679EBA678EBA678E9A577EAA578E9A478E9A277E9A277E9A276E9A57B
+ E69E73E77D4BD27145866F606B6E706F70717272727171716D6D6D7676769393
+ 939C9C9C9E9E9EA1A1A1A2A2A29F9F9F9C9C9C9797979393938E8E8E89898982
+ 82827A7A7A7777777070706767676161615A5A5A5C5C5C636363636363666666
+ 7676767E7E7E8484848989898D8D8D9393939999999E9E9EA2A2A2A5A5A5A8A8
+ A89C9C9C8080807373726C6B6B62686B6B6764B36E4BE17644E17D4CE38350E5
+ 8752E68C55EBA26EF2B789F6CBA8FAE4CFFADFC5FADBBFFADDBFFBDDBEFCE7CF
+ FCE0C3FBD0A2FBCA97FCBD81FBB97AFBBD80FDBF80FCB26DFCB57AFFEEE2FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E2DFAD9B9090715F7E59
+ 3E76492A794A2A7B4C2B7A4C2B774B2A784C2D86634BA89385E9E4E1FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5E5E5AEAEAEE5E5E5E2E2E2E2E2E4E2E2
+ E2E2E2E2D8D8D9CECECFC8C8C9CCCCCCE4E4E4B0B0B0D5C9D088BC9D41C0793F
+ C1793FC27958BE84BEC6C2C8C1C5BEBFBEF5F5F5B6B6B6D9D9D9D0D0D1E1E1E1
+ E0E0E1E0E0E0DCDCDCE0E0E2C3C3C3D0D0D0FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFAE9A78CDE7A48E5
+ 9465E8A074E89D72E8A073E8A073E89F73E89E72E79F72E79E72E89F73E89E73
+ E89E73E79F74E79D73E79E73E69C72E69C72E69B71E59F76E3986EE47748CD6B
+ 42816A5C66696A6868686868686B6B6B6E6E6E7D7D7DA0A0A0AFAFAFACACACAA
+ AAAAA6A6A6A2A2A29D9D9D9898989393938E8E8E8B8B8B8484847D7D7D797979
+ 7272726B6B6B6464645D5D5D5F5F5F6666666767676868687676767E7E7E8484
+ 848989898F8F8F9393939999999E9E9EA2A2A2A5A5A5ABABABAFAFAF9F9F9F85
+ 85847F7F7F7B7A7A636A6D726359C26A44E07242DE7948E07E4CE2814DE58854
+ ECA271F0B488F5CCADFAE4D2F9DEC6FADCC0FBE5CFFBE0C6F9C99EF9C493F8B8
+ 7FF7B072F9B477F9B779FAAF6DF9AC6DFDE6D5FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFEFEFEC8BCB483624D774A2C7B4D2B7F4F2D81512F80502E7D
+ 502D7E502D7F512E81512E7D4F2C754829947563EAE5E1FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFD1D1D1B3B3B3F2F2F2CACACAC6C6C7CACACAC4C4C4B8B8B9E6
+ E6E6D8D8D7D2D2D1D2D3D3BCBBBCCDC7CA8ABE9E5DC8875CC9885FC98963C38A
+ B5C4BBCCC5CAB9B9B9F8F8F8BBBBBBF0F0F0CECECEBEBEBECBCBCCC9C9C9C2C2
+ C2E4E4E4E0E0E1C0C0C0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFBFAE3A68BDC7244E18B5DE4976CE4956A
+ E3956BE5966BE4956BE5956AE3956BE4966BE5966AE4956BE3956BE4966CE495
+ 6AE3946BE2946BE29369E29269E1956DDF8E66E07044C9643E7B64565D616263
+ 63647171707C7C7C858585929292AEAEAEB4B4B4ADADADA9A9A9A5A5A5A1A1A1
+ 9D9D9D9898989393938E8E8E8B8B8B8484847D7D7D7979797373736B6B6B6565
+ 655E5E5E5F5F5F6767676666666767677777777E7E7E8484848989898E8E8E93
+ 93939999999D9D9DA1A1A1A5A5A5A9A9A9ADADADAFAFAF9A9A9A878787898989
+ 868687767A7C8B6D5ECB6940E06E3FDC7546DE7949DF7C49E38855EBA475EFB1
+ 86F5D0B4FAE5D3FAE1CEF9E1CCF6C9A1F5BC8DF4B17CF3A66BF3A96CF5AC71F5
+ A86AF5A365FAD7BBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFCB8
+ A79D7D563B7D4E2C80502E7E502C7F52318A6143A07E65AF927DAE917C9F7D63
+ 875D3E7D4F2C80522E7A4A2AAA9485FEFEFDFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4
+ C4C4C0C0C0FEFEFEB2B2B2C2C2C2CFCFCFC6C6C6ABABABF7F7F7D6D6D6E1E1E1
+ BDBDBDCCC8CBC1C4C293C6A57DD59D76D19879D39972CB93A5C1AFD5CFD3B0B0
+ B0FCFCFCBCBCBCFFFFFFCFCFCFB1B1B1D0D0D0CECECEAEAEAEDCDCDCF8F8F8B7
+ B7B7FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFDFBFAE0A389D76C42E08C63E39872E3966FE3966FE2976FE196
+ 6FE2976FE19670E29670E3976FE29670E29670E29670E3966FE2966FE1956FE1
+ 956EE0936FE19773DE906BDE6E43C35D3A7A60556B6E707B7C7D8C8C8C929292
+ 8F8F8F949494AEAEAEB2B2B2ACACACAAAAAAA6A6A6A2A2A29E9E9E9999999494
+ 949090908A8A8A8383837C7C7C7777777171716868686161615A5A5A5C5C5C63
+ 63636464646767677676767D7D7D8383838888888E8E8E9494949A9A9A9E9E9E
+ A1A1A1A5A5A5A9A9A9ACACACB2B2B2AFAFAF9696968787878C8C8C8A8B8D8488
+ 89A57A66D36A3EDA6B3DD97143DA7545DC7645E28755E9A072EDAF85F5D7C0FB
+ E7D9F4C6A4F0B284F0AB78ED9C63EE9C62EFA066F0A065F0965BF5BF9AFFFBF9
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFAFABAA89C7B503480512D7E502D
+ 8054339A765BCBB8ABE7DED7F1ECE8F7F4F1F7F4F1F2EDE9E4D9D2B0937E8255
+ 347E502D8F6A50DCD1CAF2EDEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBDBDBDD0D0D0FFFFFF
+ E3E3E4D5D5D5D3D3D3D5D5D5E6E6E6FFFFFFCDCDCDF1F1F1B2B2B2DBD4D8B2BE
+ B694CCA8A0E4B897DFB096DFB083D4A290B99FD9D3D7B4B3B3FDFDFDC2C2C2FF
+ FFFFF8F8F8DBDBDBD3D3D3D3D3D3D8D8D8F4F4F4FFFFFFB8B8B8F5F5F5FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFB
+ FADFA088D36B43E29A78E5A789E4A485E4A485E4A485E4A485E4A585E4A585E4
+ A585E5A585E4A585E4A585E4A384E4A485E3A485E3A384E4A385E3A183E3A788
+ E0A081DC734CC35B398F73688B8E909495969494949191918E8E8E939393ADAD
+ ADB3B3B3ADADADAAAAAAA6A6A6A2A2A29D9D9D9898989191918D8D8D8686867F
+ 7F7F7878787272726B6B6B6363635A5A5A5454545555555C5C5C606060686868
+ 7474747B7B7B8282828787878B8B8B9090909797979C9C9CA1A1A1A5A5A5A9A9
+ A9ADADADB0B0B0B6B6B6AEAEAE9393938787878B8B8B8B8D8E898D8EB1765BD3
+ 663BD66A3ED66D40D86F41DA7242E08354E7A074F0C3A4F5D5BCEEB791EA9F6E
+ E8915BE88E57EA945DEB965DEA8E56EEA67BFDF1E9FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFD3C7C07A503580502D7E502D8A6142C2AD9DF1EBE7FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F4F2B79D8A7C4F2C895F42B8
+ A090D7CAC1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBFCBCBCBF1F1F1F4F4F4F8F8F8F8F8
+ F8F8F8F8F5F5F5F1F1F1C3C3C3F9F9F9ADAEAEE3DFE2B4BAB57DB49381C59D88
+ C59F82C39B68B58989AD97DDD8DBC0BFC0ECECECD3D3D3E8E8E8F3F3F3F7F7F7
+ F8F8F8F8F8F8F7F7F7F1F1F1F0F0F0B9B9B9F4F4F4FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFADD9883D06741E0
+ 9B7DE5AC90E4A88BE4A78BE4A78BE4A88BE6A78BE5A88BE4A78BE4A88BE4A88B
+ E4A88BE4A78AE3A68BE2A68BE3A58AE3A58AE2A388E4A88FE1A388D7704DC45A
+ 39A184799497999193929190909090908D8D8D979797B0B0B0B3B3B3ACACACA8
+ A8A8A2A2A29C9C9C9797979191918B8B8B8787878C8C8C8F8F8F939393959595
+ 9191919999999C9C9C9797979A9A9A9D9D9D9999999C9C9CA1A1A1A0A0A0A7A7
+ A7A9A9A99E9E9E9999999D9D9D9E9E9E9F9F9F9F9F9FA5A5A5AAAAAAAFAFAFB4
+ B4B4B9B9B9ABABAB8E8E8E8888888C8C8C898D908F8986BA6D4ED36036D4663C
+ D56A3FD66B40D76C3DE08A60EFC1A4F3D0B7ECB18CE28451E2804DE58753E48A
+ 56E58650F39665F9E6DBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1EE
+ EB9576627D4F2D7D4F2D8D6648D8CABFFFFFFFFFFFFFFEFEFEEAE6E2CAC0B8B4
+ A49AB5A59BCDC4BFF8F7F6FFFFFFF0EBE7967155845838B09580D0C0B4FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFE6E6E6CDCDCDC6C6C6C6C6C6C7C7C7C7C7C7C6C6C6C5C5C5CA
+ CACAE6E6E6EBEBEBB0B0B0E3E5E4CBC8C9BAB9BAB1B6B3B3B6B4B4B8B5B7B9B9
+ CCC7CAE3E3E3C9CAC9D7D7D7FAFAFAD3D3D3C4C4C4C5C5C5C6C6C6C6C6C6C6C6
+ C6C5C5C5C9C9C9DCDCDCFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFBFADC9581CB5B37D67E5CDB8C6CDA8868
+ DA8867DA8868DA8868DB8969DA8A68DA8968DA8868DA8868DA8868D98868D987
+ 68D88768D88667D78767D78466D8876AD68366CF5B3AC054379D827891969792
+ 93939392929191918C8C8C999999AFAFAFAEAEAEA8A8A8A5A5A5A1A1A1A4A4A4
+ AEAEAEB9B9B9C5C5C5CBCBCBD6D6D6DCDCDCE4E4E4E8E8E8EAEAEAF3F3F3F7F7
+ F7F6F6F6F8F8F8F8F8F8F7F7F7F8F8F8F7F7F7F8F8F8F9F9F9F8F8F8F6F6F6ED
+ EDEDE0E0E0CCCCCCBDBDBDAFAFAFACACACADADADADADADB0B0B0B5B5B5BBBBBB
+ A5A5A58C8C8C8C8C8C8C8C8C878E8F96837AC26442D15C33D1623BD2663DD364
+ 39D7764BE8AC8BEFC3A9E39670DB6E3EDD7949DE7D4CE27D4AEC8B5BECD1C4FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEC1B77F53357F502D89
+ 5F41D4C5B9FFFFFFFFFFFFECE8E5AA988D7F5D46774F32794E2F784E2F764E33
+ A18C7DF5F2F0FEFEFDB89F8D845838B79E8BD9CCC2FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFEFEFEFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFCFCFCFDFDFDFFFFFFD9D9D9
+ B9B9B9E8E7E8D5D6D5C8CFCBC3CDC7C6CDC9C9CFCBCAD1CDD6D9D6EBEBEBD5D5
+ D4C4C4C4FFFFFFFFFFFFFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFDFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFDFBFADA917EC75131CA603ECD6C4ACF6B4ACF6C4ACF6B4ACF6B
+ 4ACF6C4BCE6D4ACE6C4ACF6C4ACF6C4BCF6C4BCD6C4ACF6A4ACE6A4ACD6949CD
+ 6A49CD6849CC684AC96244C74729BD4D349980778C93949091918F8F8F8D8D8D
+ 8A8A8A9F9F9FB0B0B0AFAFAFB7B7B7C4C4C4D4D4D4E0E0E0EAEAEAF6F6F6FEFE
+ FEFFFFFFFEFEFEFDFDFDFDFDFDFCFCFCFCFCFCF5F5F5F1F1F1F2F2F2F1F1F1F2
+ F2F2F3F3F3F2F2F2F2F2F2F2F2F2F3F3F3F5F5F5F6F6F6F9F9F9FBFBFBFAFAFA
+ FAFAFAF5F5F5DFDFDFCCCCCCBFBFBFB8B8B8B5B5B5B8B8B8BBBBBBA1A1A18C8C
+ 8C8C8B8B8B8C8D8A8E8F9B7E72C35C3BCE5833CD5F38CE5F37D36E46DF926EE3
+ 9F7CDC8159D5673AD76F43DB7143E37A4AD8B2A0FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFCFBFAA98E7B7D4F2D7E4F2EBAA18FFEFEFDFFFFFF
+ E1DBD78E725F794B2C80512D80502E80502D7F502D81512D7A4E2DBCAA9DFFFF
+ FFB9A1918A6142D7C8BEF0EBE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCDC7C7C7F3EAF1ABCE
+ BA70CD9974D4A070D09C73D19D6FD09A81C79FE8E9E8E3DEE1BDBDBDFEFEFEFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFB
+ FAD89180C14B2DC65738CA6547CA6547CB6547CB6647CB6647CB6647CA6546CA
+ 6546CB6647CB6647CB6647CB6547CB6546CA6446C96446C96245C86345C96347
+ C45A3DC04125B847309D80779498999495959292929595959B9B9BB2B2B2CACA
+ CADADADAE5E5E5EFEFEFF8F8F8FBFBFBF8F8F8EEEEEEE5E5E5E0E0E0D7D7D7D3
+ D3D3D1D1D1D1D1D1D0D0D0CCCCCCCACACACACACACBCBCBCBCBCBCBCBCBCBCBCB
+ CBCBCBCBCBCBCBCBCBCACACACCCCCCD0D0D0D8D8D8E0E0E0EAEAEAEDEDEDEFEF
+ EFF1F1F1EEEEEEDDDDDDC9C9C9C0C0C0C0C0C0B7B7B79999998B8B8B8C8C8C8C
+ 8E8F8A8E8FA27464C75331CD5733C95732D06B46E09979E5A789DA825ED06136
+ D3673DDE6E40D7997BDCD5D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFF6F3F197745A7D4F2D8F6649E6DDD7FFFFFFF0ECE99579667A4C2B8252
+ 2F7E4F2D7E502D80502E8154337E4F2D7E4F2DA0816BF6F3F19979659C785EF8
+ F6F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFC1C1C1DBD9DAEDE7EA8BCBA869DCA085E7B57B
+ E2AD82E6B27DE6AF69CE97D7E1DBEFE7EBB9BAB9FBFBFBFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFCFCDBA297C24D31C1
+ 4D32C65D41C65F42C85E42C85E42C85E42C85F42C75D41C75D41C75E41C75D42
+ C65D42C75D42C75D41C65D41C55C41C55B40C55A40C65A40C15137BA381FB947
+ 33B89D95B8BDBDB5B6B6B3B3B3BABABAC9C9C9DBDBDBE7E7E7EEEEEEEFEFEFE5
+ E5E5D7D7D7D0D0D0CBCBCBC8C8C8C5C5C5C4C4C4C1C1C1C0C0C0C2C2C2C3C3C3
+ C4C4C4C4C4C4C6C6C6C5C5C5C5C5C5C6C6C6C6C6C6C6C6C6C6C6C6C5C5C5C5C5
+ C5C6C6C6C6C6C6C4C4C4C1C1C1BFBFBFBEBEBEC5C5C5D0D0D0D8D8D8DFDFDFE3
+ E3E3E7E7E7DDDDDDCDCDCDC5C5C5B5B5B59696968C8C8C8E8E8E8C90918D8D8D
+ AD664FC64927C64E2CCE6847E0A085E6B198D88363CC5931D45F37C16A47D9CB
+ C3D2D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2EEEB916C
+ 507C4D2CA17F67F8F6F4FFFFFFCABAAF7C4F317F502D7C4E2C7F52319D7A61BF
+ A999C5B0A0A5846D805230A4856DD5C9C1835C40CCB9ABFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFB7B7B7F1ECEFE3E3E27CCCA15CDA9A7CE2AD8DE5B789E5B66DDFA5
+ 5BCE92C7DECFFDF5F8AFAFAFF7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEE0B5AFC24D35BC4329C05238C05339
+ C25339C25339C15439C15339C15339C15339C15338C05239C15239C05338C050
+ 37C05037BF5037C04F37BF5139C04F37BA412AB3220CB74737C6BBB9C7CFD0C6
+ C5C5CFCFCFDBDBDBE1E1E1E2E2E2D8D8D8CDCDCDC5C5C5BFBFBFBEBEBEBCBCBC
+ BDBDBDC0C0C0C2C2C2C4C4C4C6C6C6C9C9C9C8C8C8C9C9C9CACACAC9C9C9CBCB
+ CBCACACACACACACBCBCBCCCCCCCCCCCCCBCBCBCACACAC9C9C9CACACAC9C9C9C7
+ C7C7C3C3C3C3C3C3C0C0C0BDBDBDB9B9B9B7B7B7BABABAC6C6C6D1D1D1D6D6D6
+ D9D9D9D4D4D4CCCCCCB2B2B29292928C8C8C8F8E8E878E8F908987C06850C040
+ 1FCB6547E3AB95E9BFABD8886CCC4C25BB56377C6257BCC1C2D1D1D1FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F4F19B765A7E4F2CAA8C75FE
+ FEFEFEFEFDB59B887C4E2D7C4F2C825635B79D8AF4F0EDFFFFFFFFFFFFF4F0ED
+ A18066987A65937664AC8F79F8F5F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9B1B2B1
+ FFFBFFD5DED86BC99650D69155D5955DD69958D5954ED4904ECD89B0D4BEFFF7
+ FDB5B5B5F0F0F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFF1DEDBC5614EB53822B93F29B93F29B83F29B83F2ABF3F
+ 28C53C23BC341CBC341EC23A22BF3720BB331EB62F1AB52C17B42C17B32B18B4
+ 2B18B42B18B32916B12D17B22D19B8685AC1C0C0C4C9CACBCACAD1D1D1CECECE
+ C7C7C7BDBDBDB6B6B6B6B6B6B6B6B6B9B9B9C0C0C0C2C2C2C5C5C5C8C8C8C8C8
+ C8CACACACBCBCBCBCBCBCBCBCBCCCCCCCCCCCCCCCCCCCCCCCCCDCDCDCDCDCDCC
+ CCCCCCCCCCCCCCCCCCCCCCCCCCCCCBCBCBCBCBCBC9C9C9C9C9C9C8C8C8C7C7C7
+ C5C5C5C3C3C3BFBFBFBCBCBCB8B8B8B2B2B2B0B0B0B5B5B5BFBFBFC7C7C7CACA
+ CAC8C8C8ABABAB9090908A89898F8F8FA9B0B2C9B5B0BF583FC45134E2AC99EC
+ C7B7D5765BC14B2A8F685A5F6466A4A6A6D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFB9A18E7F512DA17F67FAF9F8FFFFFFBBA08B
+ 7E4F2E7B4E2CAC8C76F7F4F2FFFFFFFFFFFFFFFFFFFFFFFFA28573714B34A586
+ 72F0EAE6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F3B3B4B4FFFFFFC6D8CE59C5
+ 8A4AD28B49CE8A3FCB8340C98243CC854ACB869CCBB0FFF7FCC7C6C7E5E5E5FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFEFDFDE3B8B1CE8175CA7466CA7365CB7365CD7365C27569B77E74C17D71B4
+ 5A4C9E3F2FA64739AD4C3EB65549BB5B4EBA5A4DB8594CB6594CB65649B8574C
+ BB6A5CB77E72B7A19CBDBEBFC2C2C3C3C3C2BABABAADADADACACACAFAFAFB4B4
+ B4B9B9B9BEBEBEC2C2C2C4C4C4C6C6C6C8C8C8C8C8C8C9C9C9CBCBCBCDCDCDCD
+ CDCDCDCDCDCECECECECECECECECECECECECFCFCFCFCFCFCECECECECECECECECE
+ CECECECECECECECECECDCDCDCBCBCBCBCBCBCBCBCBC9C9C9C7C7C7C6C6C6C4C4
+ C4C0C0C0BDBDBDB9B9B9B4B4B4AEAEAEA8A8A8AAAAAAB2B2B2BABABABCBCBCA7
+ A7A79B9B9BB1B1B1CBCDCECDD0D1C6A197BE4D34C95F46D0735CC85234AC6F5D
+ 8A8C8A6567689D9C9CD3D3D3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F0EEDED6D2
+ D3C9C3CDC4BEB4A3957E5D478F7161DED9D5FFFFFFD6C8BE865C3D7D4E2CBCA6
+ 97FFFFFFFFFFFFFFFFFFFFFFFFBBADA3744B30A48671EFE8E4FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFDDDDDDB8B9B9FFFFFFB9D3C356C38640C77F34BE7532
+ BC7330BA7030BB7059CB8B91C5A7FAF4F6D7D5D6D6D6D6FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC
+ F9F8F9F0EEF9EFEEF9EFEEFAEFEEF6F0EFF6F5F4E9E5E4ADACAB615C5A858080
+ AAA5A3C9C3C1D2CECCCECAC8CCC8C6CBC8C5CFCBC8CDC8C5BAB9B9B2B3B3B4B6
+ B7B2B3B3ABABABA3A3A3A2A2A2A8A8A8AFAFAFB5B5B5BCBCBCBEBEBEC2C2C2C4
+ C4C4C6C6C6C7C7C7C9C9C9C9C9C9CACACACCCCCCCDCDCDCECECECFCFCFCFCFCF
+ CFCFCFD0D0D0D0D0D0CFCFCFCFCFCFCFCFCFD0D0D0D0D0D0D0D0D0D0D0D0D0D0
+ D0CECECECDCDCDCCCCCCCBCBCBCACACAC8C8C8C6C6C6C4C4C4C2C2C2BEBEBEBD
+ BDBDB9B9B9B5B5B5AEAEAEA5A5A59D9D9D9E9E9EA7A7A7AFAFAFAEAEAEB0B0B0
+ C0C0BFD3D4D5CFD1D1C79E94BC5D48BC543DC98A7BB7B3B2989D9F6D6D6D8B8B
+ 8BCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFEFEFED5CCC6AC9B8F957B6986624C7E573F7A543A7E5B
+ 407A573F7B56408A6D59A18C7DA99488835F46804F2D89664FC4B7B0E3DDDAD0
+ C5BFA894888E6E59BEA896F5F2EFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB
+ EBEBA3A3A3E2E2E2FDF9FDABCFB973CE985FCB8C49C07C5FC88C6BCC947BD49E
+ 86D8A673B690ECEAEBDFDEDEC8C8C8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFF0F0EFA6ADAF5E6466969DA0C5CDCFD5DDDED4DC
+ DDD0D9DAD1D8DAD5DDDECCD4D5B0B8BAA2A8AAA4A8A8A0A1A19797979797979D
+ 9D9DA8A8A8B2B2B2B6B6B6BABABABDBDBDC0C0C0C3C3C3C5C5C5C7C7C7C9C9C9
+ C9C9C9CBCBCBCCCCCCCDCDCDCDCDCDCECECED0D0D0D1D1D1D1D1D1D1D1D1D1D1
+ D1D2D2D2D2D2D2D1D1D1D2D2D2D2D2D2D1D1D1D1D1D1D1D1D1CFCFCFCDCDCDCC
+ CCCCCBCBCBCBCBCBC9C9C9C7C7C7C5C5C5C3C3C3BFBFBFBDBDBDBBBBBBB8B8B8
+ B3B3B3ADADADA6A6A69B9B9B9191919393939C9C9C9999999A9A9AB4B2B2D0D3
+ D3D1D6D7CDC2BECCBBB5D2D3D3D3D8DAB0AFAF777878818181CDCDCDFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDED7
+ D3A08A7B825D447649297D4E2C7E4F2D7E4F2C80502D7F502D80512E7F512E7F
+ 502E7C4C2A714627754A2A7E4F2D7A4C2C7A5339957865A38876BCA697E0D4CB
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACABCBCBCF9F8F9
+ F4F1F28EC2A386D5A5A8E5BE89D5A683CF9F7AC99876C39463B4847EB093F4F1
+ F3E2E1E2C3C3C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFECECEC9E9D9C6D6C6CB5B4B4D6D5D5D3D2D2CFCECED0CFCFD5D4D4C3
+ C2C29F9E9E908F8F9190908F8E8E8B8B8B9393939F9F9FA7A7A7AFAFAFB3B3B3
+ B6B6B6BABABABEBEBEC0C0C0C3C3C3C5C5C5C7C7C7C9C9C9CBCBCBCCCCCCCDCD
+ CDCECECECFCFCFD0D0D0D2D2D2D2D2D2D1D1D1D3D3D3D2D2D2D3D3D3D3D3D3D3
+ D3D3D3D3D3D3D3D3D2D2D2D1D1D1D1D1D1D0D0D0CFCFCFCECECECDCDCDCBCBCB
+ C9C9C9C8C8C8C6C6C6C4C4C4C1C1C1BDBDBDBBBBBBB7B7B7B2B2B2AFAFAFACAC
+ ACA7A7A79B9B9B8B8B8B8585858A8A8A8B8B8B898989A5A5A5CCCCCCD3D7D8D2
+ D7D8D1D3D3D6D5D5C6C6C68C8C8C888888CECECEFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFBBFB0A7815E47774A29804F2D81
+ 512D7E4F2D7F5230946F52A78872B89F8CBFA7969476647B5D4CB59D8DC5AE9D
+ BFA897C3AE9EC8B5A6D0BEB1D7C9BFE6DED8FFFEFEFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB8B8B8C6C6C6F9FBFAF6F0F491B3A059A8
+ 7A7AB99482B9988CBC9F9DC4ADAECCBCC0D4CAE6E9E8FFFFFFE2E2E2C6C5C5FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBEBEB9E
+ 9E9E7B7B7BCBCBCBD8D8D8D0D0D0D2D2D2DADADABEBFBF8D8D8D818181828282
+ 7D7D7D8282829292929F9F9FA6A6A6A9A9A9AFAFAFB3B3B3B6B6B6BABABABFBF
+ BFC0C0C0C2C2C2C5C5C5C8C8C8CACACACBCBCBCDCDCDCECECED0D0D0D0D0D0D0
+ D0D0D2D2D2D2D2D2D2D2D2D3D3D3D4D4D4D4D4D4D4D4D4D4D4D4D2D2D2D2D2D2
+ D2D2D2D2D2D2D1D1D1D0D0D0CFCFCFCFCFCFCECECECCCCCCCACACAC7C7C7C5C5
+ C5C4C4C4C1C1C1BDBDBDBABABAB7B7B7B4B4B4AFAFAFAAAAAAA6A6A6A3A3A399
+ 99998A8A8A7A7A7A7A7A7A7C7C7C7676769C9B9BD1D1D1D4D3D3D0D0D0D3D3D3
+ D5D5D59E9E9E888888CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFEFDFDBCABA27950347E4F2D80512D7D4E2C875C3CAD907AD6C6BB
+ EBE4DEF6F2F0FEFEFDFFFFFFC6B4A7754D36CFC0B6FFFFFFFEFEFEFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFDFDFDACACACD7D8D7FFFFFFFDFBFDDFE0E0C2CEC8CCDCD3DCE6E1EA
+ F0ECFBFAFBFFFCFFFBFAFAF8F7F8ECECECBDBDBDE6E6E6FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEAA4A4A4929292D6D6D6
+ D6D6D6D1D1D1DBDBDBBCBCBC7F7F7F6C6C6C7171717171717F7F7F9090909B9B
+ 9BA2A2A2A7A7A7AAAAAAAEAEAEB3B3B3B7B7B7BBBBBBBFBFBFC1C1C1C4C4C4C6
+ C6C6C8C8C8CACACACCCCCCCDCDCDCECECECFCFCFD1D1D1D1D1D1D3D3D3D3D3D3
+ D3D3D3D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3D2D2
+ D2D1D1D1D0D0D0CFCFCFCECECECCCCCCCACACAC8C8C8C5C5C5C4C4C4C1C1C1BE
+ BEBEBABABAB7B7B7B4B4B4AFAFAFABABABA6A6A6A2A2A29D9D9D979797898989
+ 7474746C6C6C6A6A6A646464959595D0D0D0D2D2D2D2D2D2D6D6D6B5B5B58F8F
+ 8FD4D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCEC2BA
+ 7D53397F512E7E502E7E512FA5856DDED2C9F7F4F2FFFFFFFEFEFEFAF8F7F6F4
+ F2FCFBFAEBE4DF8F6546A58976FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7AA
+ AAAAE3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFEFBFDFAF9FAEEEDEDDDDCDDCCCCCC
+ C1C2C1CBCBCBD2D2D2EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFECECECB6B6B6B3B3B3DBDBDBD1D1D1D9D9D9C4C4
+ C47C7C7C5C5C5C6161616666667979798F8F8F9696969A9A9AA1A1A1A6A6A6A9
+ A9A9AFAFAFB3B3B3B7B7B7BABABABDBDBDC0C0C0C4C4C4C6C6C6C9C9C9CACACA
+ CCCCCCCDCDCDCECECED0D0D0D2D2D2D1D1D1D2D2D2D3D3D3D4D4D4D3D3D3D5D5
+ D5D5D5D5D5D5D5D5D5D5D5D5D5D3D3D3D3D3D3D3D3D3D3D3D3D1D1D1D0D0D0CF
+ CFCFCDCDCDCBCBCBC9C9C9C8C8C8C5C5C5C4C4C4C0C0C0BDBDBDBBBBBBB8B8B8
+ B4B4B4AEAEAEAAAAAAA6A6A6A2A2A29C9C9C9797979292928585856C6C6C5E5E
+ 5E5A5A5A606060A0A0A0D4D4D4D4D4D4D3D3D3D1D1D1A6A6A6D8D8D8FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDE9E68D6C567F502D7E502D7D4F
+ 2DB29783F3EFEBFFFFFFFEFEFEDCD4CFA9968A9279688B6F5BA08C7DD1C6BEA3
+ 8672946F55F7F4F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDB3B3B3E7E7E7E0E0E0
+ E5E5E5D9D9D9D1D1D1C1C1C1C9C9C9D2D2D2E5E5E5F7F7F7FBFBFBFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF1F1F1CDCDCDC7C7C7D7D7D7D8D8D8CACACA8989895B5B5B5454545C
+ 5C5C7474748989899090909595959A9A9AA1A1A1A7A7A7AAAAAAADADADB2B2B2
+ B6B6B6BABABABDBDBDC0C0C0C2C2C2C6C6C6C9C9C9CACACACBCBCBCECECECECE
+ CED0D0D0D0D0D0D2D2D2D3D3D3D3D3D3D4D4D4D3D3D3D4D4D4D3D3D3D4D4D4D4
+ D4D4D4D4D4D4D4D4D4D4D4D3D3D3D2D2D2D1D1D1D0D0D0CFCFCFCECECECCCCCC
+ CACACAC8C8C8C4C4C4C3C3C3C1C1C1BDBDBDBBBBBBB7B7B7B3B3B3AFAFAFABAB
+ ABA6A6A6A0A0A09B9B9B9696969090908B8B8B80808067676753535359595969
+ 6969AEAEAEDADADAD3D3D3D9D9D9CBCBCBDADADAFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFEFEFEC6B5AA794A2C7F502D7D4E2CA38169F4EFECFFFFFFFB
+ FAF9B4A2987B563D794B2B7B4D2B7C4D2C794B2A7D583F7A563F947055EEE8E4
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFDFDFDFCACACAF1F1F1ACACACDFDFDFE9E9E9F6F6
+ F6F9F9F9FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFF3F3F3C9
+ C9C9DEDEDED8D8D8D2D2D29A9A9A6060605353535757576D6D6D8282828B8B8B
+ 8F8F8F9494949C9C9CA1A1A1A6A6A6AAAAAAADADADB2B2B2B6B6B6BABABABDBD
+ BDC1C1C1C2C2C2C4C4C4C8C8C8C9C9C9CBCBCBCECECECECECED0D0D0D1D1D1D1
+ D1D1D3D3D3D4D4D4D4D4D4D5D5D5D5D5D5D4D4D4D5D5D5D5D5D5D4D4D4D4D4D4
+ D4D4D4D2D2D2D2D2D2D2D2D2D0D0D0CFCFCFCDCDCDCCCCCCCACACAC7C7C7C5C5
+ C5C3C3C3C0C0C0BCBCBCBABABAB7B7B7B2B2B2AEAEAEAAAAAAA5A5A5A0A0A09B
+ 9B9B9696969090908989898484847A7A7A6161615555555A5A5A767676C1C1C1
+ D9D9D9D7D7D7D8D8D8D9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5
+ F2F0A88D7A7C4E2C7D4E2C8E6648DDD1C7FFFFFFF9F8F6AF9A8D784D317F512D
+ 7F502D7E4F2D7E502D7F4F2D7D4E2C7B4C2B977258EBE3DEFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFCBCBCBE3E3E3EEEEEEB5B5B5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFF5F5F5C5C5C5E8E8E8DADADA
+ B0B0B06969695353535959596F6F6F7F7F7F8181818787878E8E8E9393939999
+ 999F9F9FA5A5A5A9A9A9ADADADB1B1B1B4B4B4B9B9B9BCBCBCC0C0C0C2C2C2C4
+ C4C4C7C7C7C9C9C9CACACACDCDCDCECECECFCFCFD1D1D1D1D1D1D2D2D2D3D3D3
+ D2D2D2D3D3D3D4D4D4D5D5D5D5D5D5D4D4D4D3D3D3D3D3D3D3D3D3D2D2D2D1D1
+ D1D0D0D0CFCFCFCECECECBCBCBCACACAC9C9C9C6C6C6C4C4C4C1C1C1BFBFBFBC
+ BCBCB8B8B8B5B5B5B1B1B1ACACACA9A9A9A4A4A49F9F9F9A9A9A9595958E8E8E
+ 8787878282828181817C7C7C626262575757565656909090D2D2D2DADADADCDC
+ DCDADADAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEAE69C7A617D4F2D
+ 7C4E2CB09580FDFCFCFFFFFFCBBDB37E52367F502D7E502D7C4E2C8F6649A98B
+ 75B195809873577F502D99745AF0EBE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCACACAE8
+ E8E8DADADAC9C9C9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFEFEFEFFFFFFF2F2F2CDCDCDE7E7E7C9C9C97E7E7E5555555959
+ 597171718383838282828181818787878D8D8D9393939797979E9E9EA3A3A3A8
+ A8A8ACACACB0B0B0B3B3B3B8B8B8BCBCBCBFBFBFC2C2C2C4C4C4C7C7C7C8C8C8
+ C9C9C9CBCBCBCDCDCDCFCFCFD0D0D0D0D0D0D2D2D2D3D3D3D2D2D2D3D3D3D4D4
+ D4D4D4D4D4D4D4D4D4D4D3D3D3D3D3D3D3D3D3D1D1D1D0D0D0CFCFCFCFCFCFCD
+ CDCDCCCCCCCACACAC7C7C7C5C5C5C3C3C3C1C1C1BDBDBDBBBBBBB8B8B8B5B5B5
+ B1B1B1ACACACA8A8A8A4A4A49F9F9F9898989494948E8E8E8888888282828383
+ 838585857F7F7F646464545454656565B4B4B4DEDEDEDFDFDFD5D5D5FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1ECE9A280677D4F2C7D4E2CC8B3A4FFFF
+ FFFEFEFDA98E7C7D4D2C7E4F2C7C4E2CA4846DE6DCD6FCFCFBFEFDFDECE5E096
+ 70559C795FFAF8F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6C1C1C1BCBCBCE9E9E9
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF1F1F1E8E8E8D6D6D6A8A8A85F5F5F5555556F6F6F85858587878785
+ 85858585858787878C8C8C9292929696969D9D9DA3A3A3A6A6A6AAAAAAAFAFAF
+ B3B3B3B7B7B7BBBBBBBEBEBEC1C1C1C3C3C3C6C6C6C7C7C7C9C9C9CBCBCBCCCC
+ CCCECECECFCFCFD0D0D0D1D1D1D0D0D0D1D1D1D3D3D3D3D3D3D1D1D1D3D3D3D3
+ D3D3D1D1D1D2D2D2D1D1D1D1D1D1D0D0D0CDCDCDCECECECDCDCDCACACAC8C8C8
+ C6C6C6C4C4C4C2C2C2C0C0C0BCBCBCBABABAB6B6B6B2B2B2AEAEAEABABABA7A7
+ A7A1A1A19E9E9E9999999393938D8D8D8888888686868787878787878A8A8A7C
+ 7C7C5E5E5E5454548F8F8FD5D5D5E1E1E1D0D0D0FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFF9F7F6B69C8A7E502D7B4C2CBBA596FFFFFFFCFBFAA889737D
+ 4E2C7C4D2B9B765BEDE6E1FFFFFFFFFFFFFFFFFFFAF9F8A58875B79D89FEFEFD
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9DCDCDCDEDEDEFDFDFDFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDED
+ EDEDC8C8C87C7C7C5050506666668585858B8B8B888888888888878787888888
+ 8B8B8B9292929696969B9B9BA1A1A1A6A6A6ABABABAEAEAEB2B2B2B6B6B6B9B9
+ B9BCBCBCBFBFBFC1C1C1C4C4C4C5C5C5C7C7C7CACACACBCBCBCCCCCCCCCCCCCF
+ CFCFCFCFCFD0D0D0D1D1D1D2D2D2D1D1D1D2D2D2D0D0D0D2D2D2D2D2D2D0D0D0
+ D0D0D0CFCFCFCECECECDCDCDCCCCCCCBCBCBC8C8C8C8C8C8C6C6C6C3C3C3C1C1
+ C1BDBDBDBABABAB8B8B8B5B5B5B2B2B2AEAEAEAAAAAAA5A5A5A1A1A19C9C9C96
+ 96969191918C8C8C8A8A8A8A8A8A8989898A8A8A8A8A8A8D8D8D767676585858
+ 646464BEBEBEDFDFDFCDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFDCD0C7865B3C7C4D2D977762F4F2F0FFFFFFB79C887D4E2C7C4E2CBCA697
+ FFFFFFFFFFFFFFFFFFFFFFFFCBBEB69C7D69E6DDD6FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEE9E9E9A9A9A9606060
+ 5959598181819090908C8C8C8C8C8C8C8C8C8B8B8B8C8C8C8C8C8C9090909494
+ 949B9B9BA0A0A0A3A3A3A9A9A9ACACACB0B0B0B4B4B4B7B7B7BBBBBBBDBDBDC0
+ C0C0C3C3C3C4C4C4C6C6C6C9C9C9C9C9C9CBCBCBCCCCCCCECECECFCFCFD0D0D0
+ D0D0D0D0D0D0D0D0D0D1D1D1D0D0D0D1D1D1D1D1D1CFCFCFCFCFCFCECECECDCD
+ CDCDCDCDCBCBCBC9C9C9C8C8C8C7C7C7C5C5C5C2C2C2BEBEBEBCBCBCB9B9B9B6
+ B6B6B3B3B3B0B0B0ADADADA9A9A9A4A4A49F9F9F9A9A9A9494949090908E8E8E
+ 8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8E8E8E8E8E8E6A6A6A5454549A9A9AD7D7
+ D7CDCDCDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFBFAC0A999
+ 80512F774A29AB988DFEFEFEEAE2DC9B755984532F927460D9D2CDF7F6F5E4E0
+ DCBCAFA69B7F6ED4C4B9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFBFBFBCACACAAEADADA09E9EAEADADD6D6D6FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFEEEEEEE6E6E68686865555557070709090909191
+ 918E8E8E8F8F8F8E8E8E8F8F8F8E8E8E8F8F8F8F8F8F9292929898989F9F9FA2
+ A2A2A6A6A6A9A9A9AEAEAEB2B2B2B6B6B6B8B8B8BBBBBBBFBFBFC0C0C0C2C2C2
+ C4C4C4C7C7C7C8C8C8CACACACBCBCBCCCCCCCCCCCCCDCDCDCECECECECECECFCF
+ CFCFCFCFCFCFCFCFCFCFCFCFCFCDCDCDCDCDCDCCCCCCCBCBCBCCCCCCCACACAC7
+ C7C7C7C7C7C3C3C3C1C1C1C0C0C0BEBEBEBBBBBBB8B8B8B4B4B4B1B1B1AEAEAE
+ AAAAAAA5A5A5A1A1A19E9E9E9898989393939090909090909191919191919191
+ 918F8F8F8F8F8F9090909595957F7F7F5F5F5F757575C5C5C5D8D8D8FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F5F3C1AA9A8E64457448
+ 2A9B8575D3C8C1B8A6987B563B7045277F5C4596806F9E8674A98F7ED8CBC2FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7E7E7777676282626
+ 0A09090100000A0909383535919191F2F2F2FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFEEEEEEDDDDDD6F6F6F58585889898997979791919191919192929292
+ 92929292929292929292929292929393939797979D9D9DA1A1A1A6A6A6A9A9A9
+ ABABABB0B0B0B4B4B4B8B8B8BABABABCBCBCBFBFBFC1C1C1C3C3C3C4C4C4C5C5
+ C5C7C7C7C9C9C9CBCBCBCBCBCBCCCCCCCCCCCCCCCCCCCCCCCCCDCDCDCDCDCDCD
+ CDCDCCCCCCCACACACACACACACACAC9C9C9C8C8C8C7C7C7C5C5C5C4C4C4C2C2C2
+ C0C0C0BEBEBEBCBCBCB9B9B9B6B6B6B2B2B2AFAFAFADADADA9A9A9A4A4A4A0A0
+ A09B9B9B96969694949493939393939393939394949493939392929292929293
+ 93939494949494946D6D6D616161B1B1B1E1E1E1FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDED2C9BA9F8C99775E957763A6
+ 908197806F9A7A62A6856EB29885CEBEB2F4F0EDFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFF0F0F0646363040000092014226B452986581A53
+ 36060B08090606838383F5F5F5FFFFFFF1F1F1B9B9B9A3A2A2C8C8C8FCFCFCFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEC8
+ C8C86565656E6E6E9898989A9A9A969696979797979797969696979797969696
+ 9797979797979696969696969A9A9A9F9F9FA3A3A3A6A6A6AAAAAAAFAFAFB2B2
+ B2B5B5B5B7B7B7BBBBBBBCBCBCBEBEBEC0C0C0C3C3C3C3C3C3C5C5C5C7C7C7C8
+ C8C8C9C9C9C9C9C9CACACACBCBCBCACACACCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
+ CBCBCBC9C9C9C7C7C7C6C6C6C4C4C4C4C4C4C1C1C1C0C0C0BEBEBEBBBBBBB8B8
+ B8B7B7B7B4B4B4B2B2B2ADADADAAAAAAA7A7A7A3A3A39F9F9F99999997979798
+ 98989898989898989999999797979898989898989898989898989999999D9D9D
+ 7F7F7F6363639D9D9DD9D9D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3EEEBE0D4CBDACDC5E2D8D2EEE8E4
+ F9F6F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFDFDFDA5A4A4090606153C283DC78043F59B47FFA33FE794339C670C201418
+ 1515C6C6C6D9D9D95E5C5E201D1D0F0C0C2C28288C8C8CFCFCFCFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDEDEDBABABA606060858585
+ 9E9E9E9C9C9C9B9B9B9B9B9B9A9A9A9A9A9A9B9B9B9B9B9B9A9A9A9B9B9B9A9A
+ 9A9999999A9A9A9D9D9DA0A0A0A3A3A3A7A7A7ACACACB0B0B0B3B3B3B6B6B6B9
+ B9B9BABABABDBDBDC0C0C0C3C3C3C4C4C4C6C6C6C8C8C8C9C9C9CACACACBCBCB
+ CDCDCDCFCFCFCECECECECECECECECECECECECFCFCFCFCFCFCDCDCDCCCCCCCBCB
+ CBCBCBCBC9C9C9C7C7C7C5C5C5C3C3C3C0C0C0BDBDBDB9B9B9B6B6B6B2B2B2AE
+ AEAEAAAAAAA7A7A7A4A4A4A0A0A09D9D9D9B9B9B9C9C9C9C9C9C9B9B9B9C9C9C
+ 9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9C9D9D9D9393936B6B6B9191
+ 91E3E3E3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE59575805
+ 0D082E986345FFA83CFE9B3BFA993EFF9E46FFA42B885B070A084A48493B393A
+ 0200001030201A513508110D181515B1B1B0FFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFEEEEEEB4B4B4656565939393A4A4A49C9C9C9D9D
+ 9D9D9D9D9D9D9D9E9E9E9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9D9C9C9C9C
+ 9C9C9F9F9FA1A1A1A5A5A5ACACACB1B1B1B6B6B6BABABABDBDBDC2C2C2C3C3C3
+ C5C5C5C7C7C7C9C9C9CACACACBCBCBCCCCCCCDCDCDCECECECFCFCFD0D0D0D0D0
+ D0D0D0D0CFCFCFD0D0D0D0D0D0CECECECECECECECECECECECECDCDCDCBCBCBCA
+ CACAC8C8C8C5C5C5C4C4C4C2C2C2BFBFBFBCBCBCBABABAB5B5B5AFAFAFA9A9A9
+ A4A4A49F9F9F9E9E9E9E9E9E9E9E9E9D9D9D9E9E9E9F9F9F9F9F9F9E9E9E9F9F
+ 9F9E9E9E9E9E9E9E9E9E9E9E9EA0A0A0A0A0A0717171868686E6E6E6FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2E1E12D2B2B0D2D1C40D88A3FFFA1
+ 39F59539F5953AF6953FFFA333BB7A0D2015030000020000205F3E3DD08A40E7
+ 97309562050C08575455FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF3F3F39C9C9C6A6A6A9F9F9FA7A7A7A1A1A1A2A2A2A1A1A1A2A2A2A2
+ A2A2A2A2A2A2A2A2A0A0A09F9F9FA1A1A1A2A2A2A2A2A2A4A4A4A7A7A7AAAAAA
+ B0B0B0B4B4B4B8B8B8BABABABDBDBDC1C1C1C3C3C3C5C5C5C6C6C6C8C8C8C9C9
+ C9CACACACBCBCBCCCCCCCDCDCDCCCCCCCECECECECECECFCFCFCECECECECECECE
+ CECECFCFCFCDCDCDCECECECCCCCCCBCBCBCBCBCBC9C9C9C8C8C8C7C7C7C5C5C5
+ C4C4C4C2C2C2C0C0C0BEBEBEBDBDBDBABABAB5B5B5B2B2B2B0B0B0AFAFAFADAD
+ ADAAAAAAA6A6A6A3A3A3A2A2A2A2A2A2A2A2A2A2A2A2A2A2A2A3A3A3A3A3A3A2
+ A2A2A2A2A2A3A3A3A6A6A67D7D7D7E7E7EE0E0E0FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFE6E5E53937370D281A3FCF863FFFA039F5953AF6963AF6
+ 963DFFA02FBB760C22160200001731243ED38941FFA83FFFA539D788071C133C
+ 3A3AEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F3F398
+ 9898727272A5A5A5A9A9A9A5A5A5A5A5A5A5A5A5A5A5A5A4A4A4A5A5A5A6A6A6
+ A6A6A6A8A8A8AAAAAAAFAFAFB4B4B4B4B4B4B5B5B5B5B5B5B6B6B6B7B7B7B9B9
+ B9BBBBBBBDBDBDC0C0C0C2C2C2C3C3C3C5C5C5C6C6C6C7C7C7CACACAC9C9C9C9
+ C9C9CBCBCBCBCBCBCECECECCCCCCCDCDCDCCCCCCCECECECDCDCDCDCDCDCDCDCD
+ CDCDCDCACACAC9C9C9C9C9C9C9C9C9C6C6C6C7C7C7C5C5C5C1C1C1C1C1C1BEBE
+ BEBCBCBCB9B9B9B8B8B8B8B8B8B7B7B7B8B8B8B9B9B9B8B8B8B6B6B6B6B6B6B5
+ B5B5AFAFAFACACACA7A7A7A6A6A6A5A5A5A7A7A7A6A6A6A6A6A6A6A6A6A7A7A7
+ A9A9A98B8B8B828282E0E0E0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFF5F5F56260600608062B8B5C43FFA539F7963AF5953AF5953EFF9F32B8750C
+ 20150402022D825640F99C3CFB9B3DFF9C36D484071B12454444F2F2F2E7E7E7
+ BDBDBDBBBBBBE4E4E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F49B9B9B808080ABABAB
+ AAAAAAA7A7A7A6A6A6A7A7A7A7A7A7A9A9A9ACACACAFAFAFB4B4B4B8B8B8B7B7
+ B7B9B9B9BABABABBBBBBBABABABABABAB9B9B9B8B8B8B8B8B8B9B9B9BBBBBBBD
+ BDBDC0C0C0C1C1C1C3C3C3C4C4C4C6C6C6C8C8C8C8C8C8C8C8C8CACACACBCBCB
+ CBCBCBCBCBCBCBCBCBCCCCCCCCCCCCCCCCCCCACACAC9C9C9C9C9C9C9C9C9C8C8
+ C8C8C8C8C7C7C7C6C6C6C4C4C4C2C2C2C1C1C1BFBFBFBDBDBDBBBBBBBABABABA
+ BABABBBBBBBABABABBBBBBBBBBBBBABABABBBBBBBBBBBBBBBBBBBBBBBBBABABA
+ B8B8B8B3B3B3AEAEAEABABABA8A8A8A8A8A8A9A9A9AAAAAAABABAB9191918484
+ 84DFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4F3F3F3B6B6B616
+ 1414122E203FCF883EFF9F39F69639F5943FFFA039B777111E17070D0B35BB77
+ 3EFF9F3BFB993FFFA235B071050F0A302E2E6B6B6B2F2D2D1714141714142C29
+ 29838383EBEBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFF5F5F5A1A1A1848484AEAEAEADADADAAAAAAACAC
+ ACAEAEAEB2B2B2B8B8B8BBBBBBBCBCBCBCBCBCBDBDBDBCBCBCBCBCBCBBBBBBBB
+ BBBBBBBBBBBBBBBBBCBCBCBCBCBCBCBCBCBBBBBBBBBBBBBCBCBCBFBFBFC0C0C0
+ C2C2C2C3C3C3C4C4C4C5C5C5C6C6C6C6C6C6C9C9C9C9C9C9C9C9C9CACACACBCB
+ CBCBCBCBCBCBCBCACACAC8C8C8C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7C5C5C5C4
+ C4C4C3C3C3C1C1C1C0C0C0BEBEBEBEBEBEBDBDBDBDBDBDBEBEBEBEBEBEBEBEBE
+ BEBEBEBDBDBDBEBEBEBDBDBDBDBDBDBEBEBEBDBDBDBEBEBEBEBEBEBDBDBDBDBD
+ BDBBBBBBB6B6B6B0B0B0ACACACACACACADADAD909090898989E1E1E1FFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFE9E9E9A3A3A26F706D6566637374712626250200001F5339
+ 3FE08E3FFF9E3AF7953FFFA03AA97210120F162B2139D4853DFF9E3DFF9F3EEA
+ 9321543B0402020704040503020B251720593E184D3408180F0B0707646464EF
+ EFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFF2F2F2ADADAD8C8C8CB0B0B0B4B4B4B6B6B6BBBBBBBEBEBEC1C1C1C1
+ C1C1C2C2C2C0C0C0C0C0C0BFBFBFC0C0C0C0C0C0BFBFBFBFBFBFC0C0C0C0C0C0
+ BFBFBFC1C1C1C0C0C0BFBFBFBFBFBFBFBFBFBFBFBFC1C1C1C2C2C2C2C2C2C3C3
+ C3C4C4C4C5C5C5C6C6C6C7C7C7C7C7C7C8C8C8C8C8C8C9C9C9C9C9C9C9C9C9C8
+ C8C8C7C7C7C7C7C7C8C8C8C6C6C6C6C6C6C6C6C6C4C4C4C3C3C3C3C3C3C1C1C1
+ C1C1C1C1C1C1C2C2C2C1C1C1C2C2C2C2C2C2C2C2C2C1C1C1C2C2C2C2C2C2C2C2
+ C2C1C1C1C1C1C1C1C1C1C2C2C2C1C1C1C2C2C2C1C1C1C3C3C3C2C2C2C2C2C2C2
+ C2C2BFBFBFB7B7B7B2B2B2939393999999E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECEC
+ 6565650C0C0706060605060B0B0B0A090B0504010005030325634341EF973EFF
+ 9F3FFF9E3292620C09092152383FE7923FFFA342F79C3083590906060200000A
+ 0B0A266A483DD48745F6A044F49B3AB8791436230300009D9D9DFDFDFDFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5B3
+ B3B3909090B1B1B1BEBEBEC4C4C4C6C6C6C5C5C5C4C4C4C4C4C4C4C4C4C5C5C5
+ C4C4C4C4C4C4C4C4C4C4C4C4C3C3C3C4C4C4C4C4C4C5C5C5C4C4C4C4C4C4C4C4
+ C4C5C5C5C4C4C4C5C5C5C4C4C4C3C3C3C3C3C3C3C3C3C4C4C4C4C4C4C5C5C5C5
+ C5C5C6C6C6C6C6C6C7C7C7C6C6C6C8C8C8C8C8C8C8C8C8C7C7C7C6C6C6C6C6C6
+ C7C7C7C6C6C6C6C6C6C6C6C6C4C4C4C5C5C5C5C5C5C4C4C4C5C5C5C5C5C5C4C4
+ C4C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4C4C4C4C4C4C4C4C4C5C5C5C5C5C5C4
+ C4C4C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4C4C4C5C5C5C5C5C5C7C7C7BFBFBF
+ B5B5B5929292A5A5A5ECECECFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9B9B9B10110E0D0729210E
+ 7328128B230F751D1344090A090300000A090930855B46F9A644FFAB28805406
+ 0505226B4740FCA045FFA836A06A0E17140100000E17122F895C42F2993EFF9E
+ 3AFD993BFF9B44FFA936AA7008140C484646E4E3E3FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAC7C7C7929292ABABAB
+ C1C1C1C8C8C8C8C8C8C8C8C8C8C8C8C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C8C8
+ C8C8C8C8C7C7C7C8C8C8C7C7C7C7C7C7C8C8C8C7C7C7C8C8C8C8C8C8C7C7C7C7
+ C7C7C7C7C7C7C7C7C7C7C7C7C7C7C8C8C8C7C7C7C7C7C7C7C7C7C8C8C8C8C8C8
+ C8C8C8C6C6C6C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C9C9C9C8C8
+ C8C8C8C8C9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C9C9C9C9C9C9C9C9C9C9C9C9C8
+ C8C8C9C9C9C9C9C9C8C8C8C8C8C8C8C8C8C9C9C9C8C8C8C7C7C7C9C9C9C8C8C8
+ C8C8C8C8C8C8C9C9C9C8C8C8C8C8C8C8C8C8CACACAC0C0C0B8B8B8888888B2B2
+ B2F5F5F5FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFEFEFE6566640205012918872B07E52401E62604E32F
+ 10D02718710B0D130000000F1914349A693DC7861444270000001D4D313ECE88
+ 36A9710E1F1700000015291E349A6843F9A03CFF9C3AF69639F59539F6943DFF
+ 9E45EE9817452D1B1919D5D4D4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFDFDFDD9D9D9939393A6A6A6C5C5C5C9C9C9CCCC
+ CCCACACACACACAC9C9C9CACACAC9C9C9CACACACACACACACACACACACACACACACA
+ CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA
+ CACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACACA
+ CACACACACACACACACACACACACACDCDCDCDCDCDCCCCCCCCCCCCCCCCCCCCCCCCCC
+ CCCCCDCDCDCCCCCCCDCDCDCDCDCDCCCCCCCDCDCDCCCCCCCBCBCBCDCDCDCDCDCD
+ CDCDCDCCCCCCCDCDCDCCCCCCCDCDCDCDCDCDCDCDCDCDCDCDCCCCCCCCCCCCCCCC
+ CCCDCDCDCDCDCDCBCBCBCCCCCCC1C1C1BBBBBB8C8C8CC6C6C6FBFBFBFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFF7E7F7D0205001D10592E0DD42400EF2200E12200E72C0ADF27167D
+ 0B0B170100000B0D0B101A131524231B3E3E14252216271A0D1611030101193B
+ 283AB97843FFA43DFD9C39F4943AF5963AF69639F5953BFF9A47F89F194F3514
+ 1212D3D2D2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFE5E5E59F9F9FA9A9A9C5C5C5CBCBCBD0D0D0CECECECECECECD
+ CDCDCECECECDCDCDCECECECECECECECECECECECECDCDCDCECECECECECECECECE
+ CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE
+ CECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECECE
+ CECECFCFCFD0D0D0D0D0D0D0D0D0CFCFCFCFCFCFD0D0D0D0D0D0D0D0D0CFCFCF
+ D0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFD0D0D0D0D0D0D0D0D0CFCFCFD0D0
+ D0CFCFCFD0D0D0D0D0D0D0D0D0D0D0D0D0D0D0CFCFCFCFCFCFD0D0D0D0D0D0CF
+ CFCFCCCCCCC3C3C3B3B3B3A2A2A2DFDFDFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC
+ 32322F05050422136B2D0FBF2A08DF2604EA2400EF2906E22816890B08130603
+ 03224F523EB5B648DBDB3AADAF193D410301011B3D2C3FD08841FFA73DFF9E3B
+ F9973AF7963AF69539F59539F79541FFA73DC9840F2719343232DDDCDCFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
+ F0F0BEBEBEA8A8A8BEBEBECDCDCDD3D3D3D3D3D3D2D2D2D1D1D1D2D2D2D1D1D1
+ D2D2D2D2D2D2D1D1D1D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1D1D1D1D1D1
+ D1D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D1D1D1D2D2D2D2D2D2D2
+ D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2D2
+ D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D2D2
+ D2D3D3D3D2D2D2D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3
+ D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D4D4D4CCCCCCC3C3C3
+ A2A2A2BABABAF3F3F3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB2B2B21E201C0406
+ 0218123E25157C28129F290EAE2E10D72E13AE0F0A1A194C4346E1E245FFFF41
+ FFFF44FFFF43D5D51A32361C442C42E6943CF4993DF69943FF9F45FFA345FFA5
+ 43FFA644FFA644E99C205F41030100767575F6F6F6FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD6D6D6A1A1A1
+ B7B7B7CECECED3D3D3D6D6D6D4D4D4D4D4D4D4D4D4D5D5D5D4D4D4D4D4D4D5D5
+ D5D4D4D4D5D5D5D4D4D4D4D4D4D4D4D4D5D5D5D5D5D5D5D5D5D4D4D4D4D4D4D4
+ D4D4D4D4D4D4D4D4D4D4D4D4D4D4D5D5D5D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4
+ D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D6D6D6D6D6D6D5D5D5D5D5D5D5D5
+ D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D6D6D6D5
+ D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5
+ D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5D5CBCBCBC2C2C2A8A8A8CBCBCBF8F8
+ F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFF8FBFDD3E8EEEDF5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1
+ EEF3D4E7EEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFCDCDCD817F80201C1C0300000000000703030D
+ 0A0F1510291E165311073B0C0B0C319B9946FFFF40FDFF3EFBFC40FFFF49FFFF
+ 32878907100D1A4D321C5E3B2469452F855B36986736A26D35AA7133A06B205C
+ 3C0303022E2D2DD1D1D1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEAEAEAB5B5B5B7B7B7CBCBCBD3D3
+ D3D9D9D9D8D8D8D8D8D8D7D7D7D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8
+ D8D8D7D7D7D7D7D7D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8
+ D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8
+ D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D7
+ D7D7D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8
+ D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8D8
+ D8D8D8D8D8D8D8D2D2D2CBCBCBB8B8B8BCBCBCE8E8E8FDFDFDFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDEEF293CFDF93C8
+ D8ECF4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5E7ED70B4CD93C3D6
+ EBF4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
+ FAFABCBCBD322F2F0300000A110D0F1C161016140B0808010101000000000000
+ 0000000F0E0E37A3A343FFFF3EFCFD3EFBFC3FFDFE44FFFF359898080F100000
+ 000000000503030806060C090A0D0C0C0B0E0C0A0A090C0A0A474545BEBEBEFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF9F9F9D6D6D6BABABAC6C6C6D0D0D0D9D9D9DCDCDCDC
+ DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC
+ DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC
+ DCDCDCDCDCDCDCDCDCDCDDDDDDDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC
+ DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDDDDDDDCDCDCDCDCDC
+ DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDC
+ DCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDCDDDDDDDADADACF
+ CFCFC7C7C7BABABAD2D2D2F7F7F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFCCE5EC85DAE876D4E4CAE2EAFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFEFE9FCEDD2FA1C96DAFC7DFEDF2FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4B4B33F3D3E050504
+ 23644336B47536BD7B3AAD73308E5E216F47276A472A5D421931240403032973
+ 7547FBFC42FFFF40FFFF42FFFF48FEFE29656709140E0C23180F1C160E121108
+ 0606010000020000020000040000333132CECECEFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFEAEAEAC2C2C2BEBEBECECECED7D7D7DFDFDFDFDFDFDEDEDEDFDFDF
+ DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE
+ DEDEDEDEDEDEDEDEDEDEDFDFDFDFDFDFDFDFDFDFDFDFDEDEDEDEDEDEDEDEDEDE
+ DEDEDFDFDFDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDE
+ DEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDFDFDFDFDFDFDEDEDEDEDEDEDEDEDEDEDE
+ DEDFDFDFDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDF
+ DFDFDEDEDEDEDEDEDEDEDEDFDFDFDEDEDEDEDEDED7D7D7CFCFCFC2C2C2C5C5C5
+ E9E9E9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFCFE5EC86DBE881EDF7A8D8E4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF3F9FB6AC0DF31A6CD6FAEC4E6F0F5FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5856560401011D583A42E69444FFA842FF
+ A342FFA240FF9E3BF89940F29743E6973DC7841A492F0E1B1D34929346EAEB48
+ F9F943E5E52E8385080B0E1531243CC37F3ECE883BB0762C8F5C237B4E2A754E
+ 1E4431080B09151212656465DCDCDCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFB
+ DCDCDCC3C3C3CACACAD3D3D3DEDEDEE1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E1E1
+ E1E1E1E1E1E1E1E2E2E2E2E2E2E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1
+ E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1
+ E1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E2E2E2E2E2
+ E2E2E2E2E1E1E1E2E2E2E2E2E2E2E2E2E2E2E2E2E2E2E1E1E1E3E3E3E2E2E2E2
+ E2E2E2E2E2E2E2E2E1E1E1E1E1E1E1E1E1E2E2E2E1E1E1E1E1E1E2E2E2E2E2E2
+ E2E2E2E3E3E3E2E2E2DDDDDDD4D4D4CBCBCBC6C6C6DFDFDFFAFAFAFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7E8EF82D6E491FFFF
+ 8AD6E2EBF4F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECF5F6B3D7E0EEF6F8FFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFD6E8EFBBDAE2FBFDFDFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFCBE3EC45C0E635A5C978B1C6F1F7F9FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFF353333010202349E6845FFA43BFB993AF5943AF7963BFB993B
+ FB9B3DFF9D41FFA845F09D286747000000090F101D47492E6A6A1E4445090607
+ 060A070A130F2A765044E49644FFA93EFF9E3DFA9B42F39B3EDA9136AC721841
+ 2C0300005F5D5EEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4D5D5D5CACA
+ CAD3D3D3DADADAE1E1E1E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4
+ E4E4E5E5E5E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4
+ E4E4E4E4E4E4E4E4E4E4E4E4E4E4E4E3E3E3E4E4E4E4E4E4E4E4E4E4E4E4E4E4
+ E4E4E4E4E4E4E4E4E4E4E5E5E5E5E5E5E5E5E5E6E6E6E5E5E5E5E5E5E5E5E5E5
+ E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E6E6E6E5E5E5E5E5E5E5E5E5E5E5E5
+ E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E5E6E6E6E6E6E6E2E2
+ E2D9D9D9D0D0D0C5C5C5D3D3D3F4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFF1F7F994D0DE93FCFF85EFF79FD1DEFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFEFFFFA1D2DE6FC1D7E9F3F7FFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFBEDFE95EB7CFC2DEE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FCFC
+ 69C2DF37C0EB3EA1C1A3CBDAFDFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF48
+ 4647010100297C5142FB9E3BFE9C39F59539F59439F4943BFC9940FFA23ED487
+ 2661420C110D0501010B130F090B06070505030202205D3C389F6B1023190101
+ 011D493439C98141FFA63CFF9D3CFC9A3DFF9F41FFA13ED38817412C080505AB
+ AAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECECECD1D1D1D2D2D2D6D6D6DC
+ DCDCE5E5E5E8E8E8E6E6E6E5E5E5E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6
+ E6E6E6E7E7E7E6E6E6E6E6E6E6E6E6E7E7E7E7E7E7E6E6E6E6E6E6E6E6E6E6E6
+ E6E7E7E7E6E6E6E6E6E6E6E6E6E6E6E6E6E6E6E7E7E7E5E5E5E6E6E6E6E6E6E7
+ E7E7E6E6E6E8E8E8E8E8E8E7E7E7E7E7E7E7E7E7E8E8E8E7E7E7E7E7E7E7E7E7
+ E7E7E7E7E7E7E8E8E8E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E8E8E8E8E8E8E8E8
+ E8E7E7E7E8E8E8E8E8E8E7E7E7E7E7E7E8E8E8E4E4E4DADADAD7D7D7D2D2D2CF
+ CFCFE9E9E9FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFC7E2EA88E6F093FDFF7CD7E6C3DFE7FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFDFEDF271D2E771CEE4ECF5F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC4E2EC
+ 47BEDF78BDD3F4F9FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9BCEDF3AC4F03BB9
+ E063AEC8E1EEF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8988891B19190C2317
+ 3BC58042FFA53EFF9F3EFF9E40FFA343F7A039B0731A39290502020000001839
+ 2742BB7E2665450000000F1D1737C88045FFA935A16B0C0F0C0101011939283B
+ B97B43FDA33FFF9F3CFB9A3DFF9E46FFAE2C8B5E040101807E7FFAFAFAFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFDFDFDE8E8E8CDCDCDCBCBCBD9D9D9DFDFDFE7E7E7
+ E9E9E9E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E7E7E7E8E8E8E8E8
+ E8E7E7E7E7E7E7E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E7E7E7E8
+ E8E8E8E8E8E7E7E7E8E8E8E8E8E8E7E7E7E7E7E7E8E8E8E8E8E8E7E7E7EAEAEA
+ EAEAEAEAEAEAE9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9E9EAEAEAEAEAEAEAEA
+ EAE9E9E9EAEAEAE9E9E9E9E9E9EAEAEAEAEAEAEAEAEAEAEAEAE9E9E9E9E9E9EA
+ EAEAEAEAEAEAEAEAE8E8E8DFDFDFDBDBDBD6D6D6D2D2D2E7E7E7FDFDFDFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAFDFDA1D4E290
+ F6FB89F2FB7ECDDCE6F1F5FFFFFFFFFFFFFFFFFFFFFFFFF5F9FB8CCEDF6CE5F7
+ 71D0E2EBF6F7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC3E4EB4DC9EA41B1D0A0C8
+ D6FDFEFEFFFFFFFFFFFFFFFFFFFFFFFFC5E0EA42C1EA36C4F04CAFD1B5D5E3FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE6E6E6777676060202112F2034A2693EDE
+ 8E41E5943CCF842C7D54101F16030101020000162E2239C17F45EE9A21533A02
+ 01011E3B2E3DDB8B40FFA642F69C2D7E55090A0702010115281D32966441E493
+ 3FF39C3DF39A42E0931C5A3C0200009B9B9AFEFEFEFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFDFDFDE8E8E8CFCFCFD6D6D6DEDEDEE2E2E2E9E9E9ECECECEBEB
+ EBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEBEAEAEAEBEBEBEBEBEBEBEBEBEAEAEAEA
+ EAEAEAEAEAEBEBEBEAEAEAEAEAEAEBEBEBEAEAEAEAEAEAEAEAEAEBEBEBEAEAEA
+ EBEBEBEAEAEAEAEAEAEAEAEAEBEBEBEBEBEBEAEAEAEDEDEDECECECECECECECEC
+ ECECECECECECECECECECECECECECECECEDEDEDEDEDEDEBEBEBECECECEBEBEBEB
+ EBEBECECECEBEBEBEBEBEBEDEDEDEBEBEBECECECECECECECECECEBEBEBE8E8E8
+ E3E3E3DEDEDED8D8D8D0D0D0E5E5E5FDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FAFC91DBE793F8FD80E9F479C6D5
+ EFF6F8FFFFFFFFFFFFFFFFFFECF5F892D1E06DE1F370EAFD65CFE2D5EBEFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFA9DAE34BCFEF48CDED42A5C2AAD1DEF8FCFDFF
+ FFFFFFFFFFFFFFFFCFE5ED45C0E733C7F43CB6DE91CADCFEFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFEDEDED6867670B0808040805102E2018422E081A1204
+ 010103000003000014231A39B17746FFAF32C57C10291C02010126503B40E290
+ 3CFF9B3DFF9D42F299276847060303030000080A09153C2A19603D17603B143D
+ 280405043B3A3ADFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFEFEFEE9E9E9D0D0D0DADADAE3E3E3E7E7E7EAEAEAEDEDEDEEEEEEEDEDEDED
+ EDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEDEEEEEEEEEEEEEDEDEDEDEDEDEDEDED
+ EEEEEEEEEEEEEDEDEDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEDEDEDEDEDEDEDED
+ EDEEEEEEEDEDEDEEEEEEEEEEEEEFEFEFEEEEEEEFEFEFEEEEEEEEEEEEEFEFEFEE
+ EEEEEEEEEEEEEEEEEEEEEEEFEFEFEEEEEEEEEEEEEEEEEEEFEFEFEFEFEFEFEFEF
+ EEEEEEEEEEEEEFEFEFEEEEEEEFEFEFEEEEEEE9E9E9E4E4E4E2E2E2D8D8D8D2D2
+ D2E7E7E7FEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFF2FBFC96E3EC95F8FD7FE9F566C1D1C4DFE8FFFFFFFBFD
+ FEDFF0F588CDDF6EE3F473EEFE6BE7FA5FD2E7A7D2E0FDFEFEFFFFFFFFFFFFFF
+ FFFFF3F9FA82C9DF4DD4F54EDBFB42C5E4399EBE96C6D7E9F4F7FDFEFEFBFDFE
+ 9FCEDF3DC3ED32C6F437BDE886CBE0FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFF3F3F39A9A9A424041211E1E221E1E2B28282625250502020F1914
+ 36A36C43FFA341FFA53AB77813241A010000265D4140EB943CFF9B39F5953FFF
+ 9F41DF8F1F47330200000A06071B1717171313130F0F181515403D3EC7C7C7FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEE
+ EEEED7D7D7D9D9D9E3E3E3E8E8E8ECECECF0F0F0F1F1F1F1F1F1EFEFEFF0F0F0
+ F0F0F0F0F0F0F0F0F0F0F0F0EFEFEFF0F0F0F0F0F0F0F0F0EFEFEFEFEFEFF0F0
+ F0EFEFEFF0F0F0F0F0F0F0F0F0F0F0F0EFEFEFF0F0F0F0F0F0EFEFEFF0F0F0F0
+ F0F0F1F1F1F1F1F1F0F0F0F1F1F1F0F0F0F0F0F0F1F1F1F1F1F1F0F0F0F1F1F1
+ F1F1F1F1F1F1F1F1F1F1F1F1F1F1F1F0F0F0F0F0F0F1F1F1F1F1F1F0F0F0F2F2
+ F2F2F2F2EFEFEFEBEBEBE9E9E9E2E2E2D5D5D5D1D1D1ECECECFEFEFEFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFF3FBFC9BE3EC9CF8FD83EFF96AD7E579C8DAAFDAE59DD5E376D2E575E9FA73
+ EFFB6EDAE96BDEF264DCF276C7D6EDF5F8FFFFFFFFFFFFFFFFFFCEE7EE5AC7E3
+ 4CD6F656CDE95AD8ED43C9E735AACC5DB3CE99CDDE95CDE04ABDE135C5F132C3
+ F234BFEA85CEE4FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FCFCFCECECECCCCCCCCCCCCCD4D4D45351510509062C875B43FA9F3CFE9E3EFF
+ 9F3198650E100F0200001F5F3E3CED943BFF9B39F4943AF89640FFA337B97A07
+ 150F1D1A1B8C8C8CACACACA09F9FB3B2B2E7E7E7FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F4F4DADADA
+ D7D7D7E1E1E1E9E9E9EEEEEEF0F0F0F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2
+ F2F2F2F2F1F1F1F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F2F1F1F1F2F2F2F2
+ F2F2F1F1F1F2F2F2F1F1F1F2F2F2F2F2F2F1F1F1F2F2F2F2F2F2F3F3F3F3F3F3
+ F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3F3
+ F3F3F3F3F3F3F3F2F2F2F2F2F2F3F3F3F3F3F3F2F2F2F2F2F2F1F1F1EDEDEDE7
+ E7E7DFDFDFD0D0D0DADADAF4F4F4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6FBFCA5DDE5B3
+ FAFC95F4FD82EFFB7CEBFA7CE9F77AE9F87DF2FD77F2FC67CBE48DB7D378C7DE
+ 6EEAFA5DD3E595CDDBD6DFEDE0E1F1CDDDEB7ACDE050DAF74AD3F176B6D482B6
+ D45CDAF04EDDF63AC4EB39BFE938C2EE34C4F031C0EF31C3F238C2E99CD3E4FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFD9D9D91E1C1C10362441E3913DFF9D3BFC9941FF9E23754C02010103
+ 01011B623D39EF933CFF9C39F4943AF5953CFB9D40F49C256D47090606989898
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFBFBE4E4E4D5D5D5D9D9
+ D9E9E9E9EFEFEFF1F1F1F3F3F3F3F3F3F4F4F4F5F5F5F5F5F5F4F4F4F5F5F5F4
+ F4F4F5F5F5F5F5F5F4F4F4F4F4F4F4F4F4F5F5F5F4F4F4F5F5F5F4F4F4F5F5F5
+ F5F5F5F4F4F4F4F4F4F5F5F5F5F5F5F4F4F4F5F5F5F5F5F5F5F5F5F5F5F5F6F6
+ F6F6F6F6F5F5F5F5F5F5F5F5F5F4F4F4F5F5F5F6F6F6F5F5F5F5F5F5F5F5F5F5
+ F5F5F5F5F5F4F4F4F4F4F4F3F3F3F2F2F2EAEAEAE3E3E3D5D5D5CFCFCFE1E1E1
+ FBFBFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FAFD97B3D9B0EBF3CDFFFFB2F9FD
+ 9FF7FE97FAFF90FAFE7CEDF561BCE26085D2767BCF70AAD97AECF766E3F755CC
+ E35EADD165A1D056B7DC50D6F24FDDF947C8E8698FD2787BD0639DDC6AD7EF5F
+ E7F74DDCF840D0F63BC9F339CAF236D0F43BA9DEAFC2E1FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA3A2A207
+ 05051A593B40FF9D3AF9963DFF9F3FE491204F36010000040101216E463AF295
+ 3CFF9B3AF5963AF5963BF99844FFA236A66D030002726F70FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F5F5DDDDDDD6D6D6E1E1E1EB
+ EBEBF3F3F3F6F6F6F5F5F5F5F5F5F7F7F7F6F6F6F6F6F6F6F6F6F7F7F7F7F7F7
+ F6F6F6F6F6F6F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6F6F6F6F6F6F6F7F7F7F6F6
+ F6F7F7F7F7F7F7F7F7F7F7F7F7F7F7F7F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6F6
+ F6F6F6F6F6F6F6F6F7F7F7F6F6F6F7F7F7F7F7F7F6F6F6F6F6F6F5F5F5F4F4F4
+ F5F5F5EFEFEFE4E4E4D8D8D8CDCDCDD9D9D9F4F4F4FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFEFEFFA555FCF5D8CDFC0EEF7D7FFFCC7FFFDA8F3F886D7
+ EF60A1DD5B74DA6F79E3818AE9799CE183DDEF84F3FD65E0F857DFF656E1F755
+ DDF752DBF74BD9F357B5E27E94E38089EA6875E15F84DC6AB9E76DDEF263E4F5
+ 5BE3F650DEF33AB7E82057CF8585D9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F9F9F0503031D634140FFA3
+ 3CFF9E44FFA834A56C0C120E020001020000246A463EF89A3CFF9D39F49539F4
+ 953CF99942FFA23295630200016B696AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFDFDEDEDEDD8D8D8D6D6D6E2E2E2EFEFEF
+ F7F7F7FBFBFBF9F9F9F7F7F7F8F8F8F9F9F9F9F9F9F9F9F9F8F8F8F8F8F8F9F9
+ F9F9F9F9F9F9F9F9F9F9F8F8F8F8F8F8F8F8F8F9F9F9F9F9F9F8F8F8F9F9F9F9
+ F9F9F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F9F9F9F9F9F9F9F9F9F8F8F8
+ F9F9F9F8F8F8F9F9F9F9F9F9F8F8F8F8F8F8F8F8F8F3F3F3E8E8E8D7D7D7CACA
+ CAD3D3D3EBEBEBFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFF4F5FB696ED2192CD14A70D577A0DE78A5E05D8DD64C6DD34E5CD75F69DC69
+ 78DD7282DF7887DE73A7DC8EE6F394F7FF7CECFD6AE4F95FE0FA50DAF74DBAE1
+ 6C93D87D88DF6F81DE6574DC5963DA4B5ED54978D55093DA4E9CDD418DD82A53
+ D21E27CD969ADEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFBCBCBC0C0A0A113D2842E59545FFA73CC3801437
+ 26070505575757282525102C1E3BCB8342FFA63DFF9D3BFF9A40FFA642E59519
+ 48300603038F8F8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEEDEDEDDBDBDBD8D8D8DBDBDBE8E8E8F5F5
+ F5FDFDFDFDFDFDFAFAFAF8F8F8F9F9F9F9F9F9F9F9F9FAFAFAFAFAFAFAFAFAFA
+ FAFAF9F9F9F9F9F9F9F9F9FAFAFAFAFAFAF9F9F9FAFAFAFAFAFAFAFAFAFAFAFA
+ FAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFBFBFBFAFAFAF9F9F9FAFAFAFBFB
+ FBFDFDFDFAFAFAEBEBEBDEDEDED2D2D2CACACAD4D4D4E9E9E9FDFDFDFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2D3ED8D
+ 90DD878BDD8C93DB9096DB9497DC9A9CDE9FA3DFA2A7DFA5AAE0A7ADE0ABAEE1
+ AAB0DEA2C7DF94DFE88BE7F178DFF063D6EB74C8DF9FBBDDADAEE0AAAFE0A6AC
+ DFA3A9E0A1A6DF9DA1DF999ADD9697DC9396DB9193DC8C8CDD9DA0DFE4E5F4FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFEEEEEE4A49490609061D573A267B501430210200005C5C5CE6E6E77B
+ 7A7A04000018473037B87745F29C45F49A3CCE852875500504043D3C3CDDDDDD
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFF1F1F1DDDDDDD7D7D7D6D6D6DCDCDCE8E8E8F5
+ F5F5FFFFFFFEFEFEFDFDFDFCFCFCFAFAFAFBFBFBFBFBFBFBFBFBFBFBFBFBFBFB
+ FBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFBFCFCFCFDFDFDFCFCFCFCFCFCFCFC
+ FCFCFCFCFCFCFCFCFCFCFEFEFEFFFFFFFFFFFFF9F9F9E9E9E9DBDBDBD0D0D0C7
+ C7C7CCCCCCD9D9D9EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDAEE
+ F3C3EAF2BCE8F3C0E6EFE7F2F6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF
+ C0BF3734350200000200000C08085E5E5DD9D9D9FFFFFFD7D7D74F4C4E020000
+ 0B22151E623F1F6641113020030102252324B4B4B4FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFAFAFAE7E7E7D8D8D8D5D5D5D2D2D2D3D3D3DEDEDE
+ ECECECFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7
+ F7F7E7E7E7DADADAD2D2D2C6C6C6C1C1C1CCCCCCD3D3D3DEDEDEF8F8F8FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF959495
+ 8C8A8BABAAABEBEBEBFFFFFFFFFFFFFFFFFFDDDDDD7D7B7C3331310908080908
+ 08201D1D605E5EC0C1C1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFF9F9F9EAEAEADEDEDEDBDBDBCFCFCFCDCDCDC8C8
+ C8CBCBCBD1D1D1D9D9D9DFDFDFECECECF3F3F3F0F0F0EFEFEFEFEFEFEFEFEFF2
+ F2F2E7E7E7D4D4D4CFCFCFC4C4C4C8C8C8BFBFBFB7B7B7B5B5B5B9B9B9C7C7C7
+ D7D7D7D6D6D6DFDFDFFAFAFAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFAFAFAD5D5D5B6B5B6B7B6B6C7C7C7EEEEEEFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F7F7E9E9E9E1E1E1D9D9D9DCDCDCCF
+ CFCFC1C1C1C3C3C3B9B9B9AAAAAAA8A8A8A4A4A4A6A6A6AAAAAAA3A3A3A6A6A6
+ B9B9B9B8B8B8C9C9C9D4D4D4D4D4D4D8D8D8E3E3E3FBFBFBFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFDFDFDF5F5F5F5F5F5F9F9F9FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFDFDFDFAFAFAF7F7F7F7F7F7EBEBEBDADADAD8D8D8
+ C8C8C8B8B8B8B6B6B6B3B3B3B4B4B4B7B7B7B3B3B3BDBDBDD7D7D7DADADAEAEA
+ EAF6F6F6F7F7F7F8F8F8FCFCFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFE1A68CD68561E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9
+ C75828C75828F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828E5B1
+ 9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6FBF4F1FFFF
+ FFFFFFFFFFFFFFFBF4F1F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF4DED4F0D2C6FBF4F1FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F4DED4FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F8E9E2FFFFFFFFFFFFFFFF
+ FFFFFFFFF0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1F0D2C6F0D2C6FB
+ F4F1FFFFFFFFFFFFFFFFFFF0D2C6F0D2C6FBF4F1FFFFFFFFFFFFF4DED4F0D2C6
+ F8E9E2FFFFFFFFFFFFFFFFFFF8E9E2F0D2C6F4DED4FFFFFFFFFFFFFFFFFFFBF4
+ F1F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFBF4F1F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFF4DED4
+ F0D2C6F8E9E2FFFFFFFFFFFFF8E9E2F0D2C6F4DED4FFFFFFFFFFFFFFFFFFF8E9
+ E2E5B19BE5B19BE5B19BE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9
+ BCA9E5B19BE5B19BE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFECC7B7E5B19BE5B19B
+ E9BCA9FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFF4DED4F0D2C6F8E9E2FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9C75828CB6336FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFF8E9E2F0D2C6F0D2C6FFFFFFFFFFFFFFFFFFFBF4F1F0D2C6
+ F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4E5B19BE5B1
+ 9BE9BCA9FBF4F1F4DED4F0D2C6F8E9E2FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828E1A68CFFFFFFFFFFFFFFFFFFE1
+ A68CC75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE6E45C75828
+ E1A68CFFFFFFFFFFFFFFFFFFE1A68CC75828CB6336FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFDD9B7EC75828D27953FFFFFFFFFFFFFFFFFFECC7B7C75828C7
+ 5828F4DED4FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828F0D2C6FFFFFFFFFFFF
+ FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFF
+ FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFF
+ FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFDD9B7EC75828C75828C75828C7
+ 5828C75828CB6336E9BCA9FFFFFFFFFFFFFFFFFFD27953C75828C75828C75828
+ C75828F0D2C6FFFFFFFBF4F1D27953C75828C75828C75828C75828CB6336F4DE
+ D4FFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFC75828C75828E9BCA9FFFFFFFFFFFFFFFFFFFFFFFF
+ E5B19BC75828C75828FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFE9BCA9C75828C75828C75828C75828CB6336CE
+ 6E45C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF4DED4C75828C75828CE6E45FFFFFFFFFFFFFFFFFFCE6E45C75828C75828
+ F4DED4FFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828CE6E45FFFFFFFFFF
+ FFFFFFFFCE6E45C75828C75828F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCB
+ 6336C75828C75828F8E9E2FFFFFFFFFFFFDD9B7EC75828C75828E5B19BFFFFFF
+ FFFFFFFFFFFFF0D2C6C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFC75828C758
+ 28F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC7
+ 5828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C758
+ 28FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC7
+ 5828D68561FFFFFFFFFFFFD68561CB6336E9BCA9FBF4F1FBF4F1E5B19BC75828
+ CB6336FBF4F1FFFFFFECC7B7C75828C75828E5B19BF0D2C6E5B19BF8E9E2FFFF
+ FFD68561C75828CB6336E9BCA9ECC7B7D27953C75828CB6336FBF4F1FFFFFFFF
+ FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ E9BCA9C75828C75828D27953FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828C758
+ 28FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFCB6336C75828D27953F0D2C6E5B19BCE6E45C75828C75828E5B19B
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828
+ C75828C75828F4DED4FFFFFFF4DED4C75828C75828C75828E5B19BFFFFFFFFFF
+ FFFFFFFFFFFFFFE5B19BC75828C75828C75828F4DED4FFFFFFF4DED4C75828C7
+ 5828C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828C75828
+ E5B19BFFFFFFFFFFFFCB6336C75828C75828DA9070FFFFFFFFFFFFFFFFFFF8E9
+ E2E5B19BE5B19BF8E9E2FFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFF
+ FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFF
+ FFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFF
+ FFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFF
+ FFFFFFE9BCA9FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFF
+ FFE5B19BC75828D27953FFFFFFFFFFFFFFFFFFFFFFFFF4DED4C75828C75828F0
+ D2C6FFFFFFFFFFFFFBF4F1CB6336C75828E5B19BFFFFFFFFFFFFD68561C75828
+ E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD27953C75828C758
+ 28C75828F0D2C6FFFFFFFFFFFFFFFFFFF0D2C6E5B19BE5B19BFFFFFFFFFFFFFF
+ FFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828
+ C75828F8E9E2FFFFFFFFFFFFFBF4F1D27953C75828E5B19BFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDA9070C75828D27953C75828E1A6
+ 8CFFFFFFE1A68CC75828D27953C75828DA9070FFFFFFFFFFFFFFFFFFFFFFFFDA
+ 9070C75828D27953C75828E1A68CFFFFFFE1A68CC75828D27953C75828DA9070
+ FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D27953C75828D27953FFFFFFECC7
+ B7C75828D27953C75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828
+ E5B19BFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFF0D2
+ C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561
+ C75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFBF4F1ECC7B7DA9070C75828C75828F4DED4FFFFFFE5B19BC75828D6
+ 8561FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828CE6E45FFFFFFFFFFFFFFFFFF
+ FFFFFFDD9B7EC75828DA9070FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828D68561C75828DD9B7EFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828
+ C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFF
+ FFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFCB6336C75828ECC7B7C75828CE6E45FFFFFFCE6E45C7
+ 5828ECC7B7C75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFCB6336C75828ECC7B7
+ C75828CE6E45FFFFFFCE6E45C75828ECC7B7C75828CB6336FFFFFFFFFFFFFFFF
+ FFFFFFFFDA9070C75828E5B19BD27953C75828F8E9E2DD9B7EC75828E5B19BCE
+ 6E45C75828F4DED4FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFF
+ FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FF
+ FFFFFFFFFFFFFFFFF0D2C6F0D2C6F0D2C6F0D2C6F0D2C6F0D2C6FFFFFFFFFFFF
+ F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFF
+ FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFE5B19BCE6E45C75828C7
+ 5828C75828C75828DD9B7EFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFF
+ FFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC758
+ 28D68561FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFDD9B7EC75828D68561F4DED4C75828C75828F8E9E2FFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD6
+ 8561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4
+ DED4C75828C75828FFFFFFDA9070C75828E9BCA9C75828CE6E45FFFFFFCB6336
+ C75828F4DED4FFFFFFFFFFFFF4DED4C75828C75828FFFFFFDA9070C75828E9BC
+ A9C75828CE6E45FFFFFFCB6336C75828F4DED4FFFFFFFFFFFFFFFFFFCB6336C7
+ 5828F0D2C6E5B19BC75828E5B19BCB6336C75828F8E9E2DA9070C75828E5B19B
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C758
+ 28F0D2C6FFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC7
+ 5828D68561FFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFF
+ C75828C75828C75828C75828C75828C75828FFFFFFFFFFFFF0D2C6C75828C758
+ 28FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC7
+ 5828D68561FFFFFFFFFFFFE5B19BC75828C75828CB6336D68561E5B19BF4DED4
+ FFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFE5B1
+ 9BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFF
+ FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF4F1C75828
+ C75828E9BCA9FFFFFFCE6E45C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19B
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D68561
+ FFFFFFE9BCA9C75828CB6336C75828E1A68CFFFFFFD68561C75828E5B19BFFFF
+ FFFFFFFFE5B19BC75828D68561FFFFFFE9BCA9C75828CB6336C75828E1A68CFF
+ FFFFD68561C75828E5B19BFFFFFFFFFFFFF4DED4C75828C75828FFFFFFF8E9E2
+ C75828CB6336C75828D27953FFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFF
+ FFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFF
+ FFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFE5B19BE5B19BE5B1
+ 9BE5B19BE5B19BE5B19BFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFF
+ FFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFE5B19BC75828D68561FFFFFF
+ FFFFFFD68561C75828D68561FBF4F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFECC7B7C75828C75828FB
+ F4F1FFFFFFFFFFFFFFFFFFD27953C75828E1A68CFFFFFFFFFFFFD68561C75828
+ E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828CB6336FFFFFFFFFF
+ FFE5B19BC75828CB6336FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828
+ C75828FFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561C75828E1A68CFFFFFFF8E9E2C758
+ 28C75828C75828F4DED4FFFFFFE5B19BC75828D68561FFFFFFFFFFFFD68561C7
+ 5828E1A68CFFFFFFF8E9E2C75828C75828C75828F4DED4FFFFFFE5B19BC75828
+ D68561FFFFFFFFFFFFE5B19BC75828D27953FFFFFFFFFFFFCE6E45C75828C758
+ 28E5B19BFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828
+ CE6E45F0D2C6FFFFFFFFFFFFD27953C75828CB6336E5B19BFFFFFFFFFFFFE1A6
+ 8CC75828CE6E45FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFF0D2C6C75828C75828E1A68CFBF4F1FFFFFFF4DED4C75828
+ C75828E9BCA9FFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFDA9070C758
+ 28DD9B7EFFFFFFFFFFFFFFFFFFF0D2C6E1A68CFFFFFFFFFFFFE5B19BC75828D6
+ 8561FFFFFFFFFFFFFFFFFFFFFFFFFBF4F1CB6336C75828DD9B7EFFFFFFFFFFFF
+ E9BCA9C75828C75828F0D2C6FFFFFFFFFFFFD68561C75828C75828E5B19BFBF4
+ F1FBF4F1F4DED4FFFFFFCE6E45C75828E1A68CFFFFFFFFFFFFFBF4F1C75828C7
+ 5828E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828
+ C75828D27953F0D2C6FFFFFFF4DED4FBF4F1F0D2C6C75828C75828FFFFFFFFFF
+ FFFFFFFFFFFFFFD68561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFC75828C75828ECC7B7FFFFFFFFFFFFD27953C75828CE6E45FF
+ FFFFFFFFFFECC7B7C75828C75828FFFFFFFFFFFFC75828C75828ECC7B7FFFFFF
+ FFFFFFD27953C75828CE6E45FFFFFFFFFFFFECC7B7C75828C75828FFFFFFFFFF
+ FFD68561C75828E1A68CFFFFFFFFFFFFE1A68CC75828C75828F8E9E2FFFFFFFB
+ F4F1C75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFD68561C75828C75828C75828D279
+ 53CE6E45C75828C75828CE6E45C75828CE6E45D27953C75828C75828E1A68CFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ F0D2C6C75828C75828C75828C75828D68561CB6336C75828CB6336FBF4F1FFFF
+ FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFECC7B7C75828C75828DA9070E5
+ B19BD27953C75828D68561FFFFFFE9BCA9CE6E45C75828CB6336D68561D68561
+ D68561F4DED4FFFFFFE9BCA9C75828C75828CE6E45D27953C75828C75828DD9B
+ 7EFFFFFFFFFFFFFFFFFFD68561C75828CB6336C75828C75828C75828D68561E9
+ BCA9C75828C75828F8E9E2FFFFFFFFFFFFFFFFFFDD9B7EC75828D27953FFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828CB6336C758
+ 28C75828C75828F0D2C6F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFD6
+ 8561C75828E5B19BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4DED4D6
+ 8561D68561F8E9E2FFFFFFFFFFFFE9BCA9D68561E5B19BFFFFFFFFFFFFF8E9E2
+ D68561D68561F4DED4F4DED4D68561D68561F8E9E2FFFFFFFFFFFFE9BCA9D685
+ 61E5B19BFFFFFFFFFFFFF8E9E2D68561D68561F4DED4FFFFFFD68561D68561EC
+ C7B7FFFFFFFFFFFFF4DED4D68561DD9B7EFFFFFFFFFFFFFFFFFFDA9070D68561
+ E9BCA9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD68561D685
+ 61F4DED4FFFFFFFFFFFFE1A68CD68561E5B19BDD9B7ECB6336C75828CB6336E5
+ B19BFBF4F1E1A68CCB6336C75828C75828DD9B7EFBF4F1FFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C758
+ 28ECC7B7D27953C75828C75828D27953F4DED4FFFFFFFFFFFFFFFFFFE9BCA9D6
+ 8561E1A68CFFFFFFFFFFFFFFFFFFECC7B7D27953C75828C75828C75828DA9070
+ ECC7B7FFFFFFE9BCA9CE6E45C75828CB6336D68561D68561D68561F4DED4FFFF
+ FFFFFFFFECC7B7D27953C75828C75828CE6E45E5B19BFFFFFFFFFFFFFFFFFFFF
+ FFFFE1A68CD68561E9BCA9E9BCA9DA9070D68561E1A68CE5B19BD68561DD9B7E
+ FFFFFFFFFFFFFFFFFFFFFFFFF0D2C6D68561D68561F8E9E2FFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFF4DED4D68561D68561F8E9E2E1A68CD68561D68561F4
+ DED4F4DED4D68561D68561FFFFFFFFFFFFFFFFFFFFFFFFE1A68CD68561E9BCA9
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFC75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFF0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5B19BC75828D6
+ 8561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFC75828C75828F0D2C6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ F0D2C6C75828C75828FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFE5B19BC75828D68561FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0D2C6E5B19BE9BCA9FFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8E9E2E5B19BE5B1
+ 9BFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}
+ WaterMark.Image.Alignment = iaCenter
+ WaterMark.Image.Layout = ilCenter
+ WaterMark.Width = 201
+ end
+ object Page2: TJvWizardInteriorPage
+ Header.Height = 50
+ Header.Title.Color = clNone
+ Header.Title.Text = #1052#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080
+ Header.Title.Anchors = [akLeft, akTop, akRight]
+ Header.Title.Font.Charset = DEFAULT_CHARSET
+ Header.Title.Font.Color = clWindowText
+ Header.Title.Font.Height = -16
+ Header.Title.Font.Name = 'Tahoma'
+ Header.Title.Font.Style = [fsBold]
+ Header.Subtitle.Color = clNone
+ Header.Subtitle.Text = #1042#1099#1073#1077#1088#1080#1090#1077' '#1082#1086#1085#1090#1072#1082#1090#1099', '#1080#1089#1090#1086#1088#1080#1102' '#1082#1086#1090#1086#1088#1099#1093' '#1042#1099' '#1093#1086#1090#1080#1090#1077' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1090#1100'.'
+ Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom]
+ Header.Subtitle.Font.Charset = DEFAULT_CHARSET
+ Header.Subtitle.Font.Color = clWindowText
+ Header.Subtitle.Font.Height = -11
+ Header.Subtitle.Font.Name = 'Tahoma'
+ Header.Subtitle.Font.Style = []
+ EnabledButtons = [bkBack, bkNext, bkFinish, bkCancel]
+ ExplicitWidth = 0
+ ExplicitHeight = 0
+ object CBSelectAll: TCheckBox
+ Left = 16
+ Top = 199
+ Width = 97
+ Height = 17
+ Caption = #1042#1099#1073#1088#1072#1090#1100' '#1074#1089#1077#1093
+ TabOrder = 0
+ OnClick = CBSelectAllClick
+ end
+ object ContactList: TListView
+ Left = 16
+ Top = 64
+ Width = 529
+ Height = 129
+ Checkboxes = True
+ Columns = <
+ item
+ AutoSize = True
+ Caption = #1053#1080#1082
+ end
+ item
+ Caption = #1055#1088#1086#1090#1086#1082#1086#1083
+ Width = 100
+ end
+ item
+ AutoSize = True
+ Caption = #1053#1086#1084#1077#1088
+ end>
+ ColumnClick = False
+ RowSelect = True
+ TabOrder = 1
+ ViewStyle = vsReport
+ OnChange = ContactListChange
+ OnChanging = ContactListChanging
+ end
+ end
+ object Page3: TJvWizardInteriorPage
+ Header.Height = 50
+ Header.Title.Color = clNone
+ Header.Title.Text = #1052#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080
+ Header.Title.Anchors = [akLeft, akTop, akRight]
+ Header.Title.Font.Charset = DEFAULT_CHARSET
+ Header.Title.Font.Color = clWindowText
+ Header.Title.Font.Height = -16
+ Header.Title.Font.Name = 'Tahoma'
+ Header.Title.Font.Style = [fsBold]
+ Header.Subtitle.Color = clNone
+ Header.Subtitle.Text = #1048#1076#1077#1090' '#1101#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080', '#1087#1086#1076#1086#1078#1076#1080#1090#1077'...'
+ Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom]
+ Header.Subtitle.Font.Charset = DEFAULT_CHARSET
+ Header.Subtitle.Font.Color = clWindowText
+ Header.Subtitle.Font.Height = -11
+ Header.Subtitle.Font.Name = 'Tahoma'
+ Header.Subtitle.Font.Style = []
+ EnabledButtons = [bkBack, bkNext, bkFinish, bkCancel]
+ OnPage = Page3Page
+ ExplicitWidth = 0
+ ExplicitHeight = 0
+ object LExportDesc: TLabel
+ Left = 16
+ Top = 77
+ Width = 82
+ Height = 13
+ Caption = #1042#1099#1073#1088#1072#1085#1086' 0 '#1080#1079' 10'
+ end
+ object LExportDesc2: TLabel
+ Left = 16
+ Top = 119
+ Width = 63
+ Height = 13
+ Caption = #1048#1085#1092#1086#1088#1084#1072#1094#1080#1103
+ end
+ object PBTotalExport: TProgressBar
+ Left = 16
+ Top = 96
+ Width = 529
+ Height = 17
+ TabOrder = 0
+ end
+ end
+ object Page4: TJvWizardInteriorPage
+ Header.Height = 50
+ Header.Title.Color = clNone
+ Header.Title.Text = #1052#1072#1089#1090#1077#1088' '#1101#1082#1089#1087#1086#1088#1090#1072' '#1080#1089#1090#1086#1088#1080#1080
+ Header.Title.Anchors = [akLeft, akTop, akRight]
+ Header.Title.Font.Charset = DEFAULT_CHARSET
+ Header.Title.Font.Color = clWindowText
+ Header.Title.Font.Height = -16
+ Header.Title.Font.Name = 'Tahoma'
+ Header.Title.Font.Style = [fsBold]
+ Header.Subtitle.Color = clNone
+ Header.Subtitle.Text = #1069#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080' '#1079#1072#1074#1077#1088#1096#1077#1085'.'
+ Header.Subtitle.Anchors = [akLeft, akTop, akRight, akBottom]
+ Header.Subtitle.Font.Charset = DEFAULT_CHARSET
+ Header.Subtitle.Font.Color = clWindowText
+ Header.Subtitle.Font.Height = -11
+ Header.Subtitle.Font.Name = 'Tahoma'
+ Header.Subtitle.Font.Style = []
+ EnabledButtons = [bkBack, bkFinish, bkCancel]
+ VisibleButtons = [bkFinish]
+ ExplicitWidth = 0
+ ExplicitHeight = 0
+ object LExportDone: TLabel
+ Left = 16
+ Top = 72
+ Width = 529
+ Height = 42
+ AutoSize = False
+ Caption =
+ #1069#1082#1089#1087#1086#1088#1090' '#1080#1089#1090#1086#1088#1080#1080' '#1079#1072#1074#1077#1088#1096#1077#1085'. '#1058#1077#1087#1077#1088#1100' '#1042#1099' '#1084#1086#1078#1077#1090#1077' '#1086#1090#1087#1088#1072#1074#1080#1090#1100' '#1079#1072#1087#1088#1086#1089' '#1085#1072' '#1089 +
+ #1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1102' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1085#1085#1086#1081' '#1080#1089#1090#1086#1088#1080#1080' '#1089' '#1073#1072#1079#1086#1081' '#1076#1072#1085#1085#1099#1093'. '#1055#1088#1080' '#1073#1086#1083#1100#1096#1086 +
+ #1084' '#1086#1073#1098#1105#1084#1077' '#1101#1082#1089#1087#1086#1088#1090#1080#1088#1086#1074#1072#1085#1085#1086#1081' '#1080#1089#1090#1086#1088#1080#1080' '#1087#1088#1086#1094#1077#1076#1091#1088#1072' '#1089#1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1080' '#1084#1086#1078#1077#1090' ' +
+ #1074#1099#1087#1086#1083#1085#1103#1090#1100#1089#1103' '#1079#1085#1072#1095#1080#1090#1077#1083#1100#1085#1086#1077' '#1074#1088#1077#1084#1103'.'
+ WordWrap = True
+ end
+ object CBSyncRequest: TCheckBox
+ Left = 16
+ Top = 120
+ Width = 529
+ Height = 17
+ Caption = #1054#1090#1087#1088#1072#1074#1080#1090#1100' '#1079#1072#1087#1088#1086#1089' '#1085#1072' '#1089#1080#1085#1093#1088#1086#1085#1080#1079#1072#1094#1080#1102
+ TabOrder = 0
+ end
+ end
+ end
+ object IMExportThread: TJvThread
+ Exclusive = True
+ MaxCount = 0
+ RunOnCreate = True
+ FreeOnTerminate = True
+ OnExecute = IMExportThreadExecute
+ Left = 264
+ Top = 216
+ end
+end
diff --git a/plugins/MirandaNGHistoryToDB/MsgExport.pas b/plugins/MirandaNGHistoryToDB/MsgExport.pas
new file mode 100644
index 0000000000..e36e3b1c8a
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/MsgExport.pas
@@ -0,0 +1,452 @@
+{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.5 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+unit MsgExport;
+
+interface
+
+uses
+ Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+ Dialogs, JvWizard, JvExControls, JvWizardRouteMapNodes, ComCtrls, StdCtrls,
+ JvComponentBase, JvThread, JclStringConversions, Global, Contacts, m_api;
+
+type
+ TContactRecord = record
+ hContact: Cardinal;
+ ContactID: AnsiString;
+ ContactName: AnsiString;
+ ProtoName: AnsiString;
+ Selected: Boolean;
+ end;
+ TExportForm = class(TForm)
+ IMExportWizard: TJvWizard;
+ Page1: TJvWizardWelcomePage;
+ Page2: TJvWizardInteriorPage;
+ Page3: TJvWizardInteriorPage;
+ Page4: TJvWizardInteriorPage;
+ LExportDesc: TLabel;
+ IMExportThread: TJvThread;
+ CBSelectAll: TCheckBox;
+ ContactList: TListView;
+ PBTotalExport: TProgressBar;
+ LExportDesc2: TLabel;
+ CBSyncRequest: TCheckBox;
+ LExportDone: TLabel;
+ procedure FormCreate(Sender: TObject);
+ procedure FormShow(Sender: TObject);
+ procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+ procedure FormClose(Sender: TObject; var Action: TCloseAction);
+ procedure Page3Page(Sender: TObject);
+ procedure IMExportWizardCancelButtonClick(Sender: TObject);
+ procedure IMExportWizardFinishButtonClick(Sender: TObject);
+ procedure IMExportThreadExecute(Sender: TObject; Params: Pointer);
+ procedure CBSelectAllClick(Sender: TObject);
+ procedure ContactListChanging(Sender: TObject; Item: TListItem; Change: TItemChange; var AllowChange: Boolean);
+ procedure ContactListChange(Sender: TObject; Item: TListItem; Change: TItemChange);
+ procedure BringFormToFront(Form: TForm);
+ function CheckStopExportAndExit: Boolean;
+ private
+ { Private declarations }
+ StartExport: Boolean;
+ //
+ procedure OnLanguageChanged(var Msg: TMessage); message WM_LANGUAGECHANGED;
+ procedure LoadLanguageStrings;
+ public
+ { Public declarations }
+ end;
+
+var
+ ExportForm: TExportForm;
+ ExportContactRecords: Array of TContactRecord;
+
+implementation
+
+{$R *.dfm}
+{$R icons.res}
+
+procedure TExportForm.FormCreate(Sender: TObject);
+begin
+ StartExport := False;
+ ExportFormDestroy := False;
+ //
+ ExportFormHandle := Handle;
+ SetWindowLong(Handle, GWL_HWNDPARENT, 0);
+ SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_APPWINDOW);
+ //
+ LoadLanguageStrings;
+end;
+
+procedure TExportForm.FormShow(Sender: TObject);
+var
+ ListItem: TListItem;
+ hContact: Cardinal;
+ ContactProto, ContactID, ContactName: AnsiString;
+ Count: Integer;
+begin
+ IMExportWizard.ActivePage := Page1;
+ StartExport := False;
+ //
+ hContact := CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ ContactList.Columns[0].MaxWidth := 190;
+ ContactList.Columns[1].MaxWidth := 90;
+ ContactList.Columns[2].MaxWidth := 140;
+ ContactList.Items.BeginUpdate;
+ Count := 0;
+ while hContact <> 0 do
+ begin
+ ContactProto := GetContactProto(hContact);
+ ContactID := GetContactID(hContact, ContactProto);
+ ContactName := GetContactDisplayName(hContact, '', True);
+ // .
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ if ContactName = '' then
+ ContactName := 'NoContactName';
+ if ContactID = '' then
+ ContactID := 'NoContactID';
+ SetLength(ExportContactRecords, Count + 1);
+ ExportContactRecords[Count].hContact := hContact;
+ ExportContactRecords[Count].ContactID := ContactID;
+ ExportContactRecords[Count].ContactName := ContactName;
+ ExportContactRecords[Count].ProtoName := ContactProto;
+ ExportContactRecords[Count].Selected := False;
+ Inc(Count);
+ ListItem := ContactList.Items.Add;
+ ListItem.Caption := ContactName;
+ ListItem.SubItems.Add(ContactProto);
+ ListItem.SubItems.Add(ContactID);
+ {if StrContactProtoToInt(ContactProto) = 15 then // 15 - Unknown Proto
+ ListItem.Checked := False
+ else
+ ListItem.Checked := True;}
+ hContact := CallService(MS_DB_CONTACT_FINDNEXT, hContact, 0);
+ end;
+ ContactList.Items.EndUpdate;
+end;
+
+procedure TExportForm.FormClose(Sender: TObject; var Action: TCloseAction);
+begin
+ ExportFormDestroy := True;
+ Action := caFree;
+end;
+
+procedure TExportForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
+begin
+ CanClose := CheckStopExportAndExit;
+end;
+
+procedure TExportForm.IMExportWizardCancelButtonClick(Sender: TObject);
+begin
+ Close;
+end;
+
+procedure TExportForm.IMExportWizardFinishButtonClick(Sender: TObject);
+begin
+ if IMExportWizard.ActivePage = Page4 then
+ begin
+ if CBSyncRequest.Checked then
+ OnSendMessageToAllComponent('002');
+ Close;
+ end;
+end;
+
+procedure TExportForm.Page3Page(Sender: TObject);
+begin
+ StartExport := True;
+ Page3.EnabledButtons := [bkCancel];
+ if not IMExportThread.Terminated then
+ begin
+ IMExportThread.Terminate;
+ while not (IMExportThread.Terminated) do
+ Sleep(1);
+ end;
+ IMExportThread.Execute(Self);
+end;
+
+procedure TExportForm.IMExportThreadExecute(Sender: TObject; Params: Pointer);
+var
+ I, J, K, ProtoType: Integer;
+ SelectedCount, BlobSize: Integer;
+ hDbEvent: Cardinal;
+ DBEventInfo: TDBEventInfo;
+ msgA: PAnsiChar;
+ msgW: PChar;
+ msgLen, LenW: Cardinal;
+ Msg_Date: TDateTime;
+ Msg_RcvrNick, Msg_RcvrAcc, Msg_SenderNick, Msg_SenderAcc, Msg_Text, MD5String: WideString;
+ Date_Str, MsgStatus: String;
+ ContactProto, ContactID, ContactName: AnsiString;
+ MyContactName, MyContactID: AnsiString;
+begin
+ LExportDesc2.Caption := 'Export...';
+ //
+ SelectedCount := 0;
+ for J := 0 to Length(ExportContactRecords) do
+ begin
+ if ExportContactRecords[J].Selected = True then
+ Inc(SelectedCount);
+ if IMExportThread.Terminated then //
+ Exit;
+ end;
+ LExportDesc.Caption := Format(GetLangStr('TotalSelect'), [IntToStr(SelectedCount), IntToStr(Length(ExportContactRecords))]);
+ //
+ PBTotalExport.Position := 0;
+ PBTotalExport.Max := SelectedCount;
+ SelectedCount := 0;
+ for I := 0 to Length(ExportContactRecords) do
+ begin
+ // ,
+ if ExportContactRecords[I].Selected = True then
+ begin
+ LExportDesc2.Caption := Format(GetLangStr('ContactExport'), [ExportContactRecords[I].ContactName, ExportContactRecords[I].ContactID]);
+ Inc(SelectedCount);
+ PBTotalExport.Position := SelectedCount;
+ if IMExportThread.Terminated then //
+ Exit;
+ hDbEvent := CallService(MS_DB_EVENT_FINDFIRST, ExportContactRecords[I].hContact, 0);
+ while hDbEvent <> 0 do
+ begin
+ ZeroMemory(@DBEventInfo, SizeOf(DBEventInfo));
+ DBEventInfo.cbSize := SizeOf(DBEventInfo);
+ DBEventInfo.pBlob := nil;
+ BlobSize := CallService(MS_DB_EVENT_GETBLOBSIZE, hDbEvent, 0);
+ GetMem(DBEventInfo.pBlob, BlobSize);
+ DBEventInfo.cbBlob := BlobSize;
+ if IMExportThread.Terminated then //
+ begin
+ if ImportLogOpened then
+ CloseLogFile(5);
+ Exit;
+ end;
+ if (CallService(MS_DB_EVENT_GET, hDbEvent, Integer(@DBEventInfo)) = 0) and (DBEventInfo.eventType = EVENTTYPE_MESSAGE and EVENTTYPE_URL) then
+ begin
+ //
+ msgA := PAnsiChar(DBEventInfo.pBlob);
+ msgW := nil;
+ msgLen := lstrlenA(PAnsiChar(DBEventInfo.pBlob)) + 1;
+ if msgLen > DBEventInfo.cbBlob then
+ msgLen := DBEventInfo.cbBlob;
+ if Boolean(DBEventInfo.flags and DBEF_UTF) then
+ begin
+ SetLength(Msg_Text, msgLen);
+ LenW := Utf8ToWideChar(PChar(Msg_Text), msgLen, msgA, msgLen - 1, CP_ACP);
+ if Integer(LenW) > 0 then
+ SetLength(Msg_Text, LenW - 1)
+ else
+ Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1);
+ end
+ else
+ begin
+ LenW := 0;
+ if DBEventInfo.cbBlob >= msgLen * SizeOf(Char) then
+ begin
+ msgW := PChar(msgA + msgLen);
+ for K := 0 to ((DBEventInfo.cbBlob - msgLen) div SizeOf(Char)) - 1 do
+ if msgW[K] = #0 then
+ begin
+ LenW := K;
+ Break;
+ end;
+ end;
+ if (LenW > 0) and (LenW < msgLen) then
+ SetString(Msg_Text, msgW, LenW)
+ else
+ Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1);
+ end;
+ //
+ ContactProto := GetContactProto(ExportContactRecords[I].hContact);
+ //
+ ContactID := GetContactID(ExportContactRecords[I].hContact, ContactProto);
+ ContactName := GetContactDisplayName(ExportContactRecords[I].hContact, '', True);
+ //
+ MyContactName := GetMyContactDisplayName(ContactProto);
+ MyContactID := GetMyContactID(ContactProto);
+ // .
+ if ContactProto = MyAccount then
+ ContactProto := 'ICQ';
+ //
+ ProtoType := StrContactProtoToInt(ContactProto);
+ if ContactID = '' then
+ ContactID := 'NoContactID';
+ if ContactName = '' then
+ ContactName := 'NoContactName';
+ if MyContactID = '' then
+ MyContactID := 'NoMyContactID';
+ if MyContactName = '' then
+ MyContactName := 'NoMyContactName';
+ // , ..
+ Msg_SenderNick := PrepareString(pWideChar(AnsiToWideString(MyContactName, CP_ACP)));
+ Msg_SenderAcc := PrepareString(pWideChar(AnsiToWideString(MyContactID, CP_ACP)));
+ Msg_SenderNick := WideStringToUTF8(Msg_SenderNick);
+ Msg_SenderAcc := WideStringToUTF8(Msg_SenderAcc);
+ Msg_RcvrNick := PrepareString(pWideChar(AnsiToWideString(ContactName, CP_ACP)));
+ Msg_RcvrAcc := PrepareString(pWideChar(AnsiToWideString(ContactID, CP_ACP)));
+ Msg_RcvrNick := WideStringToUTF8(Msg_RcvrNick);
+ Msg_RcvrAcc := WideStringToUTF8(Msg_RcvrAcc);
+ Msg_Text := WideStringToUTF8(PrepareString(pWideChar(Msg_Text)));
+ MD5String := Msg_RcvrAcc + FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + Msg_Text;
+ if (DBType = 'oracle') or (DBType = 'oracle-9i') then
+ Date_Str := FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp))
+ else
+ Date_Str := FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp));
+ if MatchStrings(LowerCase(ContactProto), 'skype*') then
+ begin
+ // ( )
+ if (DBEventInfo.flags and DBEF_SENT) = 0 then
+ MsgStatus := '0' //
+ else
+ MsgStatus := '1'; //
+ //
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2);
+ if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- CHAT_MSG_LOG_ORACLE
+ WriteInLog(ProfilePath, Format(CHAT_MSG_LOG_ORACLE, [DBUserName, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]), 5)
+ else
+ WriteInLog(ProfilePath, Format(CHAT_MSG_LOG, [DBUserName, MsgStatus, Date_Str, Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]), 5);
+ end
+ else
+ begin
+ // ( )
+ if (DBEventInfo.flags and DBEF_SENT) = 0 then
+ MsgStatus := '1' //
+ else
+ MsgStatus := '0'; //
+ //
+ if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2);
+ if (MatchStrings(DBType, 'oracle*')) then // Oracle, SQL- MSG_LOG_ORACLE
+ WriteInLog(ProfilePath, Format(MSG_LOG_ORACLE, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_Text, EncryptMD5(MD5String)]), 5)
+ else
+ WriteInLog(ProfilePath, Format(MSG_LOG, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, Date_Str, Msg_Text, EncryptMD5(MD5String)]), 5);
+ end;
+ end;
+ hDbEvent := CallService(MS_DB_EVENT_FINDNEXT, hDbEvent, 0);
+ end;
+ end;
+ if IMExportThread.Terminated then //
+ Exit;
+ end;
+ Page3.EnabledButtons := [bkCancel,bkNext];
+ StartExport := False;
+ if ImportLogOpened then
+ CloseLogFile(5);
+ LExportDesc2.Caption := GetLangStr('ExportDone');
+end;
+
+procedure TExportForm.BringFormToFront(Form: TForm);
+begin
+ if Form.WindowState = wsMaximized then
+ ShowWindow(Form.Handle, SW_SHOWMAXIMIZED)
+ else
+ ShowWindow(Form.Handle, SW_SHOWNORMAL);
+ Form.BringToFront;
+end;
+
+function TExportForm.CheckStopExportAndExit: Boolean;
+begin
+ if StartExport then
+ begin
+ case MessageBox(Handle, pWideChar(GetLangStr('ExportAbort')), pWideChar(htdPluginShortName + ' - ' +GetLangStr('ExportAbortCaption')),36) of
+ 6:
+ begin
+ if not IMExportThread.Terminated then
+ begin
+ IMExportThread.Terminate;
+ while not (IMExportThread.Terminated) do
+ begin
+ Sleep(1);
+ Forms.Application.ProcessMessages;
+ end;
+ end;
+ Result := True;
+ end;
+ 7:
+ begin
+ Result := False;
+ Exit;
+ end;
+ end;
+ end
+ else
+ Result := True;
+end;
+
+procedure TExportForm.ContactListChange(Sender: TObject; Item: TListItem; Change: TItemChange);
+begin
+ if Item.Checked <> ExportContactRecords[Item.Index].Selected then // Item.Checked
+ begin
+ ExportContactRecords[Item.Index].Selected := Item.Checked; //
+ { ....}
+ end;
+end;
+
+procedure TExportForm.ContactListChanging(Sender: TObject; Item: TListItem; Change: TItemChange; var AllowChange: Boolean);
+begin
+ ExportContactRecords[Item.Index].Selected := Item.Checked; // Item.Checked,
+ AllowChange := True; // :)
+end;
+
+procedure TExportForm.CBSelectAllClick(Sender: TObject);
+var
+ I: Integer;
+begin
+ for I := 0 to ContactList.Items.Count-1 do
+ begin
+ ContactList.Items[I].Checked := CBSelectAll.Checked;
+ ExportContactRecords[I].Selected := CBSelectAll.Checked;
+ end;
+ //LExportDesc.Caption := IntToStr(Length(ExportContactRecords)) + ' - ' + IntToStr(ContactList.Items.Count);
+end;
+
+//
+procedure TExportForm.OnLanguageChanged(var Msg: TMessage);
+begin
+ LoadLanguageStrings;
+end;
+
+//
+procedure TExportForm.LoadLanguageStrings;
+var
+ ExportBitmap: TBitmap;
+begin
+ Caption := htdPluginShortName + ' - ' + GetLangStr('ExortFormCaption');
+ IMExportWizard.ButtonBack.Caption := '< ' + GetLangStr('ButtonBack');
+ IMExportWizard.ButtonNext.Caption := GetLangStr('ButtonNext') + ' >';
+ IMExportWizard.ButtonFinish.Caption := GetLangStr('ButtonFinish');
+ IMExportWizard.ButtonCancel.Caption := GetLangStr('ButtonCancel');
+ IMExportWizard.Pages.Items[0].Title.Text := GetLangStr('IMExportWizardPage0Title');
+ IMExportWizard.Pages.Items[0].Subtitle.Text := Format(GetLangStr('IMExportWizardPage0SubTitle'), [htdIMClientName]);
+ IMExportWizard.Pages.Items[1].Title.Text := GetLangStr('IMExportWizardPage1Title');
+ IMExportWizard.Pages.Items[1].Subtitle.Text := GetLangStr('IMExportWizardPage1SubTitle');
+ IMExportWizard.Pages.Items[2].Title.Text := GetLangStr('IMExportWizardPage2Title');
+ IMExportWizard.Pages.Items[2].Subtitle.Text := GetLangStr('IMExportWizardPage2SubTitle');
+ IMExportWizard.Pages.Items[3].Title.Text := GetLangStr('IMExportWizardPage3Title');
+ IMExportWizard.Pages.Items[3].Subtitle.Text := GetLangStr('IMExportWizardPage3SubTitle');
+ CBSelectAll.Caption := GetLangStr('SelectAll');
+ ContactList.Columns[0].Caption := GetLangStr('NickName');
+ ContactList.Columns[1].Caption := GetLangStr('Protocol');
+ ContactList.Columns[2].Caption := GetLangStr('Number');
+ LExportDone.Caption := GetLangStr('ExportDoneDesc');
+ CBSyncRequest.Caption := GetLangStr('SendSyncRequest');
+ //
+ if IMExportWizard.ActivePage = Page1 then
+ begin
+ ExportBitmap := TBitmap.Create;
+ try
+ if DefaultLanguage = 'Russian' then
+ ExportBitmap.LoadFromResourceName(HInstance, 'Export_Ru')
+ else
+ ExportBitmap.LoadFromResourceName(HInstance, 'Export_En');
+ Page1.WaterMark.Image.Picture.Assign(ExportBitmap);
+ finally
+ ExportBitmap.Free;
+ end;
+ end;
+end;
+
+end.
diff --git a/plugins/MirandaNGHistoryToDB/copy_langs.bat b/plugins/MirandaNGHistoryToDB/copy_langs.bat
new file mode 100644
index 0000000000..b1487eba92
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/copy_langs.bat
@@ -0,0 +1,14 @@
+@echo off
+
+if not exist .\..\..\bin10\Release\Plugins\langs (
+ mkdir .\..\..\bin10\Release\Plugins\langs
+)
+
+if not exist .\..\..\bin10\Release64\Plugins\langs (
+ mkdir .\..\..\bin10\Release64\Plugins\langs
+)
+
+copy /Y langs\Russian.xml .\..\..\bin10\Release\Plugins\langs
+copy /Y langs\English.xml .\..\..\bin10\Release\Plugins\langs
+copy /Y langs\Russian.xml .\..\..\bin10\Release64\Plugins\langs
+copy /Y langs\English.xml .\..\..\bin10\Release64\Plugins\langs
diff --git a/plugins/MirandaNGHistoryToDB/icons.res b/plugins/MirandaNGHistoryToDB/icons.res
new file mode 100644
index 0000000000..88c819c734
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/icons.res
Binary files differ
diff --git a/plugins/MirandaNGHistoryToDB/jedi.inc b/plugins/MirandaNGHistoryToDB/jedi.inc
new file mode 100644
index 0000000000..c31a08c04a
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/jedi.inc
@@ -0,0 +1,1430 @@
+{$IFNDEF JEDI_INC}
+{$DEFINE JEDI_INC}
+
+{**************************************************************************************************}
+{ }
+{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License");}
+{ you may not use this file except in compliance with the License. You may obtain a copy of the }
+{ License at http://www.mozilla.org/MPL/ }
+{ }
+{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
+{ ANY KIND, either express or implied. See the License for the specific language governing rights }
+{ and limitations under the License. }
+{ }
+{ The Original Code is: jedi.inc. }
+{ The Initial Developer of the Original Code is Project JEDI http://www.delphi-jedi.org }
+{ }
+{ Alternatively, the contents of this file may be used under the terms of the GNU Lesser General }
+{ Public License (the "LGPL License"), in which case the provisions of the LGPL License are }
+{ applicable instead of those above. If you wish to allow use of your version of this file only }
+{ under the terms of the LGPL License and not to allow others to use your version of this file }
+{ under the MPL, indicate your decision by deleting the provisions above and replace them with }
+{ the notice and other provisions required by the LGPL License. If you do not delete the }
+{ provisions above, a recipient may use your version of this file under either the MPL or the }
+{ LGPL License. }
+{ }
+{ For more information about the LGPL: http://www.gnu.org/copyleft/lesser.html }
+{ }
+{**************************************************************************************************}
+{ }
+{ This file defines various generic compiler directives used in different libraries, e.g. in the }
+{ JEDI Code Library (JCL) and JEDI Visual Component Library Library (JVCL). The directives in }
+{ this file are of generic nature and consist mostly of mappings from the VERXXX directives }
+{ defined by Delphi, C++Builder and FPC to friendly names such as DELPHI5 and }
+{ SUPPORTS_WIDESTRING. These friendly names are subsequently used in the libraries to test for }
+{ compiler versions and/or whether the compiler supports certain features (such as widestrings or }
+{ 64 bit integers. The libraries provide an additional, library specific, include file. For the }
+{ JCL e.g. this is jcl.inc. These files should be included in source files instead of this file }
+{ (which is pulled in automatically). }
+{ }
+{**************************************************************************************************}
+{ }
+{ Last modified: $Date:: 2012-09-04 16:01:38 +0200 (út, 04 9 2012) $ }
+{ Revision: $Rev:: 161 $ }
+{ Author: $Author:: outchy $ }
+{ }
+{**************************************************************************************************}
+
+(*
+
+- Development environment directives
+
+ This file defines two directives to indicate which development environment the
+ library is being compiled with. Currently this can either be Delphi, Kylix,
+ C++Builder or FPC.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ DELPHI Defined if compiled with Delphi
+ KYLIX Defined if compiled with Kylix
+ DELPHICOMPILER Defined if compiled with Delphi or Kylix/Delphi
+ BCB Defined if compiled with C++Builder
+ CPPBUILDER Defined if compiled with C++Builder (alias for BCB)
+ BCBCOMPILER Defined if compiled with C++Builder or Kylix/C++
+ DELPHILANGUAGE Defined if compiled with Delphi, Kylix or C++Builder
+ BORLAND Defined if compiled with Delphi, Kylix or C++Builder
+ FPC Defined if compiled with FPC
+
+- Platform Directives
+
+ Platform directives are not all explicitly defined in this file, some are
+ defined by the compiler itself. They are listed here only for completeness.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ WIN32 Defined when target platform is 32 bit Windows
+ WIN64 Defined when target platform is 64 bit Windows
+ MSWINDOWS Defined when target platform is 32 bit Windows
+ LINUX Defined when target platform is Linux
+ UNIX Defined when target platform is Unix-like (including Linux)
+ CLR Defined when target platform is .NET
+
+- Architecture directives. These are auto-defined by FPC
+ CPU32 and CPU64 are mostly for generic pointer size dependant differences rather
+ than for a specific architecture.
+
+ CPU386 Defined when target platform is native x86 (win32)
+ CPUx86_64 Defined when target platform is native x86_64 (win64)
+ CPU32 Defined when target is 32-bit
+ CPU64 Defined when target is 64-bit
+ CPUASM Defined when target assembler is available
+
+- Visual library Directives
+
+ The following directives indicate for a visual library. In a Delphi/BCB
+ (Win32) application you need to define the VisualCLX symbol in the project
+ options, if you want to use the VisualCLX library. Alternatively you can use
+ the IDE expert, which is distributed with the JCL to do this automatically.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ VCL Defined for Delphi/BCB (Win32) exactly if VisualCLX is not defined
+ VisualCLX Defined for Kylix; needs to be defined for Delphi/BCB to
+ use JCL with VisualCLX applications.
+
+
+- Other cross-platform related defines
+
+ These symbols are intended to help in writing portable code.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ PUREPASCAL Code is machine-independent (as opposed to assembler code)
+ Win32API Code is specific for the Win32 API;
+ use instead of "{$IFNDEF CLR} {$IFDEF MSWINDOWS}" constructs
+
+
+- Delphi Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. These directives are only defined if
+ the compiler is Delphi (ie DELPHI is defined).
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ DELPHI1 Defined when compiling with Delphi 1 (Codename WASABI/MANGO)
+ DELPHI2 Defined when compiling with Delphi 2 (Codename POLARIS)
+ DELPHI3 Defined when compiling with Delphi 3 (Codename IVORY)
+ DELPHI4 Defined when compiling with Delphi 4 (Codename ALLEGRO)
+ DELPHI5 Defined when compiling with Delphi 5 (Codename ARGUS)
+ DELPHI6 Defined when compiling with Delphi 6 (Codename ILLIAD)
+ DELPHI7 Defined when compiling with Delphi 7 (Codename AURORA)
+ DELPHI8 Defined when compiling with Delphi 8 (Codename OCTANE)
+ DELPHI2005 Defined when compiling with Delphi 2005 (Codename DIAMONDBACK)
+ DELPHI9 Alias for DELPHI2005
+ DELPHI10 Defined when compiling with Delphi 2006 (Codename DEXTER)
+ DELPHI2006 Alias for DELPHI10
+ DELPHI11 Defined when compiling with Delphi 2007 for Win32 (Codename SPACELY)
+ DELPHI2007 Alias for DELPHI11
+ DELPHI12 Defined when compiling with Delphi 2009 for Win32 (Codename TIBURON)
+ DELPHI2009 Alias for DELPHI12
+ DELPHI14 Defined when compiling with Delphi 2010 for Win32 (Codename WEAVER)
+ DELPHI2010 Alias for DELPHI14
+ DELPHI15 Defined when compiling with Delphi XE for Win32 (Codename FULCRUM)
+ DELPHIXE Alias for DELPHI15
+ DELPHI16 Defined when compiling with Delphi XE2 for Win32 (Codename PULSAR)
+ DELPHIXE2 Alias for DELPHI16
+ DELPHI17 Defined when compiling with Delphi XE3 for Win32 (Codename WATERDRAGON)
+ DELPHIXE3 Alias for DELPHI17
+ DELPHI1_UP Defined when compiling with Delphi 1 or higher
+ DELPHI2_UP Defined when compiling with Delphi 2 or higher
+ DELPHI3_UP Defined when compiling with Delphi 3 or higher
+ DELPHI4_UP Defined when compiling with Delphi 4 or higher
+ DELPHI5_UP Defined when compiling with Delphi 5 or higher
+ DELPHI6_UP Defined when compiling with Delphi 6 or higher
+ DELPHI7_UP Defined when compiling with Delphi 7 or higher
+ DELPHI8_UP Defined when compiling with Delphi 8 or higher
+ DELPHI2005_UP Defined when compiling with Delphi 2005 or higher
+ DELPHI9_UP Alias for DELPHI2005_UP
+ DELPHI10_UP Defined when compiling with Delphi 2006 or higher
+ DELPHI2006_UP Alias for DELPHI10_UP
+ DELPHI11_UP Defined when compiling with Delphi 2007 for Win32 or higher
+ DELPHI2007_UP Alias for DELPHI11_UP
+ DELPHI12_UP Defined when compiling with Delphi 2009 for Win32 or higher
+ DELPHI2009_UP Alias for DELPHI12_UP
+ DELPHI14_UP Defined when compiling with Delphi 2010 for Win32 or higher
+ DELPHI2010_UP Alias for DELPHI14_UP
+ DELPHI15_UP Defined when compiling with Delphi XE for Win32 or higher
+ DELPHIXE_UP Alias for DELPHI15_UP
+ DELPHI16_UP Defined when compiling with Delphi XE2 for Win32 or higher
+ DELPHIXE2_UP Alias for DELPHI16_UP
+ DELPHI17_UP Defined when compiling with Delphi XE3 for Win32 or higher
+ DELPHIXE3_UP Alias for DELPHI17_UP
+
+
+- Kylix Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. These directives are only defined if
+ the compiler is Kylix (ie KYLIX is defined).
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ KYLIX1 Defined when compiling with Kylix 1
+ KYLIX2 Defined when compiling with Kylix 2
+ KYLIX3 Defined when compiling with Kylix 3 (Codename CORTEZ)
+ KYLIX1_UP Defined when compiling with Kylix 1 or higher
+ KYLIX2_UP Defined when compiling with Kylix 2 or higher
+ KYLIX3_UP Defined when compiling with Kylix 3 or higher
+
+
+- Delphi Compiler Versions (Delphi / Kylix, not in BCB mode)
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ DELPHICOMPILER1 Defined when compiling with Delphi 1
+ DELPHICOMPILER2 Defined when compiling with Delphi 2
+ DELPHICOMPILER3 Defined when compiling with Delphi 3
+ DELPHICOMPILER4 Defined when compiling with Delphi 4
+ DELPHICOMPILER5 Defined when compiling with Delphi 5
+ DELPHICOMPILER6 Defined when compiling with Delphi 6 or Kylix 1, 2 or 3
+ DELPHICOMPILER7 Defined when compiling with Delphi 7
+ DELPHICOMPILER8 Defined when compiling with Delphi 8
+ DELPHICOMPILER9 Defined when compiling with Delphi 2005
+ DELPHICOMPILER10 Defined when compiling with Delphi Personality of BDS 4.0
+ DELPHICOMPILER11 Defined when compiling with Delphi 2007 for Win32
+ DELPHICOMPILER12 Defined when compiling with Delphi Personality of BDS 6.0
+ DELPHICOMPILER14 Defined when compiling with Delphi Personality of BDS 7.0
+ DELPHICOMPILER15 Defined when compiling with Delphi Personality of BDS 8.0
+ DELPHICOMPILER16 Defined when compiling with Delphi Personality of BDS 9.0
+ DELPHICOMPILER17 Defined when compiling with Delphi Personality of BDS 10.0
+ DELPHICOMPILER1_UP Defined when compiling with Delphi 1 or higher
+ DELPHICOMPILER2_UP Defined when compiling with Delphi 2 or higher
+ DELPHICOMPILER3_UP Defined when compiling with Delphi 3 or higher
+ DELPHICOMPILER4_UP Defined when compiling with Delphi 4 or higher
+ DELPHICOMPILER5_UP Defined when compiling with Delphi 5 or higher
+ DELPHICOMPILER6_UP Defined when compiling with Delphi 6 or Kylix 1, 2 or 3 or higher
+ DELPHICOMPILER7_UP Defined when compiling with Delphi 7 or higher
+ DELPHICOMPILER8_UP Defined when compiling with Delphi 8 or higher
+ DELPHICOMPILER9_UP Defined when compiling with Delphi 2005
+ DELPHICOMPILER10_UP Defined when compiling with Delphi 2006 or higher
+ DELPHICOMPILER11_UP Defined when compiling with Delphi 2007 for Win32 or higher
+ DELPHICOMPILER12_UP Defined when compiling with Delphi 2009 for Win32 or higher
+ DELPHICOMPILER14_UP Defined when compiling with Delphi 2010 for Win32 or higher
+ DELPHICOMPILER15_UP Defined when compiling with Delphi XE for Win32 or higher
+ DELPHICOMPILER16_UP Defined when compiling with Delphi XE2 for Win32 or higher
+ DELPHICOMPILER17_UP Defined when compiling with Delphi XE3 for Win32 or higher
+
+
+- C++Builder Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. These directives are only defined if
+ the compiler is C++Builder (ie BCB is defined).
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ BCB1 Defined when compiling with C++Builder 1
+ BCB3 Defined when compiling with C++Builder 3
+ BCB4 Defined when compiling with C++Builder 4
+ BCB5 Defined when compiling with C++Builder 5 (Codename RAMPAGE)
+ BCB6 Defined when compiling with C++Builder 6 (Codename RIPTIDE)
+ BCB10 Defined when compiling with C++Builder Personality of BDS 4.0 (also known as C++Builder 2006) (Codename DEXTER)
+ BCB11 Defined when compiling with C++Builder Personality of RAD Studio 2007 (also known as C++Builder 2007) (Codename COGSWELL)
+ BCB12 Defined when compiling with C++Builder Personality of RAD Studio 2009 (also known as C++Builder 2009) (Codename TIBURON)
+ BCB14 Defined when compiling with C++Builder Personality of RAD Studio 2010 (also known as C++Builder 2010) (Codename WEAVER)
+ BCB15 Defined when compiling with C++Builder Personality of RAD Studio XE (also known as C++Builder XE) (Codename FULCRUM)
+ BCB16 Defined when compiling with C++Builder Personality of RAD Studio XE2 (also known as C++Builder XE2) (Codename PULSAR)
+ BCB17 Defined when compiling with C++Builder Personality of RAD Studio XE3 (also known as C++Builder XE3) (Codename WATERDRAGON)
+ BCB1_UP Defined when compiling with C++Builder 1 or higher
+ BCB3_UP Defined when compiling with C++Builder 3 or higher
+ BCB4_UP Defined when compiling with C++Builder 4 or higher
+ BCB5_UP Defined when compiling with C++Builder 5 or higher
+ BCB6_UP Defined when compiling with C++Builder 6 or higher
+ BCB10_UP Defined when compiling with C++Builder Personality of BDS 4.0 or higher
+ BCB11_UP Defined when compiling with C++Builder Personality of RAD Studio 2007 or higher
+ BCB12_UP Defined when compiling with C++Builder Personality of RAD Studio 2009 or higher
+ BCB14_UP Defined when compiling with C++Builder Personality of RAD Studio 2010 or higher
+ BCB15_UP Defined when compiling with C++Builder Personality of RAD Studio XE or higher
+ BCB16_UP Defined when compiling with C++Builder Personality of RAD Studio XE2 or higher
+ BCB17_UP Defined when compiling with C++Builder Personality of RAD Studio XE3 or higher
+
+
+- RAD Studio / Borland Developer Studio Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated IDE. These directives are only defined if
+ the IDE is Borland Developer Studio Version 2 or above.
+
+ Note: Borland Developer Studio 2006 is marketed as Delphi 2006 or C++Builder 2006,
+ but those provide only different labels for identical content.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ BDS Defined when compiling with BDS version of dcc32.exe (Codename SIDEWINDER)
+ BDS2 Defined when compiling with BDS 2.0 (Delphi 8) (Codename OCTANE)
+ BDS3 Defined when compiling with BDS 3.0 (Delphi 2005) (Codename DIAMONDBACK)
+ BDS4 Defined when compiling with BDS 4.0 (Borland Developer Studio 2006) (Codename DEXTER)
+ BDS5 Defined when compiling with BDS 5.0 (CodeGear RAD Studio 2007) (Codename HIGHLANDER)
+ BDS6 Defined when compiling with BDS 6.0 (CodeGear RAD Studio 2009) (Codename TIBURON)
+ BDS7 Defined when compiling with BDS 7.0 (Embarcadero RAD Studio 2010) (Codename WEAVER)
+ BDS8 Defined when compiling with BDS 8.0 (Embarcadero RAD Studio XE) (Codename FULCRUM)
+ BDS9 Defined when compiling with BDS 9.0 (Embarcadero RAD Studio XE2) (Codename PULSAR)
+ BDS10 Defined when compiling with BDS 10.0 (Embarcadero RAD Studio XE3) (Codename WATERDRAGON)
+ BDS2_UP Defined when compiling with BDS 2.0 or higher
+ BDS3_UP Defined when compiling with BDS 3.0 or higher
+ BDS4_UP Defined when compiling with BDS 4.0 or higher
+ BDS5_UP Defined when compiling with BDS 5.0 or higher
+ BDS6_UP Defined when compiling with BDS 6.0 or higher
+ BDS7_UP Defined when compiling with BDS 7.0 or higher
+ BDS8_UP Defined when compiling with BDS 8.0 or higher
+ BDS9_UP Defined when compiling with BDS 9.0 or higher
+ BDS10_UP Defined when compiling with BDS 10.0 or higher
+
+- Compiler Versions
+
+ The following directives are direct mappings from the VERXXX directives to a
+ friendly name of the associated compiler. Unlike the DELPHI_X and BCB_X
+ directives, these directives are indepedent of the development environment.
+ That is, they are defined regardless of whether compilation takes place using
+ Delphi or C++Builder.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ COMPILER1 Defined when compiling with Delphi 1
+ COMPILER2 Defined when compiling with Delphi 2 or C++Builder 1
+ COMPILER3 Defined when compiling with Delphi 3
+ COMPILER35 Defined when compiling with C++Builder 3
+ COMPILER4 Defined when compiling with Delphi 4 or C++Builder 4
+ COMPILER5 Defined when compiling with Delphi 5 or C++Builder 5
+ COMPILER6 Defined when compiling with Delphi 6 or C++Builder 6
+ COMPILER7 Defined when compiling with Delphi 7
+ COMPILER8 Defined when compiling with Delphi 8
+ COMPILER9 Defined when compiling with Delphi 9
+ COMPILER10 Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0
+ COMPILER11 Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0
+ COMPILER12 Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0
+ COMPILER14 Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0
+ COMPILER15 Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0
+ COMPILER16 Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0
+ COMPILER17 Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0
+ COMPILER1_UP Defined when compiling with Delphi 1 or higher
+ COMPILER2_UP Defined when compiling with Delphi 2 or C++Builder 1 or higher
+ COMPILER3_UP Defined when compiling with Delphi 3 or higher
+ COMPILER35_UP Defined when compiling with C++Builder 3 or higher
+ COMPILER4_UP Defined when compiling with Delphi 4 or C++Builder 4 or higher
+ COMPILER5_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher
+ COMPILER6_UP Defined when compiling with Delphi 6 or C++Builder 6 or higher
+ COMPILER7_UP Defined when compiling with Delphi 7
+ COMPILER8_UP Defined when compiling with Delphi 8
+ COMPILER9_UP Defined when compiling with Delphi Personalities of BDS 3.0
+ COMPILER10_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher
+ COMPILER11_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher
+ COMPILER12_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher
+ COMPILER14_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher
+ COMPILER15_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher
+ COMPILER16_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher
+ COMPILER17_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher
+
+
+- RTL Versions
+
+ Use e.g. following to determine the exact RTL version since version 14.0:
+ {$IFDEF CONDITIONALEXPRESSIONS}
+ {$IF Declared(RTLVersion) and (RTLVersion >= 14.2)}
+ // code for Delphi 6.02 or higher, Kylix 2 or higher, C++Builder 6 or higher
+ ...
+ {$IFEND}
+ {$ENDIF}
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ RTL80_UP Defined when compiling with Delphi 1 or higher
+ RTL90_UP Defined when compiling with Delphi 2 or higher
+ RTL93_UP Defined when compiling with C++Builder 1 or higher
+ RTL100_UP Defined when compiling with Delphi 3 or higher
+ RTL110_UP Defined when compiling with C++Builder 3 or higher
+ RTL120_UP Defined when compiling with Delphi 4 or higher
+ RTL125_UP Defined when compiling with C++Builder 4 or higher
+ RTL130_UP Defined when compiling with Delphi 5 or C++Builder 5 or higher
+ RTL140_UP Defined when compiling with Delphi 6, Kylix 1, 2 or 3 or C++Builder 6 or higher
+ RTL150_UP Defined when compiling with Delphi 7 or higher
+ RTL160_UP Defined when compiling with Delphi 8 or higher
+ RTL170_UP Defined when compiling with Delphi Personalities of BDS 3.0 or higher
+ RTL180_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 4.0 or higher
+ RTL185_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 5.0 or higher
+ RTL190_UP Defined when compiling with Delphi.NET of BDS 5.0 or higher
+ RTL200_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 6.0 or higher
+ RTL210_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 7.0 or higher
+ RTL220_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 8.0 or higher
+ RTL230_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 9.0 or higher
+ RTL240_UP Defined when compiling with Delphi or C++Builder Personalities of BDS 10.0 or higher
+
+
+- CLR Versions
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ CLR Defined when compiling for .NET
+ CLR10 Defined when compiling for .NET 1.0 (may be overriden by FORCE_CLR10)
+ CLR10_UP Defined when compiling for .NET 1.0 or higher
+ CLR11 Defined when compiling for .NET 1.1 (may be overriden by FORCE_CLR11)
+ CLR11_UP Defined when compiling for .NET 1.1 or higher
+ CLR20 Defined when compiling for .NET 2.0 (may be overriden by FORCE_CLR20)
+ CLR20_UP Defined when compiling for .NET 2.0 or higher
+
+
+- Feature Directives
+
+ The features directives are used to test if the compiler supports specific
+ features, such as method overloading, and adjust the sources accordingly. Use
+ of these directives is preferred over the use of the DELPHI and COMPILER
+ directives.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ SUPPORTS_CONSTPARAMS Compiler supports const parameters (D1+)
+ SUPPORTS_SINGLE Compiler supports the Single type (D1+)
+ SUPPORTS_DOUBLE Compiler supports the Double type (D1+)
+ SUPPORTS_EXTENDED Compiler supports the Extended type (D1+)
+ SUPPORTS_CURRENCY Compiler supports the Currency type (D2+)
+ SUPPORTS_THREADVAR Compiler supports threadvar declarations (D2+)
+ SUPPORTS_OUTPARAMS Compiler supports out parameters (D3+)
+ SUPPORTS_VARIANT Compiler supports variant (D2+)
+ SUPPORTS_WIDECHAR Compiler supports the WideChar type (D2+)
+ SUPPORTS_WIDESTRING Compiler supports the WideString type (D3+/BCB3+)
+ SUPPORTS_INTERFACE Compiler supports interfaces (D3+/BCB3+)
+ SUPPORTS_DISPINTERFACE Compiler supports dispatch interfaces (D3+/BCB3+)
+ SUPPORTS_DISPID Compiler supports dispatch ids (D3+/BCB3+/FPC)
+ SUPPORTS_EXTSYM Compiler supports the $EXTERNALSYM directive (D4+/BCB3+)
+ SUPPORTS_NODEFINE Compiler supports the $NODEFINE directive (D4+/BCB3+)
+ SUPPORTS_LONGWORD Compiler supports the LongWord type (unsigned 32 bit) (D4+/BCB4+)
+ SUPPORTS_INT64 Compiler supports the Int64 type (D4+/BCB4+)
+ SUPPORTS_UINT64 Compiler supports the UInt64 type (D XE+ ?)
+ SUPPORTS_DYNAMICARRAYS Compiler supports dynamic arrays (D4+/BCB4+)
+ SUPPORTS_DEFAULTPARAMS Compiler supports default parameters (D4+/BCB4+)
+ SUPPORTS_OVERLOAD Compiler supports overloading (D4+/BCB4+)
+ SUPPORTS_IMPLEMENTS Compiler supports implements (D4+/BCB4+)
+ SUPPORTS_DEPRECATED Compiler supports the deprecated directive (D6+/BCB6+)
+ SUPPORTS_PLATFORM Compiler supports the platform directive (D6+/BCB6+)
+ SUPPORTS_LIBRARY Compiler supports the library directive (D6+/BCB6+/FPC)
+ SUPPORTS_LOCAL Compiler supports the local directive (D6+/BCB6+)
+ SUPPORTS_SETPEFLAGS Compiler supports the SetPEFlags directive (D6+/BCB6+)
+ SUPPORTS_EXPERIMENTAL_WARNINGS Compiler supports the WARN SYMBOL_EXPERIMENTAL and WARN UNIT_EXPERIMENTAL directives (D6+/BCB6+)
+ SUPPORTS_INLINE Compiler supports the inline directive (D9+/FPC)
+ SUPPORTS_FOR_IN Compiler supports for in loops (D9+)
+ SUPPORTS_NESTED_CONSTANTS Compiler supports nested constants (D9+)
+ SUPPORTS_NESTED_TYPES Compiler supports nested types (D9+)
+ SUPPORTS_REGION Compiler supports the REGION and ENDREGION directives (D9+)
+ SUPPORTS_ENHANCED_RECORDS Compiler supports class [operator|function|procedure] for record types (D9.NET, D10+)
+ SUPPORTS_CLASS_FIELDS Compiler supports class fields (D9.NET, D10+)
+ SUPPORTS_CLASS_HELPERS Compiler supports class helpers (D9.NET, D10+)
+ SUPPORTS_CLASS_OPERATORS Compiler supports class operators (D9.NET, D10+)
+ SUPPORTS_CLASS_CTORDTORS Compiler supports class contructors/destructors (D14+)
+ SUPPORTS_STRICT Compiler supports strict keyword (D9.NET, D10+)
+ SUPPORTS_STATIC Compiler supports static keyword (D9.NET, D10+)
+ SUPPORTS_FINAL Compiler supports final keyword (D9.NET, D10+)
+ SUPPORTS_METHODINFO Compiler supports the METHODINFO directives (D10+)
+ SUPPORTS_GENERICS Compiler supports generic implementations (D11.NET, D12+)
+ SUPPORTS_DEPRECATED_DETAILS Compiler supports additional text for the deprecated directive (D11.NET, D12+)
+ ACCEPT_DEPRECATED Compiler supports or ignores the deprecated directive (D6+/BCB6+/FPC)
+ ACCEPT_PLATFORM Compiler supports or ignores the platform directive (D6+/BCB6+/FPC)
+ ACCEPT_LIBRARY Compiler supports or ignores the library directive (D6+/BCB6+)
+ SUPPORTS_CUSTOMVARIANTS Compiler supports custom variants (D6+/BCB6+)
+ SUPPORTS_VARARGS Compiler supports varargs (D6+/BCB6+)
+ SUPPORTS_ENUMVALUE Compiler supports assigning ordinalities to values of enums (D6+/BCB6+)
+ SUPPORTS_DEPRECATED_WARNINGS Compiler supports deprecated warnings (D6+/BCB6+)
+ SUPPORTS_LIBRARY_WARNINGS Compiler supports library warnings (D6+/BCB6+)
+ SUPPORTS_PLATFORM_WARNINGS Compiler supports platform warnings (D6+/BCB6+)
+ SUPPORTS_UNSAFE_WARNINGS Compiler supports unsafe warnings (D7)
+ SUPPORTS_WEAKPACKAGEUNIT Compiler supports the WEAKPACKAGEUNIT directive
+ SUPPORTS_COMPILETIME_MESSAGES Compiler supports the MESSAGE directive
+ SUPPORTS_PACKAGES Compiler supports Packages
+ HAS_UNIT_LIBC Unit Libc exists (Kylix, FPC on Linux/x86)
+ HAS_UNIT_RTLCONSTS Unit RTLConsts exists (D6+/BCB6+/FPC)
+ HAS_UNIT_TYPES Unit Types exists (D6+/BCB6+/FPC)
+ HAS_UNIT_VARIANTS Unit Variants exists (D6+/BCB6+/FPC)
+ HAS_UNIT_STRUTILS Unit StrUtils exists (D6+/BCB6+/FPC)
+ HAS_UNIT_DATEUTILS Unit DateUtils exists (D6+/BCB6+/FPC)
+ HAS_UNIT_CONTNRS Unit contnrs exists (D6+/BCB6+/FPC)
+ HAS_UNIT_HTTPPROD Unit HTTPProd exists (D9+)
+ HAS_UNIT_GIFIMG Unit GifImg exists (D11+)
+ HAS_UNIT_ANSISTRINGS Unit AnsiStrings exists (D12+)
+ HAS_UNIT_PNGIMAGE Unit PngImage exists (D12+)
+ HAS_UNIT_CHARACTER Unit Character exists (D12+)
+ XPLATFORM_RTL The RTL supports crossplatform function names (e.g. RaiseLastOSError) (D6+/BCB6+/FPC)
+ SUPPORTS_UNICODE string type is aliased to an unicode string (WideString or UnicodeString) (DX.NET, D12+)
+ SUPPORTS_UNICODE_STRING Compiler supports UnicodeString (D12+)
+ SUPPORTS_INT_ALIASES Types Int8, Int16, Int32, UInt8, UInt16 and UInt32 are defined in the unit System (D12+)
+ HAS_UNIT_RTTI Unit RTTI is available (D14+)
+ SUPPORTS_CAST_INTERFACE_TO_OBJ The compiler supports casts from interfaces to objects (D14+)
+ SUPPORTS_DELAYED_LOADING The compiler generates stubs for delaying imported function loads (D14+)
+ HAS_UNIT_REGULAREXPRESSIONSAPI Unit RegularExpressionsAPI is available (D15+)
+ HAS_UNIT_SYSTEM_UITYPES Unit System.UITypes is available (D16+)
+ HAS_UNIT_SYSTEM_ACTIONS Unit System.Actions is available (D17+)
+
+
+- Compiler Settings
+
+ The compiler settings directives indicate whether a specific compiler setting
+ is in effect. This facilitates changing compiler settings locally in a more
+ compact and readible manner.
+
+ Directive Description
+ ------------------------------------------------------------------------------
+ ALIGN_ON Compiling in the A+ state (no alignment)
+ BOOLEVAL_ON Compiling in the B+ state (complete boolean evaluation)
+ ASSERTIONS_ON Compiling in the C+ state (assertions on)
+ DEBUGINFO_ON Compiling in the D+ state (debug info generation on)
+ IMPORTEDDATA_ON Compiling in the G+ state (creation of imported data references)
+ LONGSTRINGS_ON Compiling in the H+ state (string defined as AnsiString)
+ IOCHECKS_ON Compiling in the I+ state (I/O checking enabled)
+ WRITEABLECONST_ON Compiling in the J+ state (typed constants can be modified)
+ LOCALSYMBOLS Compiling in the L+ state (local symbol generation)
+ LOCALSYMBOLS_ON Alias of LOCALSYMBOLS
+ TYPEINFO_ON Compiling in the M+ state (RTTI generation on)
+ OPTIMIZATION_ON Compiling in the O+ state (code optimization on)
+ OPENSTRINGS_ON Compiling in the P+ state (variable string parameters are openstrings)
+ OVERFLOWCHECKS_ON Compiling in the Q+ state (overflow checing on)
+ RANGECHECKS_ON Compiling in the R+ state (range checking on)
+ TYPEDADDRESS_ON Compiling in the T+ state (pointers obtained using the @ operator are typed)
+ SAFEDIVIDE_ON Compiling in the U+ state (save FDIV instruction through RTL emulation)
+ VARSTRINGCHECKS_ON Compiling in the V+ state (type checking of shortstrings)
+ STACKFRAMES_ON Compiling in the W+ state (generation of stack frames)
+ EXTENDEDSYNTAX_ON Compiling in the X+ state (Delphi extended syntax enabled)
+*)
+
+{$DEFINE BORLAND}
+
+{ Set FreePascal to Delphi mode }
+{$IFDEF FPC}
+ {$MODE DELPHI}
+ {$ASMMODE Intel}
+ {$UNDEF BORLAND}
+ {$DEFINE CPUASM}
+ // FPC defines CPU32, CPU64 and Unix automatically
+{$ENDIF}
+
+{$IFDEF BORLAND}
+ {$IFDEF LINUX}
+ {$DEFINE KYLIX}
+ {$ENDIF LINUX}
+ {$IFNDEF CLR}
+ {$IFNDEF CPUX86}
+ {$IFNDEF CPUX64}
+ {$DEFINE CPU386} // For Borland compilers select the x86 compat assembler by default
+ {$DEFINE CPU32} // Assume Borland compilers are 32-bit (rather than 64-bit)
+ {$DEFINE CPUASM}
+ {$ELSE ~CPUX64}
+ {$DEFINE CPU64}
+ {$DEFINE CPUASM}
+ {$DEFINE DELPHI64_TEMPORARY}
+ {$ENDIF ~CPUX64}
+ {$ELSE ~CPUX86}
+ {$DEFINE CPU386}
+ {$DEFINE CPU32}
+ {$DEFINE CPUASM}
+ {$ENDIF ~CPUX86}
+ {$ENDIF ~CLR}
+{$ENDIF BORLAND}
+
+{------------------------------------------------------------------------------}
+{ VERXXX to COMPILERX, DELPHIX and BCBX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BORLAND}
+ {$IFDEF KYLIX}
+ {$I kylix.inc} // FPC incompatible stuff
+ {$ELSE ~KYLIX}
+
+ {$DEFINE UNKNOWN_COMPILER_VERSION}
+
+ {$IFDEF VER80}
+ {$DEFINE COMPILER1}
+ {$DEFINE DELPHI1}
+ {$DEFINE DELPHICOMPILER1}
+ {$DEFINE RTL80_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER90}
+ {$DEFINE COMPILER2}
+ {$DEFINE DELPHI2}
+ {$DEFINE DELPHICOMPILER2}
+ {$DEFINE RTL90_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER93}
+ {$DEFINE COMPILER2}
+ {$DEFINE BCB1}
+ {$DEFINE BCB}
+ {$DEFINE RTL93_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER100}
+ {$DEFINE COMPILER3}
+ {$DEFINE DELPHI3}
+ {$DEFINE DELPHICOMPILER3}
+ {$DEFINE RTL100_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER110}
+ {$DEFINE COMPILER35}
+ {$DEFINE BCB3}
+ {$DEFINE BCB}
+ {$DEFINE RTL110_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER120}
+ {$DEFINE COMPILER4}
+ {$DEFINE DELPHI4}
+ {$DEFINE DELPHICOMPILER4}
+ {$DEFINE RTL120_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER125}
+ {$DEFINE COMPILER4}
+ {$DEFINE BCB4}
+ {$DEFINE BCB}
+ {$DEFINE RTL125_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER130}
+ {$DEFINE COMPILER5}
+ {$IFDEF BCB}
+ {$DEFINE BCB5}
+ {$ELSE}
+ {$DEFINE DELPHI5}
+ {$DEFINE DELPHICOMPILER5}
+ {$ENDIF}
+ {$DEFINE RTL130_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER140}
+ {$DEFINE COMPILER6}
+ {$IFDEF BCB}
+ {$DEFINE BCB6}
+ {$ELSE}
+ {$DEFINE DELPHI6}
+ {$DEFINE DELPHICOMPILER6}
+ {$ENDIF}
+ {$DEFINE RTL140_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER150}
+ {$DEFINE COMPILER7}
+ {$DEFINE DELPHI7}
+ {$DEFINE DELPHICOMPILER7}
+ {$DEFINE RTL150_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER160}
+ {$DEFINE BDS2}
+ {$DEFINE BDS}
+ {$IFDEF CLR}
+ {$DEFINE CLR10}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER8}
+ {$DEFINE DELPHI8}
+ {$DEFINE DELPHICOMPILER8}
+ {$DEFINE RTL160_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER170}
+ {$DEFINE BDS3}
+ {$DEFINE BDS}
+ {$IFDEF CLR}
+ {$DEFINE CLR11}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER9}
+ {$DEFINE DELPHI9}
+ {$DEFINE DELPHI2005} // synonym to DELPHI9
+ {$DEFINE DELPHICOMPILER9}
+ {$DEFINE RTL170_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER180}
+ {$DEFINE BDS}
+ {$IFDEF CLR}
+ {$DEFINE CLR11}
+ {$ENDIF CLR}
+ {$IFDEF VER185}
+ {$DEFINE BDS5}
+ {$DEFINE COMPILER11}
+ {$IFDEF BCB}
+ {$DEFINE BCB11}
+ {$ELSE}
+ {$DEFINE DELPHI11}
+ {$DEFINE DELPHI2007} // synonym to DELPHI11
+ {$DEFINE DELPHICOMPILER11}
+ {$ENDIF}
+ {$DEFINE RTL185_UP}
+ {$ELSE ~~VER185}
+ {$DEFINE BDS4}
+ {$DEFINE COMPILER10}
+ {$IFDEF BCB}
+ {$DEFINE BCB10}
+ {$ELSE}
+ {$DEFINE DELPHI10}
+ {$DEFINE DELPHI2006} // synonym to DELPHI10
+ {$DEFINE DELPHICOMPILER10}
+ {$ENDIF}
+ {$DEFINE RTL180_UP}
+ {$ENDIF ~VER185}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$IFDEF VER190} // Delphi 2007 for .NET
+ {$DEFINE BDS}
+ {$DEFINE BDS5}
+ {$IFDEF CLR}
+ {$DEFINE CLR20}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER11}
+ {$DEFINE DELPHI11}
+ {$DEFINE DELPHI2007} // synonym to DELPHI11
+ {$DEFINE DELPHICOMPILER11}
+ {$DEFINE RTL190_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER190}
+
+ {$IFDEF VER200} // RAD Studio 2009
+ {$DEFINE BDS}
+ {$DEFINE BDS6}
+ {$IFDEF CLR}
+ {$DEFINE CLR20}
+ {$ENDIF CLR}
+ {$DEFINE COMPILER12}
+ {$IFDEF BCB}
+ {$DEFINE BCB12}
+ {$ELSE}
+ {$DEFINE DELPHI12}
+ {$DEFINE DELPHI2009} // synonym to DELPHI12
+ {$DEFINE DELPHICOMPILER12}
+ {$ENDIF BCB}
+ {$IFDEF CLR}
+ {$DEFINE RTL190_UP}
+ {$ELSE}
+ {$DEFINE RTL200_UP}
+ {$ENDIF}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER200}
+
+ {$IFDEF VER210} // RAD Studio 2010
+ {$DEFINE BDS}
+ {$DEFINE BDS7}
+ {$DEFINE COMPILER14}
+ {$IFDEF BCB}
+ {$DEFINE BCB14}
+ {$ELSE}
+ {$DEFINE DELPHI14}
+ {$DEFINE DELPHI2010} // synonym to DELPHI14
+ {$DEFINE DELPHICOMPILER14}
+ {$ENDIF BCB}
+ {$DEFINE RTL210_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER210}
+
+ {$IFDEF VER220} // RAD Studio XE
+ {$DEFINE BDS}
+ {$DEFINE BDS8}
+ {$DEFINE COMPILER15}
+ {$IFDEF BCB}
+ {$DEFINE BCB15}
+ {$ELSE}
+ {$DEFINE DELPHI15}
+ {$DEFINE DELPHIXE} // synonym to DELPHI15
+ {$DEFINE DELPHICOMPILER15}
+ {$ENDIF BCB}
+ {$DEFINE RTL220_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER220}
+
+ {$IFDEF VER230} // RAD Studio XE2
+ {$DEFINE BDS}
+ {$DEFINE BDS9}
+ {$DEFINE COMPILER16}
+ {$IFDEF BCB}
+ {$DEFINE BCB16}
+ {$ELSE}
+ {$DEFINE DELPHI16}
+ {$DEFINE DELPHIXE2} // synonym to DELPHI16
+ {$DEFINE DELPHICOMPILER16}
+ {$ENDIF BCB}
+ {$DEFINE RTL230_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER230}
+
+ {$IFDEF VER240} // RAD Studio XE3
+ {$DEFINE BDS}
+ {$DEFINE BDS10}
+ {$DEFINE COMPILER17}
+ {$IFDEF BCB}
+ {$DEFINE BCB17}
+ {$ELSE}
+ {$DEFINE DELPHI17}
+ {$DEFINE DELPHIXE3} // synonym to DELPHI17
+ {$DEFINE DELPHICOMPILER17}
+ {$ENDIF BCB}
+ {$DEFINE RTL240_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF VER240}
+
+ {$IFDEF UNKNOWN_COMPILER_VERSION} // adjust for newer version (always use latest version)
+ {$DEFINE BDS}
+ {$DEFINE BDS10}
+ {$DEFINE COMPILER17}
+ {$IFDEF BCB}
+ {$DEFINE BCB17}
+ {$ELSE}
+ {$DEFINE DELPHI17}
+ {$DEFINE DELPHIXE3} // synonym to DELPHI17
+ {$DEFINE DELPHICOMPILER17}
+ {$ENDIF BCB}
+ {$DEFINE RTL240_UP}
+ {$UNDEF UNKNOWN_COMPILER_VERSION}
+ {$ENDIF}
+
+ {$ENDIF ~KYLIX}
+
+ {$IFDEF BCB}
+ {$DEFINE CPPBUILDER}
+ {$DEFINE BCBCOMPILER}
+ {$ELSE ~BCB}
+ {$DEFINE DELPHI}
+ {$DEFINE DELPHICOMPILER}
+ {$ENDIF ~BCB}
+
+{$ENDIF BORLAND}
+
+{------------------------------------------------------------------------------}
+{ DELPHIX_UP from DELPHIX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHI17} {$DEFINE DELPHI17_UP} {$ENDIF}
+{$IFDEF DELPHI16} {$DEFINE DELPHI16_UP} {$ENDIF}
+{$IFDEF DELPHI15} {$DEFINE DELPHI15_UP} {$ENDIF}
+{$IFDEF DELPHI14} {$DEFINE DELPHI14_UP} {$ENDIF}
+{$IFDEF DELPHI12} {$DEFINE DELPHI12_UP} {$ENDIF}
+{$IFDEF DELPHI11} {$DEFINE DELPHI11_UP} {$ENDIF}
+{$IFDEF DELPHI10} {$DEFINE DELPHI10_UP} {$ENDIF}
+{$IFDEF DELPHI9} {$DEFINE DELPHI9_UP} {$ENDIF}
+{$IFDEF DELPHI8} {$DEFINE DELPHI8_UP} {$ENDIF}
+{$IFDEF DELPHI7} {$DEFINE DELPHI7_UP} {$ENDIF}
+{$IFDEF DELPHI6} {$DEFINE DELPHI6_UP} {$ENDIF}
+{$IFDEF DELPHI5} {$DEFINE DELPHI5_UP} {$ENDIF}
+{$IFDEF DELPHI4} {$DEFINE DELPHI4_UP} {$ENDIF}
+{$IFDEF DELPHI3} {$DEFINE DELPHI3_UP} {$ENDIF}
+{$IFDEF DELPHI2} {$DEFINE DELPHI2_UP} {$ENDIF}
+{$IFDEF DELPHI1} {$DEFINE DELPHI1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ DELPHIX_UP from DELPHIX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHI17_UP}
+ {$DEFINE DELPHIXE3_UP} // synonym to DELPHI17_UP
+ {$DEFINE DELPHI16_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI16_UP}
+ {$DEFINE DELPHIXE2_UP} // synonym to DELPHI16_UP
+ {$DEFINE DELPHI15_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI15_UP}
+ {$DEFINE DELPHIXE_UP} // synonym to DELPHI15_UP
+ {$DEFINE DELPHI14_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI14_UP}
+ {$DEFINE DELPHI2010_UP} // synonym to DELPHI14_UP
+ {$DEFINE DELPHI12_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI12_UP}
+ {$DEFINE DELPHI2009_UP} // synonym to DELPHI12_UP
+ {$DEFINE DELPHI11_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI11_UP}
+ {$DEFINE DELPHI2007_UP} // synonym to DELPHI11_UP
+ {$DEFINE DELPHI10_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI10_UP}
+ {$DEFINE DELPHI2006_UP} // synonym to DELPHI10_UP
+ {$DEFINE DELPHI9_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI9_UP}
+ {$DEFINE DELPHI2005_UP} // synonym to DELPHI9_UP
+ {$DEFINE DELPHI8_UP}
+{$ENDIF}
+
+{$IFDEF DELPHI8_UP} {$DEFINE DELPHI7_UP} {$ENDIF}
+{$IFDEF DELPHI7_UP} {$DEFINE DELPHI6_UP} {$ENDIF}
+{$IFDEF DELPHI6_UP} {$DEFINE DELPHI5_UP} {$ENDIF}
+{$IFDEF DELPHI5_UP} {$DEFINE DELPHI4_UP} {$ENDIF}
+{$IFDEF DELPHI4_UP} {$DEFINE DELPHI3_UP} {$ENDIF}
+{$IFDEF DELPHI3_UP} {$DEFINE DELPHI2_UP} {$ENDIF}
+{$IFDEF DELPHI2_UP} {$DEFINE DELPHI1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BCBX_UP from BCBX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BCB17} {$DEFINE BCB17_UP} {$ENDIF}
+{$IFDEF BCB16} {$DEFINE BCB16_UP} {$ENDIF}
+{$IFDEF BCB15} {$DEFINE BCB15_UP} {$ENDIF}
+{$IFDEF BCB14} {$DEFINE BCB14_UP} {$ENDIF}
+{$IFDEF BCB12} {$DEFINE BCB12_UP} {$ENDIF}
+{$IFDEF BCB11} {$DEFINE BCB11_UP} {$ENDIF}
+{$IFDEF BCB10} {$DEFINE BCB10_UP} {$ENDIF}
+{$IFDEF BCB6} {$DEFINE BCB6_UP} {$ENDIF}
+{$IFDEF BCB5} {$DEFINE BCB5_UP} {$ENDIF}
+{$IFDEF BCB4} {$DEFINE BCB4_UP} {$ENDIF}
+{$IFDEF BCB3} {$DEFINE BCB3_UP} {$ENDIF}
+{$IFDEF BCB1} {$DEFINE BCB1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BCBX_UP from BCBX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BCB17_UP} {$DEFINE BCB16_UP} {$ENDIF}
+{$IFDEF BCB16_UP} {$DEFINE BCB15_UP} {$ENDIF}
+{$IFDEF BCB15_UP} {$DEFINE BCB14_UP} {$ENDIF}
+{$IFDEF BCB14_UP} {$DEFINE BCB12_UP} {$ENDIF}
+{$IFDEF BCB12_UP} {$DEFINE BCB11_UP} {$ENDIF}
+{$IFDEF BCB11_UP} {$DEFINE BCB10_UP} {$ENDIF}
+{$IFDEF BCB10_UP} {$DEFINE BCB6_UP} {$ENDIF}
+{$IFDEF BCB6_UP} {$DEFINE BCB5_UP} {$ENDIF}
+{$IFDEF BCB5_UP} {$DEFINE BCB4_UP} {$ENDIF}
+{$IFDEF BCB4_UP} {$DEFINE BCB3_UP} {$ENDIF}
+{$IFDEF BCB3_UP} {$DEFINE BCB1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BDSX_UP from BDSX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BDS10} {$DEFINE BDS10_UP} {$ENDIF}
+{$IFDEF BDS9} {$DEFINE BDS9_UP} {$ENDIF}
+{$IFDEF BDS8} {$DEFINE BDS8_UP} {$ENDIF}
+{$IFDEF BDS7} {$DEFINE BDS7_UP} {$ENDIF}
+{$IFDEF BDS6} {$DEFINE BDS6_UP} {$ENDIF}
+{$IFDEF BDS5} {$DEFINE BDS5_UP} {$ENDIF}
+{$IFDEF BDS4} {$DEFINE BDS4_UP} {$ENDIF}
+{$IFDEF BDS3} {$DEFINE BDS3_UP} {$ENDIF}
+{$IFDEF BDS2} {$DEFINE BDS2_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ BDSX_UP from BDSX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF BDS10_UP} {$DEFINE BDS9_UP} {$ENDIF}
+{$IFDEF BDS9_UP} {$DEFINE BDS8_UP} {$ENDIF}
+{$IFDEF BDS8_UP} {$DEFINE BDS7_UP} {$ENDIF}
+{$IFDEF BDS7_UP} {$DEFINE BDS6_UP} {$ENDIF}
+{$IFDEF BDS6_UP} {$DEFINE BDS5_UP} {$ENDIF}
+{$IFDEF BDS5_UP} {$DEFINE BDS4_UP} {$ENDIF}
+{$IFDEF BDS4_UP} {$DEFINE BDS3_UP} {$ENDIF}
+{$IFDEF BDS3_UP} {$DEFINE BDS2_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ DELPHICOMPILERX_UP from DELPHICOMPILERX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHICOMPILER17} {$DEFINE DELPHICOMPILER17_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER16} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER15} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER14} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER12} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER11} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER10} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER9} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER8} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER7} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER6} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER5} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER4} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER3} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER2} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER1} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ DELPHICOMPILERX_UP from DELPHICOMPILERX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHICOMPILER17_UP} {$DEFINE DELPHICOMPILER16_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER16_UP} {$DEFINE DELPHICOMPILER15_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER15_UP} {$DEFINE DELPHICOMPILER14_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER14_UP} {$DEFINE DELPHICOMPILER12_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER12_UP} {$DEFINE DELPHICOMPILER11_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER11_UP} {$DEFINE DELPHICOMPILER10_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER10_UP} {$DEFINE DELPHICOMPILER9_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER9_UP} {$DEFINE DELPHICOMPILER8_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER8_UP} {$DEFINE DELPHICOMPILER7_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER7_UP} {$DEFINE DELPHICOMPILER6_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER6_UP} {$DEFINE DELPHICOMPILER5_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER5_UP} {$DEFINE DELPHICOMPILER4_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER4_UP} {$DEFINE DELPHICOMPILER3_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER3_UP} {$DEFINE DELPHICOMPILER2_UP} {$ENDIF}
+{$IFDEF DELPHICOMPILER2_UP} {$DEFINE DELPHICOMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ COMPILERX_UP from COMPILERX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF COMPILER17} {$DEFINE COMPILER17_UP} {$ENDIF}
+{$IFDEF COMPILER16} {$DEFINE COMPILER16_UP} {$ENDIF}
+{$IFDEF COMPILER15} {$DEFINE COMPILER15_UP} {$ENDIF}
+{$IFDEF COMPILER14} {$DEFINE COMPILER14_UP} {$ENDIF}
+{$IFDEF COMPILER12} {$DEFINE COMPILER12_UP} {$ENDIF}
+{$IFDEF COMPILER11} {$DEFINE COMPILER11_UP} {$ENDIF}
+{$IFDEF COMPILER10} {$DEFINE COMPILER10_UP} {$ENDIF}
+{$IFDEF COMPILER9} {$DEFINE COMPILER9_UP} {$ENDIF}
+{$IFDEF COMPILER8} {$DEFINE COMPILER8_UP} {$ENDIF}
+{$IFDEF COMPILER7} {$DEFINE COMPILER7_UP} {$ENDIF}
+{$IFDEF COMPILER6} {$DEFINE COMPILER6_UP} {$ENDIF}
+{$IFDEF COMPILER5} {$DEFINE COMPILER5_UP} {$ENDIF}
+{$IFDEF COMPILER4} {$DEFINE COMPILER4_UP} {$ENDIF}
+{$IFDEF COMPILER35} {$DEFINE COMPILER35_UP} {$ENDIF}
+{$IFDEF COMPILER3} {$DEFINE COMPILER3_UP} {$ENDIF}
+{$IFDEF COMPILER2} {$DEFINE COMPILER2_UP} {$ENDIF}
+{$IFDEF COMPILER1} {$DEFINE COMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ COMPILERX_UP from COMPILERX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF COMPILER17_UP} {$DEFINE COMPILER16_UP} {$ENDIF}
+{$IFDEF COMPILER16_UP} {$DEFINE COMPILER15_UP} {$ENDIF}
+{$IFDEF COMPILER15_UP} {$DEFINE COMPILER14_UP} {$ENDIF}
+{$IFDEF COMPILER14_UP} {$DEFINE COMPILER12_UP} {$ENDIF}
+{$IFDEF COMPILER12_UP} {$DEFINE COMPILER11_UP} {$ENDIF}
+{$IFDEF COMPILER11_UP} {$DEFINE COMPILER10_UP} {$ENDIF}
+{$IFDEF COMPILER10_UP} {$DEFINE COMPILER9_UP} {$ENDIF}
+{$IFDEF COMPILER9_UP} {$DEFINE COMPILER8_UP} {$ENDIF}
+{$IFDEF COMPILER8_UP} {$DEFINE COMPILER7_UP} {$ENDIF}
+{$IFDEF COMPILER7_UP} {$DEFINE COMPILER6_UP} {$ENDIF}
+{$IFDEF COMPILER6_UP} {$DEFINE COMPILER5_UP} {$ENDIF}
+{$IFDEF COMPILER5_UP} {$DEFINE COMPILER4_UP} {$ENDIF}
+{$IFDEF COMPILER4_UP} {$DEFINE COMPILER35_UP} {$ENDIF}
+{$IFDEF COMPILER35_UP} {$DEFINE COMPILER3_UP} {$ENDIF}
+{$IFDEF COMPILER3_UP} {$DEFINE COMPILER2_UP} {$ENDIF}
+{$IFDEF COMPILER2_UP} {$DEFINE COMPILER1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ RTLX_UP from RTLX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF RTL240_UP} {$DEFINE RTL230_UP} {$ENDIF}
+{$IFDEF RTL230_UP} {$DEFINE RTL220_UP} {$ENDIF}
+{$IFDEF RTL220_UP} {$DEFINE RTL210_UP} {$ENDIF}
+{$IFDEF RTL210_UP} {$DEFINE RTL200_UP} {$ENDIF}
+{$IFDEF RTL200_UP} {$DEFINE RTL190_UP} {$ENDIF}
+{$IFDEF RTL190_UP} {$DEFINE RTL185_UP} {$ENDIF}
+{$IFDEF RTL185_UP} {$DEFINE RTL180_UP} {$ENDIF}
+{$IFDEF RTL180_UP} {$DEFINE RTL170_UP} {$ENDIF}
+{$IFDEF RTL170_UP} {$DEFINE RTL160_UP} {$ENDIF}
+{$IFDEF RTL160_UP} {$DEFINE RTL150_UP} {$ENDIF}
+{$IFDEF RTL150_UP} {$DEFINE RTL145_UP} {$ENDIF}
+{$IFDEF RTL145_UP} {$DEFINE RTL142_UP} {$ENDIF}
+{$IFDEF RTL142_UP} {$DEFINE RTL140_UP} {$ENDIF}
+{$IFDEF RTL140_UP} {$DEFINE RTL130_UP} {$ENDIF}
+{$IFDEF RTL130_UP} {$DEFINE RTL125_UP} {$ENDIF}
+{$IFDEF RTL125_UP} {$DEFINE RTL120_UP} {$ENDIF}
+{$IFDEF RTL120_UP} {$DEFINE RTL110_UP} {$ENDIF}
+{$IFDEF RTL110_UP} {$DEFINE RTL100_UP} {$ENDIF}
+{$IFDEF RTL100_UP} {$DEFINE RTL93_UP} {$ENDIF}
+{$IFDEF RTL93_UP} {$DEFINE RTL90_UP} {$ENDIF}
+{$IFDEF RTL90_UP} {$DEFINE RTL80_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ Check for CLR overrides of default detection }
+{------------------------------------------------------------------------------}
+
+{$IFDEF CLR}
+ {$IFDEF FORCE_CLR10}
+ {$DEFINE CLR10}
+ {$UNDEF CLR11}
+ {$UNDEF CLR20}
+ {$ENDIF FORCE_CLR10}
+
+ {$IFDEF FORCE_CLR11}
+ {$UNDEF CLR10}
+ {$DEFINE CLR11}
+ {$UNDEF CLR20}
+ {$ENDIF FORCE_CLR11}
+
+ {$IFDEF FORCE_CLR20}
+ {$UNDEF CLR10}
+ {$UNDEF CLR11}
+ {$DEFINE CLR20}
+ {$ENDIF FORCE_CLR20}
+{$ENDIF CLR}
+
+{------------------------------------------------------------------------------}
+{ CLRX from CLRX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF CLR10} {$DEFINE CLR10_UP} {$ENDIF}
+{$IFDEF CLR11} {$DEFINE CLR11_UP} {$ENDIF}
+{$IFDEF CLR20} {$DEFINE CLR20_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ CLRX_UP from CLRX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF CLR20_UP} {$DEFINE CLR11_UP} {$ENDIF}
+{$IFDEF CLR11_UP} {$DEFINE CLR10_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+
+{$IFDEF DELPHICOMPILER}
+ {$DEFINE DELPHILANGUAGE}
+{$ENDIF}
+
+{$IFDEF BCBCOMPILER}
+ {$DEFINE DELPHILANGUAGE}
+{$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ KYLIXX_UP from KYLIXX mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF KYLIX3} {$DEFINE KYLIX3_UP} {$ENDIF}
+{$IFDEF KYLIX2} {$DEFINE KYLIX2_UP} {$ENDIF}
+{$IFDEF KYLIX1} {$DEFINE KYLIX1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ KYLIXX_UP from KYLIXX_UP mappings }
+{------------------------------------------------------------------------------}
+
+{$IFDEF KYLIX3_UP} {$DEFINE KYLIX2_UP} {$ENDIF}
+{$IFDEF KYLIX2_UP} {$DEFINE KYLIX1_UP} {$ENDIF}
+
+{------------------------------------------------------------------------------}
+{ Map COMPILERX_UP to friendly feature names }
+{------------------------------------------------------------------------------}
+
+{$IFDEF FPC}
+ {$IFDEF VER1_0}
+ Please use FPC 2.0 or higher to compile this.
+ {$ELSE}
+ {$DEFINE SUPPORTS_OUTPARAMS}
+ {$DEFINE SUPPORTS_WIDECHAR}
+ {$DEFINE SUPPORTS_WIDESTRING}
+ {$IFDEF HASINTF}
+ {$DEFINE SUPPORTS_INTERFACE}
+ {$ENDIF}
+ {$IFDEF HASVARIANT}
+ {$DEFINE SUPPORTS_VARIANT}
+ {$ENDIF}
+ {$IFDEF FPC_HAS_TYPE_SINGLE}
+ {$DEFINE SUPPORTS_SINGLE}
+ {$ENDIF}
+ {$IFDEF FPC_HAS_TYPE_DOUBLE}
+ {$DEFINE SUPPORTS_DOUBLE}
+ {$ENDIF}
+ {$IFDEF FPC_HAS_TYPE_EXTENDED}
+ {$DEFINE SUPPORTS_EXTENDED}
+ {$ENDIF}
+ {$IFDEF HASCURRENCY}
+ {$DEFINE SUPPORTS_CURRENCY}
+ {$ENDIF}
+ {$DEFINE SUPPORTS_THREADVAR}
+ {$DEFINE SUPPORTS_CONSTPARAMS}
+ {$DEFINE SUPPORTS_LONGWORD}
+ {$DEFINE SUPPORTS_INT64}
+ {$DEFINE SUPPORTS_DYNAMICARRAYS}
+ {$DEFINE SUPPORTS_DEFAULTPARAMS}
+ {$DEFINE SUPPORTS_OVERLOAD}
+ {$DEFINE ACCEPT_DEPRECATED} // 2.2 also gives warnings
+ {$DEFINE ACCEPT_PLATFORM} // 2.2 also gives warnings
+ {$DEFINE ACCEPT_LIBRARY}
+ {$DEFINE SUPPORTS_EXTSYM}
+ {$DEFINE SUPPORTS_NODEFINE}
+
+ {$DEFINE SUPPORTS_CUSTOMVARIANTS}
+ {$DEFINE SUPPORTS_VARARGS}
+ {$DEFINE SUPPORTS_ENUMVALUE}
+ {$IFDEF LINUX}
+ {$DEFINE HAS_UNIT_LIBC}
+ {$ENDIF LINUX}
+ {$DEFINE HAS_UNIT_CONTNRS}
+ {$DEFINE HAS_UNIT_TYPES}
+ {$DEFINE HAS_UNIT_VARIANTS}
+ {$DEFINE HAS_UNIT_STRUTILS}
+ {$DEFINE HAS_UNIT_DATEUTILS}
+ {$DEFINE HAS_UNIT_RTLCONSTS}
+
+ {$DEFINE XPLATFORM_RTL}
+
+ {$IFDEF VER2_2}
+ {$DEFINE SUPPORTS_DISPINTERFACE}
+ {$DEFINE SUPPORTS_IMPLEMENTS}
+ {$DEFINE SUPPORTS_DISPID}
+ {$ELSE}
+ {$UNDEF SUPPORTS_DISPINTERFACE}
+ {$UNDEF SUPPORTS_IMPLEMENTS}
+ {$endif}
+ {$UNDEF SUPPORTS_UNSAFE_WARNINGS}
+ {$ENDIF}
+{$ENDIF FPC}
+
+{$IFDEF CLR}
+ {$DEFINE SUPPORTS_UNICODE}
+{$ENDIF CLR}
+
+{$IFDEF COMPILER1_UP}
+ {$DEFINE SUPPORTS_CONSTPARAMS}
+ {$DEFINE SUPPORTS_SINGLE}
+ {$DEFINE SUPPORTS_DOUBLE}
+ {$DEFINE SUPPORTS_EXTENDED}
+ {$DEFINE SUPPORTS_PACKAGES}
+{$ENDIF COMPILER1_UP}
+
+{$IFDEF COMPILER2_UP}
+ {$DEFINE SUPPORTS_CURRENCY}
+ {$DEFINE SUPPORTS_THREADVAR}
+ {$DEFINE SUPPORTS_VARIANT}
+ {$DEFINE SUPPORTS_WIDECHAR}
+{$ENDIF COMPILER2_UP}
+
+{$IFDEF COMPILER3_UP}
+ {$DEFINE SUPPORTS_OUTPARAMS}
+ {$DEFINE SUPPORTS_WIDESTRING}
+ {$DEFINE SUPPORTS_INTERFACE}
+ {$DEFINE SUPPORTS_DISPINTERFACE}
+ {$DEFINE SUPPORTS_DISPID}
+ {$DEFINE SUPPORTS_WEAKPACKAGEUNIT}
+{$ENDIF COMPILER3_UP}
+
+{$IFDEF COMPILER35_UP}
+ {$DEFINE SUPPORTS_EXTSYM}
+ {$DEFINE SUPPORTS_NODEFINE}
+{$ENDIF COMPILER35_UP}
+
+{$IFDEF COMPILER4_UP}
+ {$DEFINE SUPPORTS_LONGWORD}
+ {$DEFINE SUPPORTS_INT64}
+ {$DEFINE SUPPORTS_DYNAMICARRAYS}
+ {$DEFINE SUPPORTS_DEFAULTPARAMS}
+ {$DEFINE SUPPORTS_OVERLOAD}
+ {$DEFINE SUPPORTS_IMPLEMENTS}
+{$ENDIF COMPILER4_UP}
+
+{$IFDEF COMPILER6_UP}
+ {$DEFINE SUPPORTS_DEPRECATED}
+ {$DEFINE SUPPORTS_LIBRARY}
+ {$DEFINE SUPPORTS_PLATFORM}
+ {$DEFINE SUPPORTS_LOCAL}
+ {$DEFINE SUPPORTS_SETPEFLAGS}
+ {$DEFINE SUPPORTS_EXPERIMENTAL_WARNINGS}
+ {$DEFINE ACCEPT_DEPRECATED}
+ {$DEFINE ACCEPT_PLATFORM}
+ {$DEFINE ACCEPT_LIBRARY}
+ {$DEFINE SUPPORTS_DEPRECATED_WARNINGS}
+ {$DEFINE SUPPORTS_LIBRARY_WARNINGS}
+ {$DEFINE SUPPORTS_PLATFORM_WARNINGS}
+ {$DEFINE SUPPORTS_CUSTOMVARIANTS}
+ {$DEFINE SUPPORTS_VARARGS}
+ {$DEFINE SUPPORTS_ENUMVALUE}
+ {$DEFINE SUPPORTS_COMPILETIME_MESSAGES}
+{$ENDIF COMPILER6_UP}
+
+{$IFDEF COMPILER7_UP}
+ {$DEFINE SUPPORTS_UNSAFE_WARNINGS}
+{$ENDIF COMPILER7_UP}
+
+{$IFDEF COMPILER9_UP}
+ {$DEFINE SUPPORTS_FOR_IN}
+ {$DEFINE SUPPORTS_INLINE}
+ {$DEFINE SUPPORTS_NESTED_CONSTANTS}
+ {$DEFINE SUPPORTS_NESTED_TYPES}
+ {$DEFINE SUPPORTS_REGION}
+ {$IFDEF CLR}
+ {$DEFINE SUPPORTS_ENHANCED_RECORDS}
+ {$DEFINE SUPPORTS_CLASS_FIELDS}
+ {$DEFINE SUPPORTS_CLASS_HELPERS}
+ {$DEFINE SUPPORTS_CLASS_OPERATORS}
+ {$DEFINE SUPPORTS_STRICT}
+ {$DEFINE SUPPORTS_STATIC}
+ {$DEFINE SUPPORTS_FINAL}
+ {$ENDIF CLR}
+{$ENDIF COMPILER9_UP}
+
+{$IFDEF COMPILER10_UP}
+ {$DEFINE SUPPORTS_ENHANCED_RECORDS}
+ {$DEFINE SUPPORTS_CLASS_FIELDS}
+ {$DEFINE SUPPORTS_CLASS_HELPERS}
+ {$DEFINE SUPPORTS_CLASS_OPERATORS}
+ {$DEFINE SUPPORTS_STRICT}
+ {$DEFINE SUPPORTS_STATIC}
+ {$DEFINE SUPPORTS_FINAL}
+ {$DEFINE SUPPORTS_METHODINFO}
+{$ENDIF COMPILER10_UP}
+
+{$IFDEF COMPILER11_UP}
+ {$IFDEF CLR}
+ {$DEFINE SUPPORTS_GENERICS}
+ {$DEFINE SUPPORTS_DEPRECATED_DETAILS}
+ {$ENDIF CLR}
+{$ENDIF COMPILER11_UP}
+
+{$IFDEF COMPILER12_UP}
+ {$DEFINE SUPPORTS_GENERICS}
+ {$DEFINE SUPPORTS_DEPRECATED_DETAILS}
+ {$DEFINE SUPPORTS_INT_ALIASES}
+ {$IFNDEF CLR}
+ {$DEFINE SUPPORTS_UNICODE}
+ {$DEFINE SUPPORTS_UNICODE_STRING}
+ {$ENDIF CLR}
+{$ENDIF COMPILER12_UP}
+
+{$IFDEF COMPILER14_UP}
+ {$DEFINE SUPPORTS_CLASS_CTORDTORS}
+ {$DEFINE HAS_UNIT_RTTI}
+ {$DEFINE SUPPORTS_CAST_INTERFACE_TO_OBJ}
+ {$DEFINE SUPPORTS_DELAYED_LOADING}
+{$ENDIF COMPILER14_UP}
+
+{$IFDEF COMPILER16_UP}
+ {$DEFINE USE_64BIT_TYPES}
+{$ENDIF COMPILER16_UP}
+
+{$IFDEF RTL130_UP}
+ {$DEFINE HAS_UNIT_CONTNRS}
+{$ENDIF RTL130_UP}
+
+{$IFDEF RTL140_UP}
+ {$IFDEF LINUX}
+ {$DEFINE HAS_UNIT_LIBC}
+ {$ENDIF LINUX}
+ {$DEFINE HAS_UNIT_RTLCONSTS}
+ {$DEFINE HAS_UNIT_TYPES}
+ {$DEFINE HAS_UNIT_VARIANTS}
+ {$DEFINE HAS_UNIT_STRUTILS}
+ {$DEFINE HAS_UNIT_DATEUTILS}
+ {$DEFINE XPLATFORM_RTL}
+{$ENDIF RTL140_UP}
+
+{$IFDEF RTL170_UP}
+ {$DEFINE HAS_UNIT_HTTPPROD}
+{$ENDIF RTL170_UP}
+
+{$IFDEF RTL185_UP}
+ {$DEFINE HAS_UNIT_GIFIMG}
+{$ENDIF RTL185_UP}
+
+{$IFDEF RTL200_UP}
+ {$DEFINE HAS_UNIT_ANSISTRINGS}
+ {$DEFINE HAS_UNIT_PNGIMAGE}
+ {$DEFINE HAS_UNIT_CHARACTER}
+{$ENDIF RTL200_UP}
+
+{$IFDEF RTL220_UP}
+ {$DEFINE SUPPORTS_UINT64}
+ {$DEFINE HAS_UNIT_REGULAREXPRESSIONSAPI}
+{$ENDIF RTL220_UP}
+
+{$IFDEF RTL230_UP}
+ {$DEFINE HAS_UNITSCOPE}
+ {$DEFINE HAS_UNIT_SYSTEM_UITYPES}
+{$ENDIF RTL230_UP}
+
+{$IFDEF RTL240_UP}
+ {$DEFINE HAS_UNIT_SYSTEM_ACTIONS}
+{$ENDIF RTL240_UP}
+
+{------------------------------------------------------------------------------}
+{ Cross-platform related defines }
+{------------------------------------------------------------------------------}
+
+{$IFNDEF CPUASM}
+ {$DEFINE PUREPASCAL}
+{$ENDIF ~CPUASM}
+
+{$IFDEF WIN32}
+ {$DEFINE MSWINDOWS} // predefined for D6+/BCB6+
+ {$DEFINE Win32API}
+{$ENDIF}
+
+{$IFDEF DELPHILANGUAGE}
+ {$IFDEF LINUX}
+ {$DEFINE UNIX}
+ {$ENDIF}
+
+ {$IFNDEF CONSOLE}
+ {$IFDEF LINUX}
+ {$DEFINE VisualCLX}
+ {$ENDIF}
+ {$IFNDEF VisualCLX}
+ {$DEFINE VCL}
+ {$ENDIF}
+ {$ENDIF ~CONSOLE}
+{$ENDIF DELPHILANGUAGE}
+
+{------------------------------------------------------------------------------}
+{ Compiler settings }
+{------------------------------------------------------------------------------}
+
+{$IFOPT A+} {$DEFINE ALIGN_ON} {$ENDIF}
+{$IFOPT B+} {$DEFINE BOOLEVAL_ON} {$ENDIF}
+{$IFDEF COMPILER2_UP}
+ {$IFOPT C+} {$DEFINE ASSERTIONS_ON} {$ENDIF}
+{$ENDIF}
+{$IFOPT D+} {$DEFINE DEBUGINFO_ON} {$ENDIF}
+{$IFOPT G+} {$DEFINE IMPORTEDDATA_ON} {$ENDIF}
+{$IFDEF COMPILER2_UP}
+ {$IFOPT H+} {$DEFINE LONGSTRINGS_ON} {$ENDIF}
+{$ENDIF}
+
+// Hints
+{$IFOPT I+} {$DEFINE IOCHECKS_ON} {$ENDIF}
+{$IFDEF COMPILER2_UP}
+ {$IFOPT J+} {$DEFINE WRITEABLECONST_ON} {$ENDIF}
+{$ENDIF}
+{$IFOPT L+} {$DEFINE LOCALSYMBOLS} {$DEFINE LOCALSYMBOLS_ON} {$ENDIF}
+{$IFOPT M+} {$DEFINE TYPEINFO_ON} {$ENDIF}
+{$IFOPT O+} {$DEFINE OPTIMIZATION_ON} {$ENDIF}
+{$IFOPT P+} {$DEFINE OPENSTRINGS_ON} {$ENDIF}
+{$IFOPT Q+} {$DEFINE OVERFLOWCHECKS_ON} {$ENDIF}
+{$IFOPT R+} {$DEFINE RANGECHECKS_ON} {$ENDIF}
+
+// Real compatibility
+{$IFOPT T+} {$DEFINE TYPEDADDRESS_ON} {$ENDIF}
+{$IFOPT U+} {$DEFINE SAFEDIVIDE_ON} {$ENDIF}
+{$IFOPT V+} {$DEFINE VARSTRINGCHECKS_ON} {$ENDIF}
+{$IFOPT W+} {$DEFINE STACKFRAMES_ON} {$ENDIF}
+
+// Warnings
+{$IFOPT X+} {$DEFINE EXTENDEDSYNTAX_ON} {$ENDIF}
+
+// for Delphi/BCB trial versions remove the point from the line below
+{.$UNDEF SUPPORTS_WEAKPACKAGEUNIT}
+
+{$ENDIF ~JEDI_INC}
diff --git a/plugins/MirandaNGHistoryToDB/langs/English.xml b/plugins/MirandaNGHistoryToDB/langs/English.xml
new file mode 100644
index 0000000000..b5fdedbc2b
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/langs/English.xml
@@ -0,0 +1,505 @@
+<?xml version="1.0" encoding="utf-8"?>
+<strings>
+ <MainFormCaption>HistoryToDB</MainFormCaption>
+ <ShowSearchButton>Search in the message window</ShowSearchButton>
+ <ClearListButton>Clear the message</ClearListButton>
+ <SyncButton>Sync history</SyncButton>
+ <ImportButton>Import history</ImportButton>
+ <ImportPM_ICQ>From the history of ICQ 7 and above</ImportPM_ICQ>
+ <ImportPM_RnQ>From the history of RnQ</ImportPM_RnQ>
+ <ImportPM_QIP2005>From the history of QIP 2005</ImportPM_QIP2005>
+ <ImportPM_QIPInfium>From the history of QIP 2010/Infium/2012</ImportPM_QIPInfium>
+ <ImportPM_Miranda>From the history of Miranda</ImportPM_Miranda>
+ <ImportPM_qutIM>From the history of qutIM</ImportPM_qutIM>
+ <SettingsButton>Settings</SettingsButton>
+ <LTitleIM>History of %s (%s)</LTitleIM>
+ <LTitleCHAT>History of chat "%s" (%s)</LTitleCHAT>
+ <LTitleIMSmall>History of %s</LTitleIMSmall>
+ <LHistory1>History with </LHistory1>
+ <LHistory2>to</LHistory2>
+ <SearchHistoryButton>Show</SearchHistoryButton>
+ <SearchButton>Search</SearchButton>
+ <SearchCaption>Search</SearchCaption>
+ <SearchMessage>No matches found.</SearchMessage>
+ <IMButtonCaption>Message history in %s</IMButtonCaption>
+ <CHATButtonCaption>History of the chat messages in %s</CHATButtonCaption>
+ <InfoCaption>Information</InfoCaption>
+ <IMNoTab>There is not one open tab.</IMNoTab>
+ <CHATNoTab>There is no open tabs chat.</CHATNoTab>
+ <IMCaption>Message history</IMCaption>
+ <CHATCaption>Chat history</CHATCaption>
+ <SearchContact>Search contact</SearchContact>
+ <ButtonRefreshHistory>Refresh history</ButtonRefreshHistory>
+ <ButtonSaveHistory>Save history</ButtonSaveHistory>
+ <ButtonDeleteHistory>Delete history</ButtonDeleteHistory>
+ <ButtonDeleteCurrentHistory>Delete history of the current contact</ButtonDeleteCurrentHistory>
+ <ButtonDeleteAllHistory>Delete history</ButtonDeleteAllHistory>
+ <NoDeleteSelectHistory>Not selected for removal of contact history</NoDeleteSelectHistory>
+ <NoSelectContactHistory>Select a contact search history</NoSelectContactHistory>
+ <NoSelectContactRefreshHistory>Select the contact to refresh history</NoSelectContactRefreshHistory>
+ <DeleteHistoryCaption>Delete</DeleteHistoryCaption>
+ <DeleteHistory>History of the selected contact will be deleted. Are you sure?</DeleteHistory>
+ <DeleteAllHistory>History of all contacts and chat rooms will be deleted. Are you sure?</DeleteAllHistory>
+ <Copy>Copy</Copy>
+ <SelectAll>Select all</SelectAll>
+ <DeSelectAll>Unselect all</DeSelectAll>
+ <SendSyncQuery>[%s] HistoryToDBSync sent a request to synchronize history</SendSyncQuery>
+ <ShowHistoryDay>Show history for the day</ShowHistoryDay>
+ <ShowHistoryMonth>Show history for the month</ShowHistoryMonth>
+ <ShowHistoryYear>Show history for the year</ShowHistoryYear>
+ <ShowHistoryAll>Show history for the entire period</ShowHistoryAll>
+ <GIFStaticText>Loading, please wait...</GIFStaticText>
+ <Settings>Settings</Settings>
+ <SettingsPageControlMainTab>Database</SettingsPageControlMainTab>
+ <SettingsPageControlSyncTab>Synchronization</SettingsPageControlSyncTab>
+ <SettingsPageControlInterfaceTab>Interface</SettingsPageControlInterfaceTab>
+ <SettingsPageControlEventsTab>Events</SettingsPageControlEventsTab>
+ <SettingsPageControlFontsTab>Fonts and more</SettingsPageControlFontsTab>
+ <SettingsPageControlEncryptionTab>Encryption history</SettingsPageControlEncryptionTab>
+ <SettingsPageControlHotKeyTab>Hot keys</SettingsPageControlHotKeyTab>
+ <SettingsPageControlAboutTab>About</SettingsPageControlAboutTab>
+ <DBGroupBox> Database </DBGroupBox>
+ <SyncGroupBox> Synchronization history </SyncGroupBox>
+ <EventsGroupBox> Events </EventsGroupBox>
+ <LDBConnectMethod>Connecting method:</LDBConnectMethod>
+ <LDBType>DB type:</LDBType>
+ <LDBAddress>DB address:</LDBAddress>
+ <LDBOracleSchema>Schema:</LDBOracleSchema>
+ <LDBPort>DB port:</LDBPort>
+ <LDBName>DB name:</LDBName>
+ <LDBNameOracle>TNS Name:</LDBNameOracle>
+ <LDBLogin>Login:</LDBLogin>
+ <LDBPasswd>Password:</LDBPasswd>
+ <TestConnectionButton>Check database connection</TestConnectionButton>
+ <CBDBConnectMethodDirect>Directly</CBDBConnectMethodDirect>
+ <LSyncMethod>Synchronization method:</LSyncMethod>
+ <LSyncInterval>Synchronization interval:</LSyncInterval>
+ <CBSyncMethodAuto>Automatic</CBSyncMethodAuto>
+ <CBSyncMethodManual>Manually</CBSyncMethodManual>
+ <CBSyncMethodOnSchedule>On schedule</CBSyncMethodOnSchedule>
+ <CBSyncInterval5Min>Every 5 minutes</CBSyncInterval5Min>
+ <CBSyncInterval10Min>Every 10 minutes</CBSyncInterval10Min>
+ <CBSyncInterval20Min>Every 20 minutes</CBSyncInterval20Min>
+ <CBSyncInterval30Min>Every 30 minutes</CBSyncInterval30Min>
+ <CBSyncIntervalExitProgram>When you exit the program</CBSyncIntervalExitProgram>
+ <CBSyncInterval10Mes>After 10 messages</CBSyncInterval10Mes>
+ <CBSyncInterval20Mes>After 20 messages</CBSyncInterval20Mes>
+ <CBSyncInterval30Mes>After 30 messages</CBSyncInterval30Mes>
+ <CBSyncIntervalNMin>Every N minutes</CBSyncIntervalNMin>
+ <CBSyncIntervalNMes>After N messages</CBSyncIntervalNMes>
+ <GBSyncCustomInterval> User intervals </GBSyncCustomInterval>
+ <LTimeInterval>Interval of time (min.):</LTimeInterval>
+ <LMsgCountInterval>Interval of count message:</LMsgCountInterval>
+ <CBEnableEncryption>Enable encryption message history</CBEnableEncryption>
+ <CBAni>Show pop-up messages</CBAni>
+ <CBWriteErrLog>Write errors to a log file</CBWriteErrLog>
+ <CBHideSyncIcon>Hide HistoryToDBSync icon from the tray</CBHideSyncIcon>
+ <LNumLastHistoryMsg>Number of recent messages to display in the window history of correspondence</LNumLastHistoryMsg>
+ <CBShowPluginButton>Add the button plug-in to modules panel (for only IM-client QIP 2012 and RnQ)</CBShowPluginButton>
+ <SaveButton>Save settings</SaveButton>
+ <CloseButton>Close</CloseButton>
+ <GBKeys> Encryption keys </GBKeys>
+ <DBGridKeysColumnID>Key number</DBGridKeysColumnID>
+ <DBGridKeysColumnSTATUS>Key status</DBGridKeysColumnSTATUS>
+ <DBGridKeysColumnMETHOD>Encryption method</DBGridKeysColumnMETHOD>
+ <ButtonGetEncryptionKey>Get encryption keys</ButtonGetEncryptionKey>
+ <ButtonCreateEncryptionKey>Create a new key</ButtonCreateEncryptionKey>
+ <UpdateCaption>Update</UpdateCaption>
+ <UpdateMessage1>Attention!</UpdateMessage1>
+ <UpdateMessage2>A new version of the program.</UpdateMessage2>
+ <UpdateMessage3>Please visit the official website for updates.</UpdateMessage3>
+ <UpdateMessage4>The structure of your database is outdated.</UpdateMessage4>
+ <UpdateMessage5>Program version: %s</UpdateMessage5>
+ <UpdateMessage6>Database version: %s</UpdateMessage6>
+ <GoodDBConnect1>Table configuration is successfully read.</GoodDBConnect1>
+ <GoodDBConnect2>Connecting to the database is successfully established.</GoodDBConnect2>
+ <ErrCaption>Error</ErrCaption>
+ <ErrVersionCheck>Unable to verify the version of the plugin.</ErrVersionCheck>
+ <ErrDBConnect>Unable to connect to the database.</ErrDBConnect>
+ <ErrSQLQuery>Error SQL query.</ErrSQLQuery>
+ <ErrSQLExecQuery>Error SQLExec query.</ErrSQLExecQuery>
+ <ErrDBParamCheck1>Please enter "DB address"</ErrDBParamCheck1>
+ <ErrDBParamCheck2>Please enter "DB port"</ErrDBParamCheck2>
+ <ErrDBParamCheck3>Please enter "Password"</ErrDBParamCheck3>
+ <ErrDBParamCheck4>Please enter "Login"</ErrDBParamCheck4>
+ <ErrDBParamCheck5>Please enter "DB name"</ErrDBParamCheck5>
+ <ErrDBParamCheck6>Please enter "Schema"</ErrDBParamCheck6>
+ <ErrDBParamCheck7>Please enter "TNS Name"</ErrDBParamCheck7>
+ <SettingsSave>Settings have been saved.</SettingsSave>
+ <SettingsErrSave>Unable to save the settings.</SettingsErrSave>
+ <SettingsErrRead>Unable to read the settings.</SettingsErrRead>
+ <SendCheckMD5HashQuery>[%s] HistoryToDBSync sent a request to recalculate the MD5-hashes</SendCheckMD5HashQuery>
+ <SendCheckAndDeleteMD5HashQuery>[%s] HistoryToDBSync sent a request to recalculate the MD5-hashes and remove duplicate messages</SendCheckAndDeleteMD5HashQuery>
+ <DBServiceButton>Database service</DBServiceButton>
+ <CheckMD5Hash>Recalculate of all the MD5-hashes in the database</CheckMD5Hash>
+ <CheckAndDeleteMD5Hash>Recalculate of all the MD5-hashes in the database and remove duplicate messages</CheckAndDeleteMD5Hash>
+ <CBAddSpecialContact>Add special-contact (for only IM-client QIP 2012)</CBAddSpecialContact>
+ <GBMessageFonts> Fonts </GBMessageFonts>
+ <TitleSpacingBox> Spacing for the header </TitleSpacingBox>
+ <MessagesSpacingBox> Spacing for text </MessagesSpacingBox>
+ <LIncommingMesTitle>Font header for incomming:</LIncommingMesTitle>
+ <LOutgoingMesTitle>Font header for outgoing:</LOutgoingMesTitle>
+ <LIncommingMes>Font for incoming messages:</LIncommingMes>
+ <LOutgoingMes>Font for outgoing messages:</LOutgoingMes>
+ <LServiceMes>Font for service messages:</LServiceMes>
+ <LSpacingBefore>Spacing before:</LSpacingBefore>
+ <LSpacingAfter>Spacing after:</LSpacingAfter>
+ <ExSearch>Find</ExSearch>
+ <ExSearchNext>Find more...</ExSearchNext>
+ <CBHotKey>Activate global keyboard shortcuts</CBHotKey>
+ <SetHotKeyButton>Assign</SetHotKeyButton>
+ <DeleteHotKeyButton>Remove</DeleteHotKeyButton>
+ <GBHotKey> Shortcuts </GBHotKey>
+ <OpenLogFileCaption>Failed to open file</OpenLogFileCaption>
+ <OpenLogFile>Failed to open file %s</OpenLogFile>
+ <OpenLogFileRepeat>Try again?</OpenLogFileRepeat>
+ <OpenLogFileLock>File to take another program.</OpenLogFileLock>
+ <MessageEncrypted>WARNING! This message is encrypted. Perhaps you entered an incorrect password or encryption key in the database is not found the right key to decrypt the message.</MessageEncrypted>
+ <LErrLogSize>The maximum size of log file errors (Kbyte)</LErrLogSize>
+ <Rename>Rename</Rename>
+ <Merge>Merge</Merge>
+ <Delete>Delete</Delete>
+ <GetContactListButton>Save contact list</GetContactListButton>
+ <UpdateContactListButton>Update contact information in the DB</UpdateContactListButton>
+ <CheckUpdateButton>Check for updates</CheckUpdateButton>
+ <SaveContactListCompleted>A list of contacts and protocols stored.</SaveContactListCompleted>
+ <SaveContactListErr>Error! Contact list and protocols are not saved or stored properly.</SaveContactListErr>
+ <SendUpdateContactListCompleted>Sent a request to update the list of contacts in the database.</SendUpdateContactListCompleted>
+ <SendUpdateContactListErr>The file %s to update your contact list can not be found. Request for update is not sent.</SendUpdateContactListErr>
+ <ContactNotInTheList>Not in the list</ContactNotInTheList>
+ <UpdateContactListInDB>Update contact information in the DB (Nickname и UserID)</UpdateContactListInDB>
+ <GIFStaticTextDelete>Please wait, is removal of the history...</GIFStaticTextDelete>
+ <SendUpdateContactListInDB>[%s] HistoryToDBSync sent a request to update the contact list from a file %s</SendUpdateContactListInDB>
+ <SendUpdateContactListInDBErrQIP>[%s] File %s to update your contact list can not be found. Please, select 'Save contact list' in the context menu, Other contacts QIPHistoryToDB.</SendUpdateContactListInDBErrQIP>
+ <SendUpdateContactListInDBErrRnQ>[%s] The file %s to update your contact list can not be found. Select 'Save contact list' in the context menu RnQHistoryToDB in the chat window.</SendUpdateContactListInDBErrRnQ>
+ <SendUpdateContactListInDBErrUnknown>[%s] The file %s to update your contact list can not be found. Select 'Save contact list' in the context menu plugin.</SendUpdateContactListInDBErrUnknown>
+ <SendStopSync>[%s] HistoryToDBSync sent a request to disable synchronization of the history of the file %s.</SendStopSync>
+ <SendStartSync>[%s] HistoryToDBSync sent a request to enable synchronization of the history of the file %s.</SendStartSync>
+ <ShowContactHistory>Message history %s (%s) in HistoryToDBViewer</ShowContactHistory>
+ <ShowOneContactHistory>History in HistoryToDBViewer</ShowOneContactHistory>
+ <CBBlockSpamMsg>Do not write messages in the DB marked as spam (for only IM-client QIP 2012)</CBBlockSpamMsg>
+ <ErrKeyPassword>Error: Invalid password encryption key. Enter the correct password or reading encrypted messages will be impossible.</ErrKeyPassword>
+ <Transparency> Transparency </Transparency>
+ <TransparencyEnable>Enable transparency windows</TransparencyEnable>
+ <LThankYou>Thank you</LThankYou>
+ <CBExPrivateChatName>Use the expanded name for private chat (ChatName / Nickname)</CBExPrivateChatName>
+ <TotalString>Total lines:</TotalString>
+ <LoadingTime>Time to all lines:</LoadingTime>
+ <MSec>ms</MSec>
+ <DeleteLogFileCaption>Failed to delete file</DeleteLogFileCaption>
+ <DeleteLogFile>Failed to delete file %s</DeleteLogFile>
+ <DeleteLogFileRepeat>Try again?</DeleteLogFileRepeat>
+ <Additionally> Additionally </Additionally>
+ <SyncWhenExit>Synchronize history when you close the IM-client</SyncWhenExit>
+ <EnableSkypeSupport>Enable support for Skype</EnableSkypeSupport>
+ <LangButton>Language</LangButton>
+ <Language>Language:</Language>
+ <CBWriteDebugLog>Enable debug logging</CBWriteDebugLog>
+ <ExportAllHistoryButton>Export history</ExportAllHistoryButton>
+ <ExortFormCaption>Export history</ExortFormCaption>
+ <ButtonBack>Back</ButtonBack>
+ <ButtonNext>Next</ButtonNext>
+ <ButtonFinish>Exit</ButtonFinish>
+ <ButtonCancel>Cancel</ButtonCancel>
+ <IMExportWizardPage0Title>Welcome to the export wizard history</IMExportWizardPage0Title>
+ <IMExportWizardPage0SubTitle>This wizard helps you export the story of %s to the external database. Exports will be made to a file in sql-insert. When you synchronize the data will be transmitted to the database.</IMExportWizardPage0SubTitle>
+ <IMExportWizardPage1Title>Export Wizard history</IMExportWizardPage1Title>
+ <IMExportWizardPage1SubTitle>Select the contacts whose history you want to export.</IMExportWizardPage1SubTitle>
+ <IMExportWizardPage2Title>Export Wizard history</IMExportWizardPage2Title>
+ <IMExportWizardPage2SubTitle>There is a history of exporting, please wait...</IMExportWizardPage2SubTitle>
+ <IMExportWizardPage3Title>Export Wizard history</IMExportWizardPage3Title>
+ <IMExportWizardPage3SubTitle>Export of finished history.</IMExportWizardPage3SubTitle>
+ <NickName>Nickname</NickName>
+ <Protocol>Protocol</Protocol>
+ <Number>UserID</Number>
+ <TotalSelect>Total selected %s contacts from %s</TotalSelect>
+ <ContactExport>Export history of contact %s (%s) ...</ContactExport>
+ <ExportDone>Export of finished history.</ExportDone>
+ <ExportAbort>Are you sure you want to cancel the export and exit the wizard?</ExportAbort>
+ <ExportAbortCaption>Out of the Export Wizard</ExportAbortCaption>
+ <ExportDoneDesc>Export of finished histori. Now you can send a request to synchronize the history of the exported database. A high volume of exported history synchronization procedure can be done a long time.</ExportDoneDesc>
+ <SendSyncRequest>Send a request to synchronize</SendSyncRequest>
+ <MirandaImportInfo>Import messages from the database directly from the Miranda of the IM-client.</MirandaImportInfo>
+ <HistoryToDBSyncCLUpdateErr>During the upgrade, contact list error.</HistoryToDBSyncCLUpdateErr>
+ <HistoryToDBSyncMD5Err>During recalculation of MD5-hash error.</HistoryToDBSyncMD5Err>
+ <SeeErrLog>For additional information, see the log files.</SeeErrLog>
+ <HistoryToDBSyncStartTrayMsg>Running the synchronization of messages...</HistoryToDBSyncStartTrayMsg>
+ <DBReConnectNum>[%s] We make %s attempts to reconnect to the database.</DBReConnectNum>
+ <DBReConnectErr>[%s] Failed to reconnect to the database.</DBReConnectErr>
+ <DBReconnectCount>Number of reconnection attempts:</DBReconnectCount>
+ <DBReconnectInterval>Reconnect interval (ms):</DBReconnectInterval>
+ <AutoScrollText>Auto scrolling messages</AutoScrollText>
+ <AutoRunHistoryToDBSync>HistoryToDBSync run at Windows startup</AutoRunHistoryToDBSync>
+ <RunningSkypeOnStartup>Start Skype with HistoryToDBSync</RunningSkypeOnStartup>
+ <ExitSkypeOnEnd>Shutdown Skype when you close HistoryToDBSync</ExitSkypeOnEnd>
+ <UpdateServerInServiceMode>Update server is down for maintenance.%sTry to start the procedure to check for updates later.</UpdateServerInServiceMode>
+
+ <AboutButton>About</AboutButton>
+ <AboutFormCaption>About</AboutFormCaption>
+ <Version>Version: </Version>
+ <License>License: </License>
+
+ <ERR_SAVE_TO_DB_CONNECT_ERR>[%s] Error: Unable to connect to the database. Error: %s</ERR_SAVE_TO_DB_CONNECT_ERR>
+ <ERR_SAVE_TO_DB_SERVICE_MODE>[%s] Error: Database on service mode. Saving messages in the database is impossible.</ERR_SAVE_TO_DB_SERVICE_MODE>
+ <ERR_TEMP_SAVE_TO_DB_SERVICE_MODE>[%s] Error: Database on service mode. Saving of pending messages in the database is impossible.</ERR_TEMP_SAVE_TO_DB_SERVICE_MODE>
+ <ERR_READ_DB_CONNECT_ERR>[%s] Error: Unable to connect to the database. Error: %s</ERR_READ_DB_CONNECT_ERR>
+ <ERR_READ_DB_SERVICE_MODE>[%s] Error: Unable to perform operation. Database on service mode.</ERR_READ_DB_SERVICE_MODE>
+ <ERR_LOAD_MSG_TO_DB>[%s] Write error messages from the log file to the database: %s</ERR_LOAD_MSG_TO_DB>
+ <ERR_SEND_UPDATE>[%s] Error in query update: %s</ERR_SEND_UPDATE>
+ <LOAD_TEMP_MSG>[%s] The file %s found %s messages; Loaded in DB: %s; Bad: %s; Duplicate: %s; Encrypted: %s</LOAD_TEMP_MSG>
+ <LOAD_TEMP_MSG_SCREEN>Found %s messages; Loaded in DB: %s; Bad: %s; Duplicate: %s; Encrypted: %s</LOAD_TEMP_MSG_SCREEN>
+ <LOAD_TEMP_MSG_NOLOGFILE>[%s] File pending message %s not found.</LOAD_TEMP_MSG_NOLOGFILE>
+ <LOAD_TEMP_MSG_NOMSGFILE>Message file %s not found.</LOAD_TEMP_MSG_NOMSGFILE>
+ <ERR_NO_DB_CONNECTED>[%s] Database connection is not established.</ERR_NO_DB_CONNECTED>
+ <ERR_NO_FOUND_VIEWER>History viewer %s not found.</ERR_NO_FOUND_VIEWER>
+ <ERR_NO_FOUND_SYNC>The history synchronization program %s not found.</ERR_NO_FOUND_SYNC>
+ <ERR_NO_FOUND_UPDATER>Update program %s not found.</ERR_NO_FOUND_UPDATER>
+ <ERR_OLD_SDK_VER>Wrong SDK version. To work needed QIP 2012 and above.</ERR_OLD_SDK_VER>
+ <ERR_NO_FOUND_IMPORT>The history import program %s not found.</ERR_NO_FOUND_IMPORT>
+ <ERR_DB_SERVICE_MODE>Unable to perform operation. Database on service mode.</ERR_DB_SERVICE_MODE>
+
+ <HistoryToDBSyncPopupMenuShow>Show</HistoryToDBSyncPopupMenuShow>
+ <HistoryToDBSyncPopupMenuHide>Hide</HistoryToDBSyncPopupMenuHide>
+ <HistoryToDBSyncPopupMenuSync>Synchronization</HistoryToDBSyncPopupMenuSync>
+ <HistoryToDBSyncPopupMenuSettings>Settings</HistoryToDBSyncPopupMenuSettings>
+ <HistoryToDBSyncPopupMenuShowAbout>About</HistoryToDBSyncPopupMenuShowAbout>
+ <HistoryToDBSyncPopupMenuShowExit>Exit</HistoryToDBSyncPopupMenuShowExit>
+ <HistoryToDBSyncGroupBox> Synchronization history </HistoryToDBSyncGroupBox>
+ <HistoryToDBSyncStatus>Synchronization status:</HistoryToDBSyncStatus>
+ <HistoryToDBSyncDone>Synchronization is done</HistoryToDBSyncDone>
+ <HistoryToDBSyncStart>Start synchronization</HistoryToDBSyncStart>
+ <HistoryToDBSyncStop>Stop synchronization</HistoryToDBSyncStop>
+ <HistoryToDBSyncStarted>Synchronization running</HistoryToDBSyncStarted>
+ <HistoryToDBSyncStoped>Synchronization stopped</HistoryToDBSyncStoped>
+ <HistoryToDBSyncFileNotFound>File synchronization can not be found</HistoryToDBSyncFileNotFound>
+ <HistoryToDBSyncStartCount>Running time of report... (%s sec.)</HistoryToDBSyncStartCount>
+ <HistoryToDBSyncWaitReq>Waiting for a synchronization request</HistoryToDBSyncWaitReq>
+ <HistoryToDBSyncNotSpecified>Not specified</HistoryToDBSyncNotSpecified>
+ <HistoryToDBSyncUnknownIMClient>Unknown type IM-client. Updating the database is impossible.</HistoryToDBSyncUnknownIMClient>
+ <HistoryToDBSyncUpdateDone>Database successfully updated.</HistoryToDBSyncUpdateDone>
+ <HistoryToDBSyncUpdateErr>An error occurred when update the database. Look in the log file.</HistoryToDBSyncUpdateErr>
+ <HistoryToDBSyncLTotalMesCountDesc>Total messages:</HistoryToDBSyncLTotalMesCountDesc>
+ <HistoryToDBSyncLMesCurrentCountDesc>Added to database:</HistoryToDBSyncLMesCurrentCountDesc>
+ <HistoryToDBSyncLBadMesCountDesc>Total error adding:</HistoryToDBSyncLBadMesCountDesc>
+ <HistoryToDBSyncLStartTimeDesc>Up time:</HistoryToDBSyncLStartTimeDesc>
+ <HistoryToDBSyncLEndTimeDesc>Time left:</HistoryToDBSyncLEndTimeDesc>
+ <HistoryToDBSyncLDublicateMesCountDesc>Found dublicates:</HistoryToDBSyncLDublicateMesCountDesc>
+ <HistoryToDBSyncLogViewButton>Log-file</HistoryToDBSyncLogViewButton>
+ <HistoryToDBSyncLogFormCaption>View the log file</HistoryToDBSyncLogFormCaption>
+ <HistoryToDBSyncLogFormFileName>Log-file name:</HistoryToDBSyncLogFormFileName>
+ <HistoryToDBSyncLogFormDeleteLogButton>Delete the log file</HistoryToDBSyncLogFormDeleteLogButton>
+ <HistoryToDBSyncLogFormReloadLogButton>Update</HistoryToDBSyncLogFormReloadLogButton>
+ <HistoryToDBSyncLTotalHashMsgСountDesc>Total messages for the analysis:</HistoryToDBSyncLTotalHashMsgСountDesc>
+ <HistoryToDBSyncLTotalBrokenMD5HashСountDesc>MD5-hash error:</HistoryToDBSyncLTotalBrokenMD5HashСountDesc>
+ <HistoryToDBSyncLTotalChangeMD5HashСountDesc>Fixed MD5-hash:</HistoryToDBSyncLTotalChangeMD5HashСountDesc>
+ <HistoryToDBSyncLMD5DublicateMesCountDesc>Found duplicates:</HistoryToDBSyncLMD5DublicateMesCountDesc>
+ <HistoryToDBSyncLDeletedMD5DublicateMesCountDesc>Removed duplicate:</HistoryToDBSyncLDeletedMD5DublicateMesCountDesc>
+ <HistoryToDBSyncKeyPasswdCaption>Entering a password</HistoryToDBSyncKeyPasswdCaption>
+ <HistoryToDBSyncGBPasswd> Enter the encryption key password </HistoryToDBSyncGBPasswd>
+ <HistoryToDBSyncKeyPasswordCaption>Entering a password</HistoryToDBSyncKeyPasswordCaption>
+ <HistoryToDBSyncErrKeyPassword>Error: Wrong key password. Enter the correct password or encryption of messages is not available.</HistoryToDBSyncErrKeyPassword>
+ <HistoryToDBSyncErrActiveKey>Error: Could not find the active key</HistoryToDBSyncErrActiveKey>
+ <HistoryToDBSyncMultiActiveKey>Error: There is more than one active key</HistoryToDBSyncMultiActiveKey>
+ <HistoryToDBSyncLKeyNumTitle>Key number:</HistoryToDBSyncLKeyNumTitle>
+ <HistoryToDBSyncLKeyPasswdTitle>Key password:</HistoryToDBSyncLKeyPasswdTitle>
+ <HistoryToDBSyncButtonGo>Enter</HistoryToDBSyncButtonGo>
+ <HistoryToDBSyncButtonExit>Cancel</HistoryToDBSyncButtonExit>
+ <HistoryToDBSyncCBSaveOnly>Remember the password for this session</HistoryToDBSyncCBSaveOnly>
+ <HistoryToDBSyncCBSave>Save all passwords</HistoryToDBSyncCBSave>
+ <HistoryToDBSyncErrDecryptKey>Unknown error decrypting the encryption key.</HistoryToDBSyncErrDecryptKey>
+ <HistoryToDBSyncCheckEncKey>Check the encryption key</HistoryToDBSyncCheckEncKey>
+ <HistoryToDBSyncLEncryptMesCountDesc>Encrypt message:</HistoryToDBSyncLEncryptMesCountDesc>
+ <HistoryToDBSyncNoKey>Error: Not found the right encryption key.</HistoryToDBSyncNoKey>
+ <HistoryToDBSyncStartUpdateCL>Started updating the contact list...</HistoryToDBSyncStartUpdateCL>
+ <HistoryToDBSyncCLFileNotFound>Not found a file with a list of protocols and contacts.</HistoryToDBSyncCLFileNotFound>
+ <HistoryToDBSyncCLUpdateDone>List for contacts updated.</HistoryToDBSyncCLUpdateDone>
+ <HistoryToDBSyncStartMD5>Launched recalculate MD5-hash...</HistoryToDBSyncStartMD5>
+ <HistoryToDBSyncMD5Done>Recalculation of the MD5-hash done.</HistoryToDBSyncMD5Done>
+ <HistoryToDBSyncShowLogFile>View log-file</HistoryToDBSyncShowLogFile>
+ <HistoryToDBSyncLSkypeStatusDesc>Skype status:</HistoryToDBSyncLSkypeStatusDesc>
+ <HistoryToDBSyncSkypeOff>Disable</HistoryToDBSyncSkypeOff>
+ <HistoryToDBSyncSkypeAttachPendingAuthorization>Request for authorization...</HistoryToDBSyncSkypeAttachPendingAuthorization>
+ <HistoryToDBSyncSkypeAttachSuccess>Connection is allowed</HistoryToDBSyncSkypeAttachSuccess>
+ <HistoryToDBSyncSkypeAttachRefused>Connection rejected</HistoryToDBSyncSkypeAttachRefused>
+ <HistoryToDBSyncSkypeAttachNotAvailable>Connection is broken</HistoryToDBSyncSkypeAttachNotAvailable>
+ <HistoryToDBSyncSkypeAttachAvailable>Skype API is available</HistoryToDBSyncSkypeAttachAvailable>
+ <HistoryToDBSyncSkypeErrCreate>Error creating an instance of Skype</HistoryToDBSyncSkypeErrCreate>
+ <HistoryToDBSyncSkypeErrDelete>Error deleting an instance of Skype</HistoryToDBSyncSkypeErrDelete>
+ <HistoryToDBSyncSkypeErrAttach>Error connecting to an instance of Skype</HistoryToDBSyncSkypeErrAttach>
+ <HistoryToDBSyncSkypeRun>We are trying to run Skype...</HistoryToDBSyncSkypeRun>
+ <HistoryToDBSyncSkypeRunErr>Error when starting Skype</HistoryToDBSyncSkypeRunErr>
+ <HistoryToDBSyncSkypeInitErr>Error creating interface Skype</HistoryToDBSyncSkypeInitErr>
+ <HistoryToDBSyncSkypeNotFound>Most likely you have not installed Skype and its version below 5.0</HistoryToDBSyncSkypeNotFound>
+
+ <ImportQHFHistory>Import history of QIP 2010/Infium/2012</ImportQHFHistory>
+ <ImportTXTHistory>Import history of QIP 2005</ImportTXTHistory>
+ <ImportGBMain> Import options </ImportGBMain>
+ <ImportRButtonSelectDir>Load from directory</ImportRButtonSelectDir>
+ <ImportRButtonSelectFile>Upload a single file</ImportRButtonSelectFile>
+ <ImportOpenHistoryFile>Open history file</ImportOpenHistoryFile>
+ <ImportLSelect>Select:</ImportLSelect>
+ <ImportLSelectSelectDir>Select a directory:</ImportLSelectSelectDir>
+ <ImportLSelectSelectFile>Select file:</ImportLSelectSelectFile>
+ <ImportLStatusUnknown>Unknown</ImportLStatusUnknown>
+ <ImportButtonSelectSource>Select</ImportButtonSelectSource>
+ <ImportButtonSelectSourceDir>Choose a directory</ImportButtonSelectSourceDir>
+ <ImportButtonSelectSourceFile>Select file</ImportButtonSelectSourceFile>
+ <ImportButtonToSQL>Generate SQL-file</ImportButtonToSQL>
+ <ImportCBPreview>Preview history</ImportCBPreview>
+ <ImportLReciver>Recipient:</ImportLReciver>
+ <ImportLMessage>Total messages:</ImportLMessage>
+ <ImportLMyNick>My Nickname:</ImportLMyNick>
+ <ImportLMyUIN>My UserID:</ImportLMyUIN>
+ <ImportLStatusTitle>Status:</ImportLStatusTitle>
+ <ImportLAddedInSQLFile>Processed messages:</ImportLAddedInSQLFile>
+ <ImportAdvSelectDirectory>Choose a directory</ImportAdvSelectDirectory>
+ <ImportQIPHistoryAllQHFFile>All QIP 2010/Infium/2012 history files (*.qhf;*.ahf)</ImportQIPHistoryAllQHFFile>
+ <ImportQIPHistoryQHFFile>QIP 2010/Infium/2012 history files (*.qhf)</ImportQIPHistoryQHFFile>
+ <ImportQIPHistoryQHFArcFile>QIP 2010/Infium/2012 archive history files (*.ahf)</ImportQIPHistoryQHFArcFile>
+ <ImportQIPHistoryTXTFile>QIP 2005 history files (*.txt)</ImportQIPHistoryTXTFile>
+ <ImportSelectHistoryFile>Selected file %s</ImportSelectHistoryFile>
+ <ImportHistoryFile>History file</ImportHistoryFile>
+ <ImportHistoryFileReadError>Error reading file</ImportHistoryFileReadError>
+ <ImportStop>Stop</ImportStop>
+ <ImportStoped>Stopped (%s)</ImportStoped>
+ <ImportDone>Done!</ImportDone>
+ <ImportSelectFile>Select the file(s) to import</ImportSelectFile>
+ <ImportProceed>Proceed</ImportProceed>
+ <ImportWait>Wait...</ImportWait>
+ <ImportRecordStart>There is a record in SQL-file...</ImportRecordStart>
+ <ImportDoneSyncWait>Import finished. After the next synchronization session, all information will be added to the database.</ImportDoneSyncWait>
+ <ImportRnQHistoryFile>RnQ history files (*.*)</ImportRnQHistoryFile>
+ <ImportRnQHistory>Import history of RnQ</ImportRnQHistory>
+ <ImportRnQStart>Running import history from RnQ</ImportRnQStart>
+ <ImportTXTStart>Running import history from QIP 2005</ImportTXTStart>
+ <ImportQHFStart>Running import history from QIP 2010/Infium/2012</ImportQHFStart>
+ <ImportSelectCnt>Total %s history files selected.</ImportSelectCnt>
+ <ImportProcessing>Processing the file %s</ImportProcessing>
+ <ImportProcessingDone>File %s processed.</ImportProcessingDone>
+ <ImportDoneCnt>Imported %s records.</ImportDoneCnt>
+ <ImportFoundCnt>Found %s records.</ImportFoundCnt>
+ <ImportICQHistory>Import history of ICQ 7</ImportICQHistory>
+ <ImportICQHistoryFile>ICQ 7 history files (Messages.qdb)</ImportICQHistoryFile>
+ <ImportICQStart>Running import history from ICQ 7</ImportICQStart>
+ <ImportICQDBConnected>You are connected to the database %s</ImportICQDBConnected>
+ <ImportICQDBLocked>The database is locked. Close the client ICQ 7 and try again.</ImportICQDBLocked>
+ <ImportICQFoundHistory>Found the history of the correspondence with the user %s</ImportICQFoundHistory>
+ <ImportICQDoneCnt>Imported %s entries.</ImportICQDoneCnt>
+
+ <EncryptKey>Creating an encryption key</EncryptKey>
+ <GBKeyProp> Creating an encryption key </GBKeyProp>
+ <LKeyStatusTitle>Status key:</LKeyStatusTitle>
+ <LCBEncryptionMethod>Encryption algorithm:</LCBEncryptionMethod>
+ <LKeyLength>Key length (characters):</LKeyLength>
+ <LKeyPassword>Key password:</LKeyPassword>
+ <LEncryptionKey>Encryption key:</LEncryptionKey>
+ <LEncryptionKeyDesc>(Encoded in BASE64)</LEncryptionKeyDesc>
+ <LLocation>Storage location key:</LLocation>
+ <ButtonCreateKey>Generate and save</ButtonCreateKey>
+ <GetEncryptPassword>Enter a password for the encryption key.</GetEncryptPassword>
+ <CheckActiveEncryptKey>Do you already have an active key, change the status of the old key and repeat the operation to generate a new key.</CheckActiveEncryptKey>
+ <SaveEncryptKeyDone>Your new key is generated and stored in No. %s</SaveEncryptKeyDone>
+ <SaveDBEncryptKeyDone>Your new key is generated and stored in the database as No. %s</SaveDBEncryptKeyDone>
+ <SaveEncryptKeyDoneHelp>Please remember the password and the key No.</SaveEncryptKeyDoneHelp>
+ <SaveEncryptKeyErr>An error occurred when saving the key in the database. Check the settings of the database and try again.</SaveEncryptKeyErr>
+ <KeyStatusActive>Active</KeyStatusActive>
+ <KeyStatusInactive>Inactive</KeyStatusInactive>
+ <KeyLocationLocal>Locally</KeyLocationLocal>
+ <KeyLocationServer>On the server DB</KeyLocationServer>
+ <StatusChangeKey>Change key status</StatusChangeKey>
+ <PasswordChangeKey>Change key password</PasswordChangeKey>
+ <DeleteKey>Delete key</DeleteKey>
+ <CheckNumActiveEncryptKey>The database already has an active key. Change the status of the active key, and then return to this operation.</CheckNumActiveEncryptKey>
+ <EncryptKeyStatusChanged>Status key is changed.</EncryptKeyStatusChanged>
+ <DeleteEncryptKeyCaption>Removing the encryption key</DeleteEncryptKeyCaption>
+ <DeleteEncryptKey>The database found messages encrypted with that key. Are you sure you want to delete this key?</DeleteEncryptKey>
+ <EncryptKeyDeleted>The encryption key is deleted.</EncryptKeyDeleted>
+ <DeleteActiveEncryptKey>WARNING! You are about to delete the active key. Without the active key encryption of messages is impossible.</DeleteActiveEncryptKey>
+ <KeyPasswordChangeCaption>Changing the password encryption key</KeyPasswordChangeCaption>
+ <ErrKeyPasswordChange>Entered an incorrect current password encryption key.</ErrKeyPasswordChange>
+ <ErrKeyPasswordChangeNotRenew>The new password and confirmation do not match, or blank. Please try again.</ErrKeyPasswordChangeNotRenew>
+ <KeyPasswordChanged>Password for the encryption key is changed.</KeyPasswordChanged>
+ <GBKeyPasswordChange> Changing the password encryption key </GBKeyPasswordChange>
+ <LCurrentPassword>Current password:</LCurrentPassword>
+ <LNewPassword>New password:</LNewPassword>
+ <LReNewPassword>Repeat new password:</LReNewPassword>
+ <ButtonNewKeyPassword>Change password</ButtonNewKeyPassword>
+ <FontCustomColorCaption>Other Colors...</FontCustomColorCaption>
+ <FontDefaultColorCaption>Automatic</FontDefaultColorCaption>
+ <GeneralSettings>General settings</GeneralSettings>
+ <ConnectionSettings>Connection settings</ConnectionSettings>
+ <Logs>Logs</Logs>
+ <SelectDBTypeAndIMClient>First, select the "DB type" and "IM-client."</SelectDBTypeAndIMClient>
+ <UpdateButton>Update</UpdateButton>
+ <StopButton>Stop</StopButton>
+ <SettingsButton>Settings</SettingsButton>
+ <IMClientType>IM-client:</IMClientType>
+ <UseProxy>Use a proxy server</UseProxy>
+ <ProxyAddress>Proxy server:</ProxyAddress>
+ <ProxyPort>Port:</ProxyPort>
+ <ProxyAuth>Proxy server requires a password</ProxyAuth>
+ <ProxyUser>User:</ProxyUser>
+ <ProxyUserPasswd>Password:</ProxyUserPasswd>
+ <Update> Update </Update>
+ <UpdateStatus>Click the "Update" button to start the update process.</UpdateStatus>
+ <Amount>Amount:</Amount>
+ <Speed>Speed:</Speed>
+ <FileName>Filename:</FileName>
+ <FileDesc>Description:</FileDesc>
+ <FileSize>File size:</FileSize>
+ <Unknown>Unknown</Unknown>
+ <NotFoundLangFile>Language file is not found</NotFoundLangFile>
+ <InitDownload>Initializing download...</InitDownload>
+ <Kb>KB</Kb>
+ <KbSec>Kbytes/sec</KbSec>
+ <InitDownloadFromURL>Initializing download from the URL</InitDownloadFromURL>
+ <InvalidResponseHeader>Invalid response header from the server.</InvalidResponseHeader>
+ <InvalidResponseHeaderDesc>Check the settings for connecting to the Internet. Maybe your proxy server blocks access to the site updates.</InvalidResponseHeaderDesc>
+ <HeaderData>Header data:</HeaderData>
+ <ParseHeader>Parse the header...</ParseHeader>
+ <ErrInternetOpen>Error opening session.</ErrInternetOpen>
+ <ErrInternetOpenURL>Error when requesting the file.</ErrInternetOpenURL>
+ <ErrDownloadingFile>An error occurred while reading the file.</ErrDownloadingFile>
+ <ErrRequest>Failed to query the data through a proxy server.</ErrRequest>
+ <Loading>Loading...</Loading>
+ <DownloadStopped>Download stopped.</DownloadStopped>
+ <ManualUpdate>Close all the components plugin, IM clients and try to repeat the update.</ManualUpdate>
+ <DownloadSuccessful>Download successful.</DownloadSuccessful>
+ <IsChecksum>Is the checksum file...</IsChecksum>
+ <MD5FileInMemory>MD5 file in memory:</MD5FileInMemory>
+ <FileSizeInMemory>Filesize in memory:</FileSizeInMemory>
+ <ChecksumConfirmed>Checksum and file size are confirmed.</ChecksumConfirmed>
+ <ChecksumFileEqServer>Checksum file to disk and server are the same.</ChecksumFileEqServer>
+ <ChecksumNotConfirmed>Not correct the checksum of the received data.</ChecksumNotConfirmed>
+ <FileSavedAs>File is saved as</FileSavedAs>
+ <ErrFileSavedAs>Can not save file</ErrFileSavedAs>
+ <SizeNotConfirmed>Not true size of the received data.</SizeNotConfirmed>
+ <AllUpdatesDownloaded>All updates are downloaded successfully.</AllUpdatesDownloaded>
+ <AllUpdatesInstalled>All updates have been installed.</AllUpdatesInstalled>
+ <Step>Step</Step>
+ <NumberFilesUpdate>The number of files to update</NumberFilesUpdate>
+ <FileToUpdate>File to update</FileToUpdate>
+ <UpdateSettingsFileNotFound>Update settings file not found</UpdateSettingsFileNotFound>
+ <UpdateLangFile>Start update localization file %s...</UpdateLangFile>
+ <UpdateLangFileDone>Update localization file %s completed.</UpdateLangFileDone>
+ <UpdateSQLFile>Start update sql-file %s...</UpdateSQLFile>
+ <UpdateSQLFileDone>Update sql-file %s completed.</UpdateSQLFileDone>
+ <UpdateFile>Start update file %s...</UpdateFile>
+ <UpdateFileDone>Update file %s completed.</UpdateFileDone>
+ <UpdateFileErr>File %s is not updated.</UpdateFileErr>
+ <InMemoryFoundProcess>In the memory of the process found %s (PID: %s)</InMemoryFoundProcess>
+ <SendExitCommand>Send the command to the end of the program...</SendExitCommand>
+ <SearchProcessInMemory>Re looking for process %s in the memory...</SearchProcessInMemory>
+ <KillProcess>Trying to force terminated the process %s</KillProcess>
+ <KillProcessDone>Process %s forcibly terminated.</KillProcessDone>
+ <NotKillProcess>Process %s can not be forcibly terminated.</NotKillProcess>
+ <SeDebugPrivilege>Set SeDebugPrivilege and try again to terminate the process %s</SeDebugPrivilege>
+ <SeDebugPrivilegeDone>Process %s forcibly terminated when SeDebugPrivilege.</SeDebugPrivilegeDone>
+ <NotKillSeDebugPrivilege>Process %s can not be forced to terminated in SeDebugPrivilege.</NotKillSeDebugPrivilege>
+ <InMemoryNotFoundProcess>Process %s not found in memory.</InMemoryNotFoundProcess>
+ <EndProcess>We are trying to close the process %s</EndProcess>
+ <StartProgram>Запускаем программу %s</StartProgram>
+ <StartProgramDone>Программа %s запущена.</StartProgramDone>
+ <StartProgramFail>Программа %s не запущена.</StartProgramFail>
+
+</strings> \ No newline at end of file
diff --git a/plugins/MirandaNGHistoryToDB/langs/Russian.xml b/plugins/MirandaNGHistoryToDB/langs/Russian.xml
new file mode 100644
index 0000000000..a7933c774c
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/langs/Russian.xml
@@ -0,0 +1,506 @@
+<?xml version="1.0" encoding="utf-8"?>
+<strings>
+ <MainFormCaption>HistoryToDB</MainFormCaption>
+ <ShowSearchButton>Поиск в окне сообщений</ShowSearchButton>
+ <ClearListButton>Очистить окно сообщений</ClearListButton>
+ <SyncButton>Синхронизировать историю</SyncButton>
+ <ImportButton>Импорт истории</ImportButton>
+ <ImportPM_ICQ>Из истории ICQ 7 и выше</ImportPM_ICQ>
+ <ImportPM_RnQ>Из истории RnQ</ImportPM_RnQ>
+ <ImportPM_QIP2005>Из истории QIP 2005</ImportPM_QIP2005>
+ <ImportPM_QIPInfium>Из истории QIP 2010/Infium/2012</ImportPM_QIPInfium>
+ <ImportPM_Miranda>Из истории Miranda</ImportPM_Miranda>
+ <ImportPM_qutIM>Из истории qutIM</ImportPM_qutIM>
+ <SettingsButton>Настройки</SettingsButton>
+ <LTitleIM>Переписка с %s (%s)</LTitleIM>
+ <LTitleCHAT>Переписка чата "%s" (%s)</LTitleCHAT>
+ <LTitleIMSmall>Переписка с %s</LTitleIMSmall>
+ <LHistory1>История переписки с </LHistory1>
+ <LHistory2>по</LHistory2>
+ <SearchHistoryButton>Показать</SearchHistoryButton>
+ <SearchButton>Поиск</SearchButton>
+ <SearchCaption>Поиск</SearchCaption>
+ <SearchMessage>Поиск закончен. Совпадений не найдено.</SearchMessage>
+ <IMButtonCaption>История сообщений в %s</IMButtonCaption>
+ <CHATButtonCaption>История чат-сообщений в %s</CHATButtonCaption>
+ <InfoCaption>Информация</InfoCaption>
+ <IMNoTab>Нет ни одной открытой вкладки сообщений.</IMNoTab>
+ <CHATNoTab>Нет ни одной открытой вкладки чата.</CHATNoTab>
+ <IMCaption>История сообщений</IMCaption>
+ <CHATCaption>История чатов</CHATCaption>
+ <SearchContact>Найти контакт</SearchContact>
+ <ButtonRefreshHistory>Перечитать историю контакта</ButtonRefreshHistory>
+ <ButtonSaveHistory>Сохранить историю контакта</ButtonSaveHistory>
+ <ButtonDeleteHistory>Удалить историю контакта</ButtonDeleteHistory>
+ <ButtonDeleteCurrentHistory>Удалить историю текущего контакта</ButtonDeleteCurrentHistory>
+ <ButtonDeleteAllHistory>Удалить всю историю</ButtonDeleteAllHistory>
+ <NoDeleteSelectHistory>Не выбран контакт для удаления истории</NoDeleteSelectHistory>
+ <NoSelectContactHistory>Выберите контакт для поиска истории</NoSelectContactHistory>
+ <NoSelectContactRefreshHistory>Выберите контакт для перезагрузки истории</NoSelectContactRefreshHistory>
+ <DeleteHistoryCaption>Удалить</DeleteHistoryCaption>
+ <DeleteHistory>История выбранного контакта будет полностью удалена из базы. Вы уверены?</DeleteHistory>
+ <DeleteAllHistory>История всех контактов и чатов будет полностью удалена из базы. Вы уверены?</DeleteAllHistory>
+ <Copy>Копировать</Copy>
+ <SelectAll>Выбрать все</SelectAll>
+ <DeSelectAll>Снять выбор со всех</DeSelectAll>
+ <SendSyncQuery>[%s] HistoryToDBSync отправлен запрос на синхронизацию истории</SendSyncQuery>
+ <ShowHistoryDay>Показать за день</ShowHistoryDay>
+ <ShowHistoryMonth>Показать за месяц</ShowHistoryMonth>
+ <ShowHistoryYear>Показать за год</ShowHistoryYear>
+ <ShowHistoryAll>Показать за весь период</ShowHistoryAll>
+ <GIFStaticText>Подождите, идет загрузка...</GIFStaticText>
+ <Settings>Настройки</Settings>
+ <SettingsPageControlMainTab>База данных</SettingsPageControlMainTab>
+ <SettingsPageControlSyncTab>Синхронизация</SettingsPageControlSyncTab>
+ <SettingsPageControlInterfaceTab>Интерфейс</SettingsPageControlInterfaceTab>
+ <SettingsPageControlEventsTab>События</SettingsPageControlEventsTab>
+ <SettingsPageControlFontsTab>Шрифты и пр.</SettingsPageControlFontsTab>
+ <SettingsPageControlHotKeyTab>Горячие клавиши</SettingsPageControlHotKeyTab>
+ <SettingsPageControlEncryptionTab>Шифрование истории</SettingsPageControlEncryptionTab>
+ <SettingsPageControlAboutTab>О программе</SettingsPageControlAboutTab>
+ <DBGroupBox> База данных </DBGroupBox>
+ <SyncGroupBox> Синхронизация истории </SyncGroupBox>
+ <EventsGroupBox> События </EventsGroupBox>
+ <LDBConnectMethod>Метод подкл-я к БД:</LDBConnectMethod>
+ <LDBType>Тип БД:</LDBType>
+ <LDBAddress>Адрес сервера БД:</LDBAddress>
+ <LDBSchema>Схема:</LDBSchema>
+ <LDBPort>Порт сервера БД:</LDBPort>
+ <LDBName>Имя БД:</LDBName>
+ <LDBNameOracle>TNS:</LDBNameOracle>
+ <LDBLogin>Логин:</LDBLogin>
+ <LDBPasswd>Пароль:</LDBPasswd>
+ <TestConnectionButton>Проверить соединение с БД</TestConnectionButton>
+ <CBDBConnectMethodDirect>Напрямую</CBDBConnectMethodDirect>
+ <LSyncMethod>Метод синхронизации:</LSyncMethod>
+ <LSyncInterval>Интервал синхронизации:</LSyncInterval>
+ <CBSyncMethodAuto>Автоматический</CBSyncMethodAuto>
+ <CBSyncMethodManual>Вручную</CBSyncMethodManual>
+ <CBSyncMethodOnSchedule>По расписанию</CBSyncMethodOnSchedule>
+ <CBSyncInterval5Min>Каждые 5 минут</CBSyncInterval5Min>
+ <CBSyncInterval10Min>Каждые 10 минут</CBSyncInterval10Min>
+ <CBSyncInterval20Min>Каждые 20 минут</CBSyncInterval20Min>
+ <CBSyncInterval30Min>Каждые 30 минут</CBSyncInterval30Min>
+ <CBSyncIntervalExitProgram>При выходе из программы</CBSyncIntervalExitProgram>
+ <CBSyncInterval10Mes>После кажд. 10-го сооб-я</CBSyncInterval10Mes>
+ <CBSyncInterval20Mes>После кажд. 20-го сооб-я</CBSyncInterval20Mes>
+ <CBSyncInterval30Mes>После кажд. 30-го сооб-я</CBSyncInterval30Mes>
+ <CBSyncIntervalNMin>Каждые N минут</CBSyncIntervalNMin>
+ <CBSyncIntervalNMes>После кажд. N сооб-я</CBSyncIntervalNMes>
+ <GBSyncCustomInterval> Интервалы пользователя </GBSyncCustomInterval>
+ <LTimeInterval>Интервал по времени (мин.):</LTimeInterval>
+ <LMsgCountInterval>Интервал по кол. сообщений:</LMsgCountInterval>
+ <CBEnableEncryption>Включить шифрование истории сообщений</CBEnableEncryption>
+ <CBAni>Показывать всплывающие сообщения</CBAni>
+ <CBWriteErrLog>Писать ошибки в лог-файл</CBWriteErrLog>
+ <CBHideSyncIcon>Скрыть иконку HistoryToDBSync из трея</CBHideSyncIcon>
+ <LNumLastHistoryMsg>Количество последних сообщений для показа в окне истории переписки</LNumLastHistoryMsg>
+ <CBShowPluginButton>Добавить кнопку плагина в панель модулей (только для IM-клиента QIP 2012 и RnQ)</CBShowPluginButton>
+ <SaveButton>Сохранить настройки</SaveButton>
+ <CloseButton>Закрыть</CloseButton>
+ <GBKeys> Ключи шифрования на сервере </GBKeys>
+ <DBGridKeysColumnID>Номер ключа</DBGridKeysColumnID>
+ <DBGridKeysColumnSTATUS>Статус ключа</DBGridKeysColumnSTATUS>
+ <DBGridKeysColumnMETHOD>Метод шифрования</DBGridKeysColumnMETHOD>
+ <ButtonGetEncryptionKey>Получить ключи из БД</ButtonGetEncryptionKey>
+ <ButtonCreateEncryptionKey>Создать новый ключ</ButtonCreateEncryptionKey>
+ <UpdateCaption>Обновление</UpdateCaption>
+ <UpdateMessage1>Внимание!</UpdateMessage1>
+ <UpdateMessage2>Вышла новая версия программы.</UpdateMessage2>
+ <UpdateMessage3>Пожалуйста, посетите официальный сайт для обновления.</UpdateMessage3>
+ <UpdateMessage4>Структура Вашей БД устарела.</UpdateMessage4>
+ <UpdateMessage5>Версия программы: %s</UpdateMessage5>
+ <UpdateMessage6>Версия БД: %s</UpdateMessage6>
+ <UpdateMessage7>Новая версия программы: %s</UpdateMessage7>
+ <GoodDBConnect1>Таблица конфигурации успешно прочитана.</GoodDBConnect1>
+ <GoodDBConnect2>Подключение к БД успешно установлено.</GoodDBConnect2>
+ <ErrCaption>Ошибка</ErrCaption>
+ <ErrVersionCheck>Не удается проверить версию плагина.</ErrVersionCheck>
+ <ErrDBConnect>Не удается установить подключение к БД.</ErrDBConnect>
+ <ErrSQLQuery>Ошибка выполнения SQL запроса.</ErrSQLQuery>
+ <ErrSQLExecQuery>Ошибка выполнения SQLExec запроса.</ErrSQLExecQuery>
+ <ErrDBParamCheck1>Не заполнено поле "Адрес сервера БД"</ErrDBParamCheck1>
+ <ErrDBParamCheck2>Не заполнено поле "Порт сервера БД"</ErrDBParamCheck2>
+ <ErrDBParamCheck3>Не заполнено поле "Пароль"</ErrDBParamCheck3>
+ <ErrDBParamCheck4>Не заполнено поле "Логин"</ErrDBParamCheck4>
+ <ErrDBParamCheck5>Не заполнено поле "Имя БД"</ErrDBParamCheck5>
+ <ErrDBParamCheck6>Не заполнено поле "Схема"</ErrDBParamCheck6>
+ <ErrDBParamCheck7>Не заполнено поле "TNS"</ErrDBParamCheck7>
+ <SettingsSave>Настройки сохранены.</SettingsSave>
+ <SettingsErrSave>Невозможно сохранить настройки.</SettingsErrSave>
+ <SettingsErrRead>Невозможно прочитать настройки.</SettingsErrRead>
+ <SendCheckMD5HashQuery>[%s] HistoryToDBSync отправлен запрос на перерасчет MD5-хешей</SendCheckMD5HashQuery>
+ <SendCheckAndDeleteMD5HashQuery>[%s] HistoryToDBSync отправлен запрос на перерасчет MD5-хешей и удаление дубликатов сообщений</SendCheckAndDeleteMD5HashQuery>
+ <DBServiceButton>Обслуживание БД</DBServiceButton>
+ <CheckMD5Hash>Пересчитать все MD5-хэши в БД</CheckMD5Hash>
+ <CheckAndDeleteMD5Hash>Пересчитать все MD5-хэши в БД и удалить дубликаты</CheckAndDeleteMD5Hash>
+ <CBAddSpecialContact>Добавить спец-контакт (только для IM-клиента QIP 2012)</CBAddSpecialContact>
+ <GBMessageFonts> Шрифты </GBMessageFonts>
+ <TitleSpacingBox> Расстояние для заголовка </TitleSpacingBox>
+ <MessagesSpacingBox> Расстояние для текста </MessagesSpacingBox>
+ <LIncommingMesTitle>Шрифт заголовка для входящих:</LIncommingMesTitle>
+ <LOutgoingMesTitle>Шрифт заголовка для исходящих:</LOutgoingMesTitle>
+ <LIncommingMes>Шрифт для входящих сообщений:</LIncommingMes>
+ <LOutgoingMes>Шрифт для исходящих сообщений:</LOutgoingMes>
+ <LServiceMes>Шрифт для сервисных сообщений:</LServiceMes>
+ <LSpacingBefore>Расстояние перед:</LSpacingBefore>
+ <LSpacingAfter>Расстояние после:</LSpacingAfter>
+ <ExSearch>Найти</ExSearch>
+ <ExSearchNext>Найти далее...</ExSearchNext>
+ <CBHotKey>Включить поддержку глобальных горячих клавиш</CBHotKey>
+ <SetHotKeyButton>Назначить</SetHotKeyButton>
+ <DeleteHotKeyButton>Удалить</DeleteHotKeyButton>
+ <GBHotKey> Горячие клавиши </GBHotKey>
+ <OpenLogFileCaption>Ошибка открытия файла</OpenLogFileCaption>
+ <OpenLogFile>Ошибка открытия файла %s</OpenLogFile>
+ <OpenLogFileRepeat>Возможно файл занять программой. Повторить попытку?</OpenLogFileRepeat>
+ <OpenLogFileLock>Возможно файл занять программой.</OpenLogFileLock>
+ <MessageEncrypted>ВНИМАНИЕ! Это сообщение зашифровано. Возможно Вы ввели неправильный пароль ключа шифрования или в БД не найдено нужного ключа для расшифровки сообщения.</MessageEncrypted>
+ <LErrLogSize>Максимальный размер лог-файла ошибок (Кбайт)</LErrLogSize>
+ <Rename>Переименовать</Rename>
+ <Merge>Объединить</Merge>
+ <Delete>Удалить</Delete>
+ <GetContactListButton>Сохранить список контактов</GetContactListButton>
+ <UpdateContactListButton>Обновить данные контактов в БД</UpdateContactListButton>
+ <CheckUpdateButton>Проверить наличие обновлений</CheckUpdateButton>
+ <SaveContactListCompleted>Список контактов и протоколов сохранен.</SaveContactListCompleted>
+ <SaveContactListErr>Ошибка! Список контактов и протоколов не сохранен или сохранен частично.</SaveContactListErr>
+ <SendUpdateContactListCompleted>Отправлен запрос на обновление списка контактов в БД.</SendUpdateContactListCompleted>
+ <SendUpdateContactListErr>Файл %s для обновления списка контактов не найден. Запрос на обновление не отправлен.</SendUpdateContactListErr>
+ <ContactNotInTheList>Не в списке</ContactNotInTheList>
+ <UpdateContactListInDB>Обновить данные контактов в БД (Nickname и UserID)</UpdateContactListInDB>
+ <GIFStaticTextDelete>Подождите, идет удаление истории...</GIFStaticTextDelete>
+ <SendUpdateContactListInDB>[%s] HistoryToDBSync отправлен запрос на обновление списка контактов из файла %s</SendUpdateContactListInDB>
+ <SendUpdateContactListInDBErrQIP>[%s] Файл %s для обновления списка контактов не найден. Выберите пункт 'Сохранить список контактов' в контекстном меню спец-контакта QIPHistoryToDB.</SendUpdateContactListInDBErrQIP>
+ <SendUpdateContactListInDBErrRnQ>[%s] Файл %s для обновления списка контактов не найден. Выберите пункт 'Сохранить список контактов' в контекстном меню RnQHistoryToDB в окне чата.</SendUpdateContactListInDBErrRnQ>
+ <SendUpdateContactListInDBErrUnknown>[%s] Файл %s для обновления списка контактов не найден. Выберите пункт 'Сохранить список контактов' в контекстном меню плагина.</SendUpdateContactListInDBErrUnknown>
+ <SendStopSync>[%s] HistoryToDBSync отправлен запрос на запрет синхронизации истории из файла %s.</SendStopSync>
+ <SendStartSync>[%s] HistoryToDBSync отправлен запрос на разрешение синхронизации истории из файла %s.</SendStartSync>
+ <ShowContactHistory>История сообщений %s (%s) в HistoryToDBViewer</ShowContactHistory>
+ <ShowOneContactHistory>История в HistoryToDBViewer</ShowOneContactHistory>
+ <CBBlockSpamMsg>Не записывать в БД сообщения помеченые как спам (только для IM-клиента QIP 2012)</CBBlockSpamMsg>
+ <ErrKeyPassword>Ошибка: Неверный пароль ключа шифрования. Введите правильный пароль или чтение зашифрованных сообщений будет невозможно.</ErrKeyPassword>
+ <Transparency> Прозрачность окон </Transparency>
+ <TransparencyEnable>Включить прозрачность окон</TransparencyEnable>
+ <LThankYou>Благодарности</LThankYou>
+ <CBExPrivateChatName>Использовать расширенное имя для приватных чатов (Имя чата / Ник собеседника)</CBExPrivateChatName>
+ <TotalString>Всего строк:</TotalString>
+ <LoadingTime>Время загрузки:</LoadingTime>
+ <MSec>мс</MSec>
+ <DeleteLogFileCaption>Ошибка удаления файла</DeleteLogFileCaption>
+ <DeleteLogFile>Ошибка удаления файла %s</DeleteLogFile>
+ <DeleteLogFileRepeat>Возможно файл занят другой программой. Повторить попытку?</DeleteLogFileRepeat>
+ <Additionally> Дополнительно </Additionally>
+ <SyncWhenExit>Дополнительная синхронизация истории при выходе из IM-клиента</SyncWhenExit>
+ <EnableSkypeSupport>Включить поддержку Skype</EnableSkypeSupport>
+ <LangButton>Язык программы</LangButton>
+ <Language>Язык программы:</Language>
+ <CBWriteDebugLog>Вести расширенный лог работы программы (Debug-режим)</CBWriteDebugLog>
+ <ExportAllHistoryButton>Экспортировать историю</ExportAllHistoryButton>
+ <ExortFormCaption>Экспорт истории</ExortFormCaption>
+ <ButtonBack>Назад</ButtonBack>
+ <ButtonNext>Далее</ButtonNext>
+ <ButtonFinish>Выйти</ButtonFinish>
+ <ButtonCancel>Отмена</ButtonCancel>
+ <IMExportWizardPage0Title>Добро пожаловать в мастер экспорта истории</IMExportWizardPage0Title>
+ <IMExportWizardPage0SubTitle>Данный мастер поможет Вам экспортировать историю %s во внешнюю базу данных. Экспорт будет произведен в файл формата sql-insert. При синхронизации эти данные будут переданы в базу данных.</IMExportWizardPage0SubTitle>
+ <IMExportWizardPage1Title>Мастер экспорта истории</IMExportWizardPage1Title>
+ <IMExportWizardPage1SubTitle>Выберите контакты, историю которых Вы хотите экспортировать.</IMExportWizardPage1SubTitle>
+ <IMExportWizardPage2Title>Мастер экспорта истории</IMExportWizardPage2Title>
+ <IMExportWizardPage2SubTitle>Идет экспорт истории, подождите...</IMExportWizardPage2SubTitle>
+ <IMExportWizardPage3Title>Мастер экспорта истории</IMExportWizardPage3Title>
+ <IMExportWizardPage3SubTitle>Экспорт истории завершен.</IMExportWizardPage3SubTitle>
+ <NickName>Ник</NickName>
+ <Protocol>Протокол</Protocol>
+ <Number>Номер</Number>
+ <TotalSelect>Всего выбрано %s контактов из %s</TotalSelect>
+ <ContactExport>Экспорт истории контакта %s (%s) ...</ContactExport>
+ <ExportDone>Экспорт истории завершен.</ExportDone>
+ <ExportAbort>Вы действительно хотите прервать экспорт и выйти из мастера?</ExportAbort>
+ <ExportAbortCaption>Выход из мастера экспорта</ExportAbortCaption>
+ <ExportDoneDesc>Экспорт истории завершен. Теперь Вы можете отправить запрос на синхронизацию экспортированной истории с базой данных. При большом объёме экспортированной истории процедура синхронизации может выполняться значительное время.</ExportDoneDesc>
+ <SendSyncRequest>Отправить запрос на синхронизацию</SendSyncRequest>
+ <MirandaImportInfo>Импорт сообщений из базы Miranda осуществляется непосредственно из самого IM-клиента.</MirandaImportInfo>
+ <HistoryToDBSyncCLUpdateErr>Во время обновления списка контактов произошла ошибка.</HistoryToDBSyncCLUpdateErr>
+ <HistoryToDBSyncMD5Err>Во время перерасчета MD5-хэшей произошла ошибка.</HistoryToDBSyncMD5Err>
+ <SeeErrLog>Для получения доп. информации смотрите лог-файлы.</SeeErrLog>
+ <HistoryToDBSyncStartTrayMsg>Запущена синхронизация сообщений...</HistoryToDBSyncStartTrayMsg>
+ <DBReConnectNum>[%s] Выполняем %s попытку переподключения к БД.</DBReConnectNum>
+ <DBReConnectErr>[%s] Ошибка переподключения к БД.</DBReConnectErr>
+ <DBReconnectCount>Кол. попыток переподключения:</DBReconnectCount>
+ <DBReconnectInterval>Интервал переподключения (мсек):</DBReconnectInterval>
+ <AutoScrollText>Автоскроллинг сообщений</AutoScrollText>
+ <AutoRunHistoryToDBSync>Запускать HistoryToDBSync при загрузке Windows</AutoRunHistoryToDBSync>
+ <RunningSkypeOnStartup>Запускать Skype при запуске HistoryToDBSync</RunningSkypeOnStartup>
+ <ExitSkypeOnEnd>Выходить из Skype при закрытии HistoryToDBSync</ExitSkypeOnEnd>
+ <UpdateServerInServiceMode>Сервер обновлений находится на сервисном обслуживании.%sПопробуйте запустить процедуру проверки обновлений позже.</UpdateServerInServiceMode>
+
+ <AboutButton>О плагине</AboutButton>
+ <AboutFormCaption>О плагине</AboutFormCaption>
+ <Version>Версия: </Version>
+ <License>Лицензия: </License>
+
+ <ERR_SAVE_TO_DB_CONNECT_ERR>[%s] Ошибка: Не удаётся подключиться к БД. Ошибка: %s</ERR_SAVE_TO_DB_CONNECT_ERR>
+ <ERR_SAVE_TO_DB_SERVICE_MODE>[%s] Ошибка: БД на сервисном обслуживании. Сохранение сообщений в БД невозможно.</ERR_SAVE_TO_DB_SERVICE_MODE>
+ <ERR_TEMP_SAVE_TO_DB_SERVICE_MODE>[%s] Ошибка: БД на сервисном обслуживании. Сохранение отложенных сообщений в БД невозможно.</ERR_TEMP_SAVE_TO_DB_SERVICE_MODE>
+ <ERR_READ_DB_CONNECT_ERR>[%s] Ошибка: Не удаётся подключиться к БД. Ошибка: %s</ERR_READ_DB_CONNECT_ERR>
+ <ERR_READ_DB_SERVICE_MODE>[%s] Ошибка: Невозможно выполнить операцию. БД на сервисном обслуживании.</ERR_READ_DB_SERVICE_MODE>
+ <ERR_LOAD_MSG_TO_DB>[%s] Ошибка записи сообщений из лог-файла в БД: %s</ERR_LOAD_MSG_TO_DB>
+ <ERR_SEND_UPDATE>[%s] Ошибка при запросе обновления: %s</ERR_SEND_UPDATE>
+ <LOAD_TEMP_MSG>[%s] В файле %s найдено %s сообщений; Добавлено в базу %s; Всего отбраковано %s; Найдено дубликатов %s; Зашифровано %s</LOAD_TEMP_MSG>
+ <LOAD_TEMP_MSG_SCREEN>Всего сообщений %s; Добавлено в базу %s; Всего отбраковано %s; Найдено дубликатов %s; Зашифровано %s</LOAD_TEMP_MSG_SCREEN>
+ <LOAD_TEMP_MSG_NOLOGFILE>[%s] Файл отложенных сообщений %s не найден.</LOAD_TEMP_MSG_NOLOGFILE>
+ <LOAD_TEMP_MSG_NOMSGFILE>Файл сообщений %s не найден.</LOAD_TEMP_MSG_NOMSGFILE>
+ <ERR_NO_DB_CONNECTED>[%s] Соединение с БД не установлено.</ERR_NO_DB_CONNECTED>
+ <ERR_NO_FOUND_VIEWER>Просмотрщик истории %s не найден.</ERR_NO_FOUND_VIEWER>
+ <ERR_NO_FOUND_SYNC>Программа синхронизации истории %s не найден.</ERR_NO_FOUND_SYNC>
+ <ERR_NO_FOUND_UPDATER>Программа проверки обновлений %s не найдена.</ERR_NO_FOUND_UPDATER>
+ <ERR_OLD_SDK_VER>Неверная версия SDK. Для работы необходим QIP 2012 и выше.</ERR_OLD_SDK_VER>
+ <ERR_NO_FOUND_IMPORT>Программа импорта истории %s не найдена.</ERR_NO_FOUND_IMPORT>
+ <ERR_DB_SERVICE_MODE>Невозможно выполнить операцию. База данных на сервисном обслуживании.</ERR_DB_SERVICE_MODE>
+
+ <HistoryToDBSyncPopupMenuShow>Показать</HistoryToDBSyncPopupMenuShow>
+ <HistoryToDBSyncPopupMenuHide>Скрыть</HistoryToDBSyncPopupMenuHide>
+ <HistoryToDBSyncPopupMenuSync>Синхронизировать историю</HistoryToDBSyncPopupMenuSync>
+ <HistoryToDBSyncPopupMenuSettings>Настройки</HistoryToDBSyncPopupMenuSettings>
+ <HistoryToDBSyncPopupMenuShowAbout>О программе</HistoryToDBSyncPopupMenuShowAbout>
+ <HistoryToDBSyncPopupMenuShowExit>Выйти</HistoryToDBSyncPopupMenuShowExit>
+ <HistoryToDBSyncGroupBox> Синхронизация истории </HistoryToDBSyncGroupBox>
+ <HistoryToDBSyncStatus>Состояние синхронизации:</HistoryToDBSyncStatus>
+ <HistoryToDBSyncDone>Синхронизация выполнена</HistoryToDBSyncDone>
+ <HistoryToDBSyncStart>Запустить синхронизацию</HistoryToDBSyncStart>
+ <HistoryToDBSyncStop>Остановить синхронизацию</HistoryToDBSyncStop>
+ <HistoryToDBSyncStarted>Идет синхронизация...</HistoryToDBSyncStarted>
+ <HistoryToDBSyncStoped>Cинхронизация остановлена</HistoryToDBSyncStoped>
+ <HistoryToDBSyncFileNotFound>Файл для синхронизации не найден</HistoryToDBSyncFileNotFound>
+ <HistoryToDBSyncStartCount>Запущен отчет времени... (%s сек.)</HistoryToDBSyncStartCount>
+ <HistoryToDBSyncWaitReq>Ожидание запроса на синхронизацию</HistoryToDBSyncWaitReq>
+ <HistoryToDBSyncNotSpecified>Не задан</HistoryToDBSyncNotSpecified>
+ <HistoryToDBSyncUnknownIMClient>Неизвестный тип IM-клиента. Обновление БД невозможно.</HistoryToDBSyncUnknownIMClient>
+ <HistoryToDBSyncUpdateDone>Произведено успешное обновление БД.</HistoryToDBSyncUpdateDone>
+ <HistoryToDBSyncUpdateErr>Произошла ошибка при обновлений БД. Смотрите в лог-файл.</HistoryToDBSyncUpdateErr>
+ <HistoryToDBSyncLTotalMesCountDesc>Всего сообщений:</HistoryToDBSyncLTotalMesCountDesc>
+ <HistoryToDBSyncLMesCurrentCountDesc>Добавлено в базу:</HistoryToDBSyncLMesCurrentCountDesc>
+ <HistoryToDBSyncLBadMesCountDesc>Всего отбраковано:</HistoryToDBSyncLBadMesCountDesc>
+ <HistoryToDBSyncLStartTimeDesc>С начала имп-а прошло:</HistoryToDBSyncLStartTimeDesc>
+ <HistoryToDBSyncLEndTimeDesc>До окончания осталось:</HistoryToDBSyncLEndTimeDesc>
+ <HistoryToDBSyncLDublicateMesCountDesc>Найдено дубликатов:</HistoryToDBSyncLDublicateMesCountDesc>
+ <HistoryToDBSyncLogViewButton>Лог-файл</HistoryToDBSyncLogViewButton>
+ <HistoryToDBSyncLogFormCaption>Просмотр лог-файла</HistoryToDBSyncLogFormCaption>
+ <HistoryToDBSyncLogFormFileName>Имя лог-файла:</HistoryToDBSyncLogFormFileName>
+ <HistoryToDBSyncLogFormDeleteLogButton>Удалить лог-файл</HistoryToDBSyncLogFormDeleteLogButton>
+ <HistoryToDBSyncLogFormReloadLogButton>Обновить</HistoryToDBSyncLogFormReloadLogButton>
+ <HistoryToDBSyncLTotalHashMsgСountDesc>Всего сообщений для анализа:</HistoryToDBSyncLTotalHashMsgСountDesc>
+ <HistoryToDBSyncLTotalBrokenMD5HashСountDesc>Ошибочных MD5-хэшей:</HistoryToDBSyncLTotalBrokenMD5HashСountDesc>
+ <HistoryToDBSyncLTotalChangeMD5HashСountDesc>Исправлено MD5-хэшей:</HistoryToDBSyncLTotalChangeMD5HashСountDesc>
+ <HistoryToDBSyncLMD5DublicateMesCountDesc>Найдено дубликатов:</HistoryToDBSyncLMD5DublicateMesCountDesc>
+ <HistoryToDBSyncLDeletedMD5DublicateMesCountDesc>Удалено дубликатов:</HistoryToDBSyncLDeletedMD5DublicateMesCountDesc>
+ <HistoryToDBSyncKeyPasswdCaption>Ввод пароля</HistoryToDBSyncKeyPasswdCaption>
+ <HistoryToDBSyncGBPasswd> Ввод пароля ключа шифрования </HistoryToDBSyncGBPasswd>
+ <HistoryToDBSyncKeyPasswordCaption>Ввод пароля ключа шифрования</HistoryToDBSyncKeyPasswordCaption>
+ <HistoryToDBSyncErrKeyPassword>Ошибка: Неверный пароль ключа шифрования. Введите правильный пароль или шифрование сообщений будет недоступно.</HistoryToDBSyncErrKeyPassword>
+ <HistoryToDBSyncErrActiveKey>Ошибка: Не найден активный ключ.</HistoryToDBSyncErrActiveKey>
+ <HistoryToDBSyncMultiActiveKey>Ошибка: Найдено более 1 активного ключа.</HistoryToDBSyncMultiActiveKey>
+ <HistoryToDBSyncLKeyNumTitle>Номер ключа:</HistoryToDBSyncLKeyNumTitle>
+ <HistoryToDBSyncLKeyPasswdTitle>Пароль ключа:</HistoryToDBSyncLKeyPasswdTitle>
+ <HistoryToDBSyncButtonGo>Ввод</HistoryToDBSyncButtonGo>
+ <HistoryToDBSyncButtonExit>Отмена</HistoryToDBSyncButtonExit>
+ <HistoryToDBSyncCBSaveOnly>Запомнить пароль до выхода из программы</HistoryToDBSyncCBSaveOnly>
+ <HistoryToDBSyncCBSave>Сохранить все пароли</HistoryToDBSyncCBSave>
+ <HistoryToDBSyncErrDecryptKey>Неизвестная ошибка расшифровки ключа шифрования.</HistoryToDBSyncErrDecryptKey>
+ <HistoryToDBSyncCheckEncKey>Проверка ключа шифрования</HistoryToDBSyncCheckEncKey>
+ <HistoryToDBSyncLEncryptMesCountDesc>Зашифровано сооб-й:</HistoryToDBSyncLEncryptMesCountDesc>
+ <HistoryToDBSyncNoKey>Ошибка: В БД не найдено нужного ключа шифрования.</HistoryToDBSyncNoKey>
+ <HistoryToDBSyncStartUpdateCL>Запущено обновление списка контактов...</HistoryToDBSyncStartUpdateCL>
+ <HistoryToDBSyncCLFileNotFound>Не найдены файл со списком протоколов и контактов.</HistoryToDBSyncCLFileNotFound>
+ <HistoryToDBSyncCLUpdateDone>Cписк контактов обновлен.</HistoryToDBSyncCLUpdateDone>
+ <HistoryToDBSyncStartMD5>Запущен перерасчет MD5-хэшей...</HistoryToDBSyncStartMD5>
+ <HistoryToDBSyncMD5Done>Перерасчет MD5-хэшей завершен.</HistoryToDBSyncMD5Done>
+ <HistoryToDBSyncShowLogFile>Посмотреть лог-файлы</HistoryToDBSyncShowLogFile>
+ <HistoryToDBSyncLSkypeStatusDesc>Статус Skype:</HistoryToDBSyncLSkypeStatusDesc>
+ <HistoryToDBSyncSkypeOff>Отключено</HistoryToDBSyncSkypeOff>
+ <HistoryToDBSyncSkypeAttachPendingAuthorization>Запрос авторизации...</HistoryToDBSyncSkypeAttachPendingAuthorization>
+ <HistoryToDBSyncSkypeAttachSuccess>Подключение разрешено</HistoryToDBSyncSkypeAttachSuccess>
+ <HistoryToDBSyncSkypeAttachRefused>Подключение отклонено</HistoryToDBSyncSkypeAttachRefused>
+ <HistoryToDBSyncSkypeAttachNotAvailable>Подключение отключено</HistoryToDBSyncSkypeAttachNotAvailable>
+ <HistoryToDBSyncSkypeAttachAvailable>Skype API доступно</HistoryToDBSyncSkypeAttachAvailable>
+ <HistoryToDBSyncSkypeErrCreate>Ошибка создания экземпляра Skype</HistoryToDBSyncSkypeErrCreate>
+ <HistoryToDBSyncSkypeErrDelete>Ошибка при удалении экземпляра Skype</HistoryToDBSyncSkypeErrDelete>
+ <HistoryToDBSyncSkypeErrAttach>Ошибка при подключении к экземпляру Skype</HistoryToDBSyncSkypeErrAttach>
+ <HistoryToDBSyncSkypeRun>Пытаемся запустить Skype...</HistoryToDBSyncSkypeRun>
+ <HistoryToDBSyncSkypeRunErr>Ошибка при запуске Skype</HistoryToDBSyncSkypeRunErr>
+ <HistoryToDBSyncSkypeInitErr>Ошибка при создании интерфейса Skype</HistoryToDBSyncSkypeInitErr>
+ <HistoryToDBSyncSkypeNotFound>Возможно на компьютере не установлен Skype или его версия ниже 5.0</HistoryToDBSyncSkypeNotFound>
+
+ <ImportQHFHistory>Импорт истории из QIP 2010/Infium/2012</ImportQHFHistory>
+ <ImportTXTHistory>Импорт истории из QIP 2005</ImportTXTHistory>
+ <ImportGBMain> Параметры импорта истории </ImportGBMain>
+ <ImportRButtonSelectDir>Загрузить из директории</ImportRButtonSelectDir>
+ <ImportRButtonSelectFile>Загрузить из одного файла</ImportRButtonSelectFile>
+ <ImportOpenHistoryFile>Открыть файл истории</ImportOpenHistoryFile>
+ <ImportLSelect>Выберите:</ImportLSelect>
+ <ImportLSelectSelectDir>Выберите директорию:</ImportLSelectSelectDir>
+ <ImportLSelectSelectFile>Выберите файл:</ImportLSelectSelectFile>
+ <ImportLStatusUnknown>Неизвестно</ImportLStatusUnknown>
+ <ImportButtonSelectSource>Выбрать</ImportButtonSelectSource>
+ <ImportButtonSelectSourceDir>Выбрать директорию</ImportButtonSelectSourceDir>
+ <ImportButtonSelectSourceFile>Выбрать файл</ImportButtonSelectSourceFile>
+ <ImportButtonToSQL>Сформировать SQL-файл</ImportButtonToSQL>
+ <ImportCBPreview>Предпросмотр истории</ImportCBPreview>
+ <ImportLReciver>Получатель:</ImportLReciver>
+ <ImportLMessage>Всего сообщений:</ImportLMessage>
+ <ImportLMyNick>Мои Nickname:</ImportLMyNick>
+ <ImportLMyUIN>Мой UserID:</ImportLMyUIN>
+ <ImportLStatusTitle>Статус:</ImportLStatusTitle>
+ <ImportLAddedInSQLFile>Обработано сообщений:</ImportLAddedInSQLFile>
+ <ImportAdvSelectDirectory>Выберите каталог</ImportAdvSelectDirectory>
+ <ImportQIPHistoryAllQHFFile>Все файлы истории QIP 2010/Infium/2012 (*.qhf;*.ahf)</ImportQIPHistoryAllQHFFile>
+ <ImportQIPHistoryQHFFile>Файлы истории QIP 2010/Infium/2012 (*.qhf)</ImportQIPHistoryQHFFile>
+ <ImportQIPHistoryQHFArcFile>Архивные файлы истории QIP 2010/Infium/2012 (*.ahf)</ImportQIPHistoryQHFArcFile>
+ <ImportQIPHistoryTXTFile>Файлы истории QIP 2005 (*.txt)</ImportQIPHistoryTXTFile>
+ <ImportSelectHistoryFile>Выбран файл %s</ImportSelectHistoryFile>
+ <ImportHistoryFile>Файл истории</ImportHistoryFile>
+ <ImportHistoryFileReadError>Ошибка чтения файла</ImportHistoryFileReadError>
+ <ImportStop>Остановить</ImportStop>
+ <ImportStoped>Остановлено (%s)</ImportStoped>
+ <ImportDone>Готово!</ImportDone>
+ <ImportSelectFile>Выберите файл(ы) для импорта</ImportSelectFile>
+ <ImportProceed>Продолжить</ImportProceed>
+ <ImportWait>Ждите...</ImportWait>
+ <ImportRecordStart>Идет запись в SQL-файл...</ImportRecordStart>
+ <ImportDoneSyncWait>Импорт закончен. После очередного сеанса синхронизации вся информация будет добавлена в БД.</ImportDoneSyncWait>
+ <ImportRnQHistoryFile>Файлы истории RnQ (*.*)</ImportRnQHistoryFile>
+ <ImportRnQHistory>Импорт истории из RnQ</ImportRnQHistory>
+ <ImportRnQStart>Запущен импорт истории из RnQ</ImportRnQStart>
+ <ImportTXTStart>Запущен импорт истории из QIP 2005</ImportTXTStart>
+ <ImportQHFStart>Запущен импорт истории из QIP 2010/Infium/2012</ImportQHFStart>
+ <ImportSelectCnt>Всего выбрано %s файлов истории.</ImportSelectCnt>
+ <ImportProcessing>Идет обработка файла %s</ImportProcessing>
+ <ImportDoneCnt>Импортировано %s записей.</ImportDoneCnt>
+ <ImportProcessingDone>Файл %s обработан.</ImportProcessingDone>
+ <ImportFoundCnt>Всего найдено %s записей.</ImportFoundCnt>
+ <ImportICQHistory>Импорт истории из ICQ 7</ImportICQHistory>
+ <ImportICQHistoryFile>Файлы истории ICQ 7 (Messages.qdb)</ImportICQHistoryFile>
+ <ImportICQStart>Запущен импорт истории из ICQ 7</ImportICQStart>
+ <ImportICQDBConnected>Вы подключены к БД %s</ImportICQDBConnected>
+ <ImportICQDBLocked>База данных заблокирована. Закройте клиента ICQ 7 и повторите попытку.</ImportICQDBLocked>
+ <ImportICQFoundHistory>Найдена история переписки с пользователем %s</ImportICQFoundHistory>
+ <ImportICQDoneCnt>Импортировано %s записей.</ImportICQDoneCnt>
+
+ <EncryptKey>Создание ключа шифрования</EncryptKey>
+ <GBKeyProp> Создание ключа шифрования </GBKeyProp>
+ <LKeyStatusTitle>Статус ключа:</LKeyStatusTitle>
+ <LCBEncryptionMethod>Алгоритм шифрования:</LCBEncryptionMethod>
+ <LKeyLength>Длина ключа (символов):</LKeyLength>
+ <LKeyPassword>Пароль ключа:</LKeyPassword>
+ <LEncryptionKey>Ключ шифрования:</LEncryptionKey>
+ <LEncryptionKeyDesc>(Закодирован в BASE64)</LEncryptionKeyDesc>
+ <LLocation>Место хранения ключа:</LLocation>
+ <ButtonCreateKey>Сгенерировать и сохранить</ButtonCreateKey>
+ <GetEncryptPassword>Введите пароль для защиты ключа шифрования.</GetEncryptPassword>
+ <CheckActiveEncryptKey>У Вас уже есть один активный ключ, поменяйте статус старого ключа и повторите операцию генерации нового ключа.</CheckActiveEncryptKey>
+ <SaveEncryptKeyDone>Ваш новый ключ сгенерирован и сохранен под номером %s</SaveEncryptKeyDone>
+ <SaveDBEncryptKeyDone>Ваш новый ключ сгенерирован и сохранен в БД под номером %s</SaveDBEncryptKeyDone>
+ <SaveEncryptKeyDoneHelp>Пожалуйста, запомните введенный пароль и номер ключа.</SaveEncryptKeyDoneHelp>
+ <SaveEncryptKeyErr>Произошла ошибка при сохранении ключа в БД. Проверьте настройки БД и попробуйте еще раз.</SaveEncryptKeyErr>
+ <KeyStatusActive>Активный</KeyStatusActive>
+ <KeyStatusInactive>Неактивный</KeyStatusInactive>
+ <KeyLocationLocal>Локально</KeyLocationLocal>
+ <KeyLocationServer>На сервере в БД</KeyLocationServer>
+ <StatusChangeKey>Изменить статус ключа</StatusChangeKey>
+ <PasswordChangeKey>Изменить пароль ключа</PasswordChangeKey>
+ <DeleteKey>Удалить ключ</DeleteKey>
+ <CheckNumActiveEncryptKey>В базе данных уже есть один активный ключ. Измените статус активного ключа, а потом вернитесь к этой операции.</CheckNumActiveEncryptKey>
+ <EncryptKeyStatusChanged>Статус ключа изменен.</EncryptKeyStatusChanged>
+ <DeleteEncryptKeyCaption>Удаление ключа шифрования</DeleteEncryptKeyCaption>
+ <DeleteEncryptKey>В базе данных найдены сообщения зашифрованные этим ключом. Вы действительно хотите удалить этот ключ?</DeleteEncryptKey>
+ <EncryptKeyDeleted>Ключ шифрования удален.</EncryptKeyDeleted>
+ <DeleteActiveEncryptKey>ВНИМАНИЕ! Вы собираетесь удалить активный ключ. Без активного ключа шифрование сообщений будет невозможно.</DeleteActiveEncryptKey>
+ <KeyPasswordChangeCaption>Смена пароля ключа шифрования</KeyPasswordChangeCaption>
+ <ErrKeyPasswordChange>Введен неправильный текущий пароль ключа шифрования.</ErrKeyPasswordChange>
+ <ErrKeyPasswordChangeNotRenew>Введенные новые пароли и подтверждение не совпадают или пустые. Повторите попытку.</ErrKeyPasswordChangeNotRenew>
+ <KeyPasswordChanged>Пароль на ключ шифрования изменен.</KeyPasswordChanged>
+ <GBKeyPasswordChange> Смена пароля ключа шифрования </GBKeyPasswordChange>
+ <LCurrentPassword>Текущий пароль:</LCurrentPassword>
+ <LNewPassword>Новый пароль:</LNewPassword>
+ <LReNewPassword>Повторите новый пароль:</LReNewPassword>
+ <ButtonNewKeyPassword>Сменить пароль</ButtonNewKeyPassword>
+ <FontCustomColorCaption>Другой цвет...</FontCustomColorCaption>
+ <FontDefaultColorCaption>Авто</FontDefaultColorCaption>
+ <GeneralSettings>Общие настройки</GeneralSettings>
+ <ConnectionSettings>Настройки соединения</ConnectionSettings>
+ <Logs>Лог работы</Logs>
+ <SelectDBTypeAndIMClient>Вначале выберите "Тип БД" и "IM-клиент".</SelectDBTypeAndIMClient>
+ <UpdateButton>Обновить</UpdateButton>
+ <StopButton>Остановить</StopButton>
+ <SettingsButton>Настройки</SettingsButton>
+ <IMClientType>IM-клиент:</IMClientType>
+ <UseProxy>Использовать прокси-сервер</UseProxy>
+ <ProxyAddress>Адрес прокси-сервера:</ProxyAddress>
+ <ProxyPort>Порт:</ProxyPort>
+ <ProxyAuth>Прокси-сервер требует авторизацию</ProxyAuth>
+ <ProxyUser>Пользователь:</ProxyUser>
+ <ProxyUserPasswd>Пароль:</ProxyUserPasswd>
+ <Update> Обновление </Update>
+ <UpdateStatus>Нажмите кнопку "Обновить" для начала процесса обновления.</UpdateStatus>
+ <Amount>Объем:</Amount>
+ <Speed>Скорость:</Speed>
+ <FileName>Имя файла:</FileName>
+ <FileDesc>Описание:</FileDesc>
+ <FileSize>Размер файла:</FileSize>
+ <Unknown>Не известно</Unknown>
+ <NotFoundLangFile>Не найден файл локализации</NotFoundLangFile>
+ <InitDownload>Инициализация скачивания...</InitDownload>
+ <Kb>Кбайт</Kb>
+ <KbSec>Кбайт/сек</KbSec>
+ <InitDownloadFromURL>Инициализация скачивания c URL</InitDownloadFromURL>
+ <InvalidResponseHeader>Неправильный заголовок ответа с сервера.</InvalidResponseHeader>
+ <InvalidResponseHeaderDesc>Проверьте настройки подключения к Интернет. Возможно Ваш прокси-сервер блокирует доступ к сайту обновления.</InvalidResponseHeaderDesc>
+ <HeaderData>Данные заголовка:</HeaderData>
+ <ParseHeader>Парсим заголовок...</ParseHeader>
+ <ErrInternetOpen>Ошибка при открытии сессии.</ErrInternetOpen>
+ <ErrInternetOpenURL>Ошибка при запрашивании файла.</ErrInternetOpenURL>
+ <ErrDownloadingFile>Ошибка при чтении файла.</ErrDownloadingFile>
+ <ErrRequest>Ошибка при запросе данных через прокси-сервер.</ErrRequest>
+ <Loading>Идет загрузка...</Loading>
+ <DownloadStopped>Скачивание остановлено.</DownloadStopped>
+ <ManualUpdate>Завершите работу всех компонентов плагина вручную и попробуйте повторить обновление.</ManualUpdate>
+ <DownloadSuccessful>Скачивание успешно завершено.</DownloadSuccessful>
+ <IsChecksum>Идет подсчёт контрольной суммы файла...</IsChecksum>
+ <MD5FileInMemory>MD5 файла в памяти:</MD5FileInMemory>
+ <FileSizeInMemory>Размер файла в памяти:</FileSizeInMemory>
+ <ChecksumConfirmed>Контрольная сумма и размер файла подтверждены.</ChecksumConfirmed>
+ <ChecksumFileEqServer>Контрольная сумма файла на диске и на сервере совпадают.</ChecksumFileEqServer>
+ <ChecksumNotConfirmed>Не сходится контрольная сумма принятых данных.</ChecksumNotConfirmed>
+ <FileSavedAs>Файл сохранен под именем</FileSavedAs>
+ <ErrFileSavedAs>Ошибка сохранения файла</ErrFileSavedAs>
+ <SizeNotConfirmed>Не сходится размер принятых данных.</SizeNotConfirmed>
+ <AllUpdatesDownloaded>Все обновления успешно загружены.</AllUpdatesDownloaded>
+ <AllUpdatesInstalled>Все обновления успешно установлены.</AllUpdatesInstalled>
+ <Step>Шаг</Step>
+ <NumberFilesUpdate>Число файлов для обновления</NumberFilesUpdate>
+ <FileToUpdate>Очередной файл для обновления</FileToUpdate>
+ <UpdateSettingsFileNotFound>Не найден файл настроек обновления</UpdateSettingsFileNotFound>
+ <UpdateLangFile>Начинаем обновление файла локализации %s...</UpdateLangFile>
+ <UpdateLangFileDone>Обновление файла локализации %s выполнено.</UpdateLangFileDone>
+ <UpdateSQLFile>Начинаем обновление sql-файла %s...</UpdateSQLFile>
+ <UpdateSQLFileDone>Обновление sql-файла %s выполнено.</UpdateSQLFileDone>
+ <UpdateFile>Начинаем обновление файла %s...</UpdateFile>
+ <UpdateFileDone>Обновление файла %s выполнено.</UpdateFileDone>
+ <UpdateFileErr>Файл %s не обновлен.</UpdateFileErr>
+ <InMemoryFoundProcess>В памяти найден процесс %s (PID: %s)</InMemoryFoundProcess>
+ <SendExitCommand>Отправляем команду завершения...</SendExitCommand>
+ <SearchProcessInMemory>Повторно ищем процесс %s в памяти...</SearchProcessInMemory>
+ <KillProcess>Пытаемся принудительно завершить процесс %s</KillProcess>
+ <KillProcessDone>Процесс %s принудительно завершен.</KillProcessDone>
+ <NotKillProcess>Процесс %s не может быть принудительно завершен.</NotKillProcess>
+ <SeDebugPrivilege>Повышаем свои привилегии до SeDebugPrivilege и пробуем еще раз завершить процесс %s</SeDebugPrivilege>
+ <SeDebugPrivilegeDone>Процесс %s принудительно завершен при SeDebugPrivilege.</SeDebugPrivilegeDone>
+ <NotKillSeDebugPrivilege>Процесс %s не может быть принудительно завершен даже при SeDebugPrivilege.</NotKillSeDebugPrivilege>
+ <InMemoryNotFoundProcess>Процесс %s не найден в памяти.</InMemoryNotFoundProcess>
+ <EndProcess>Пытаемся завершить процесс %s</EndProcess>
+ <StartProgram>Запускаем программу %s</StartProgram>
+ <StartProgramDone>Программа %s запущена.</StartProgramDone>
+ <StartProgramFail>Программа %s не запущена.</StartProgramFail>
+
+</strings> \ No newline at end of file
diff --git a/plugins/MirandaNGHistoryToDB/m_historytodb.inc b/plugins/MirandaNGHistoryToDB/m_historytodb.inc
new file mode 100644
index 0000000000..07aa224029
--- /dev/null
+++ b/plugins/MirandaNGHistoryToDB/m_historytodb.inc
@@ -0,0 +1,40 @@
+{ ############################################################################ }
+{ # # }
+{ # MirandaNG HistoryToDB Plugin v2.4 # }
+{ # # }
+{ # License: GPLv3 # }
+{ # # }
+{ # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # }
+{ # # }
+{ ############################################################################ }
+
+{$IFNDEF M_HISTORYTODB}
+{$DEFINE M_HISTORYTODB}
+
+const
+
+ // MS_MHTD_SHOWHISTORY
+ // (supported from 2.4.0)
+ // Open history
+ // wParam - zero
+ // lParam - zero
+ // Return - 0
+ MS_MHTD_SHOWHISTORY = 'MirandaNGHistoryToDB/ShowHistory';
+
+ // MS_MHTD_SHOWCONTACTHISTORY
+ // (supported from 2.4.0)
+ // Open contact history
+ // wParam - hContact
+ // lParam - zero
+ // Return - 0
+ MS_MHTD_SHOWCONTACTHISTORY = 'MirandaNGHistoryToDB/ShowContactHistory';
+
+ // MS_MHTD_GETVERSION
+ // (supported from 2.4.0)
+ // Get current MirandaNGHistoryToDB version
+ // wParam - zero
+ // lParam - zero
+ // Return - current version, via PLUGIN_MAKE_VERSION macro
+ MS_MHTD_GETVERSION = 'MirandaNGHistoryToDB/GetVersion';
+
+{$ENDIF}