diff --git a/.gitignore b/.gitignore index 86fe1c7..de9a8f2 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ backup/ *.compiled demo project1 +TestPyThread diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bd34b12 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Dietmar Budelsky, Morgan Martinet, Kiriakos Vlahos + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/demos_delphi/Demo01/Project1.conf b/demos_delphi/Demo01/Project1.conf deleted file mode 100644 index 84e6d10..0000000 --- a/demos_delphi/Demo01/Project1.conf +++ /dev/null @@ -1,32 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --H+ --W+ --M --$M16384,1048576 --K$00400000 diff --git a/demos_delphi/Demo01/Project1.dpr b/demos_delphi/Demo01/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo01/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo01/Project1.dproj b/demos_delphi/Demo01/Project1.dproj deleted file mode 100644 index ab56e83..0000000 --- a/demos_delphi/Demo01/Project1.dproj +++ /dev/null @@ -1,151 +0,0 @@ - - - {CA67512A-3B3A-48FD-8952-5503337690C4} - Project1.dpr - Debug - DCC32 - 16.1 - VCL - True - Win64 - 3 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - Project1 - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - 1033 - Project1.exe - 00400000 - x86 - - - true - Project1_Icon.ico - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - $(BDS)\bin\default_app.manifest - - - true - $(BDS)\bin\default_app.manifest - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Project1_Icon.ico - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - - - $(BDS)\bin\delphi_PROJECTICON.ico - true - - - - MainSource - - -
Form1
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - 12 - - -
diff --git a/demos_delphi/Demo01/Project1.kof b/demos_delphi/Demo01/Project1.kof deleted file mode 100644 index 6ad26fc..0000000 --- a/demos_delphi/Demo01/Project1.kof +++ /dev/null @@ -1,61 +0,0 @@ -[Compiler] -A=8 -B=0 -C=1 -D=1 -E=0 -F=0 -G=1 -H=1 -I=1 -J=0 -K=0 -L=1 -M=0 -N=1 -O=1 -P=1 -Q=0 -R=0 -S=0 -T=0 -U=0 -V=1 -W=0 -X=1 -Y=1 -Z=1 -ShowHints=1 -ShowWarnings=1 -UnitAliases= - -[Linker] -MapFile=0 -OutputObjs=0 -ConsoleApp=1 -DebugInfo=0 -RemoteSymbols=0 -MinStackSize=16384 -MaxStackSize=1048576 -ImageBase=4194304 -ExeDescription= -DynamicLoader=/lib/ld-linux.so.2 - -[Directories] -OutputDir= -UnitOutputDir= -PackageDLLOutputDir= -PackageDCPOutputDir= -SearchPath= -Packages= -Conditionals= -DebugSourceDirs= -UsePackages=0 - -[Parameters] -RunParams= -HostApplication= -Launcher=/usr/X11R6/bin/xterm -T KylixDebuggerOutput -e bash -i -c %debuggee% -UseLauncher=0 -DebugCWD= - diff --git a/demos_delphi/Demo01/Project1.res b/demos_delphi/Demo01/Project1.res deleted file mode 100644 index 3f7606c..0000000 Binary files a/demos_delphi/Demo01/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo01/Unit1.dfm b/demos_delphi/Demo01/Unit1.dfm deleted file mode 100644 index dd29a57..0000000 Binary files a/demos_delphi/Demo01/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo01/Unit1.pas b/demos_delphi/Demo01/Unit1.pas deleted file mode 100644 index 6bce430..0000000 --- a/demos_delphi/Demo01/Unit1.pas +++ /dev/null @@ -1,66 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - - -var - Form1: TForm1; - -implementation - -{$R *.DFM} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -end. diff --git a/demos_delphi/Demo02/Project1.conf b/demos_delphi/Demo02/Project1.conf deleted file mode 100644 index 84e6d10..0000000 --- a/demos_delphi/Demo02/Project1.conf +++ /dev/null @@ -1,32 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --H+ --W+ --M --$M16384,1048576 --K$00400000 diff --git a/demos_delphi/Demo02/Project1.dpr b/demos_delphi/Demo02/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo02/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo02/Project1.dproj b/demos_delphi/Demo02/Project1.dproj deleted file mode 100644 index fa1d28a..0000000 --- a/demos_delphi/Demo02/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {C2FA2A8D-7DA4-4631-B05E-4C16A0FC8F3B} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo02/Project1.res b/demos_delphi/Demo02/Project1.res deleted file mode 100644 index 55f8742..0000000 Binary files a/demos_delphi/Demo02/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo02/Unit1.dfm b/demos_delphi/Demo02/Unit1.dfm deleted file mode 100644 index 7ce3a15..0000000 Binary files a/demos_delphi/Demo02/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo02/Unit1.pas b/demos_delphi/Demo02/Unit1.pas deleted file mode 100644 index f009259..0000000 --- a/demos_delphi/Demo02/Unit1.pas +++ /dev/null @@ -1,80 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo2: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo1: TMemo; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - -var - Form1: TForm1; - -implementation - -{$R *.DFM} - -procedure TForm1.Button1Click(Sender: TObject); -var - Result : PPyObject; -begin - with PythonEngine1 do - begin - Result := EvalStrings( Memo1.Lines ); - if Assigned(Result) then - begin - ShowMessage(Format('Eval: %s',[PyObjectAsString(Result)])); - Py_DECREF(Result); - end - else - ShowMessage('Could not evaluate the script'); - // Or you could simply use: - // ShowMessage('Eval: ' + EvalStringsAsStr( Memo1.Lines ) ); - end; -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -end. diff --git a/demos_delphi/Demo03/Project1.dpr b/demos_delphi/Demo03/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo03/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo03/Project1.dproj b/demos_delphi/Demo03/Project1.dproj deleted file mode 100644 index cd6e40a..0000000 --- a/demos_delphi/Demo03/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {BA2F2117-1B8F-44C7-8610-DAB4F55DB2EC} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo03/Project1.res b/demos_delphi/Demo03/Project1.res deleted file mode 100644 index 6008d58..0000000 Binary files a/demos_delphi/Demo03/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo03/Unit1.dfm b/demos_delphi/Demo03/Unit1.dfm deleted file mode 100644 index a6bb8e6..0000000 Binary files a/demos_delphi/Demo03/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo03/Unit1.pas b/demos_delphi/Demo03/Unit1.pas deleted file mode 100644 index de21c6a..0000000 --- a/demos_delphi/Demo03/Unit1.pas +++ /dev/null @@ -1,74 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, StdCtrls, - ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonDelphiVar1: TPythonDelphiVar; - Button4: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.Button4Click(Sender: TObject); -begin - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); -end; - -end. diff --git a/demos_delphi/Demo04/Project1.dpr b/demos_delphi/Demo04/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo04/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo04/Project1.dproj b/demos_delphi/Demo04/Project1.dproj deleted file mode 100644 index a1b2994..0000000 --- a/demos_delphi/Demo04/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {6F45452F-882D-4BBD-8AEA-872276E8B856} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo04/Project1.res b/demos_delphi/Demo04/Project1.res deleted file mode 100644 index fdf1db3..0000000 Binary files a/demos_delphi/Demo04/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo04/Unit1.dfm b/demos_delphi/Demo04/Unit1.dfm deleted file mode 100644 index 9dfab95..0000000 Binary files a/demos_delphi/Demo04/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo04/Unit1.pas b/demos_delphi/Demo04/Unit1.pas deleted file mode 100644 index f4b3c49..0000000 --- a/demos_delphi/Demo04/Unit1.pas +++ /dev/null @@ -1,121 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonDelphiVar1: TPythonDelphiVar; - Button4: TButton; - Edit1: TEdit; - Label1: TLabel; - PythonGUIInputOutput1: TPythonGUIInputOutput; - PythonDelphiVar2: TPythonDelphiVar; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - procedure PythonDelphiVar1Change(Sender: TObject); - procedure PythonDelphiVar1GetData(Sender: TObject; var Data: Variant); - procedure PythonDelphiVar1SetData(Sender: TObject; Data: Variant); - procedure PythonDelphiVar2ExtGetData(Sender: TObject; - var Data: PPyObject); - procedure PythonDelphiVar2ExtSetData(Sender: TObject; Data: PPyObject); - private - { D�clarations priv�es } - FMyPythonObject : PPyObject; - public - { D�clarations publiques } - end; - -var - Form1: TForm1; - -implementation -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.Button4Click(Sender: TObject); -begin - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1Change(Sender: TObject); -begin - with Sender as TPythonDelphiVar do - ShowMessage( 'Var test changed: ' + ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1GetData(Sender: TObject; - var Data: Variant); -begin - Data := Edit1.Text; -end; - -procedure TForm1.PythonDelphiVar1SetData(Sender: TObject; Data: Variant); -begin - Edit1.Text := Data; -end; - -procedure TForm1.PythonDelphiVar2ExtGetData(Sender: TObject; - var Data: PPyObject); -begin - with GetPythonEngine do - begin - Data := FMyPythonObject; - Py_XIncRef(Data); // This is very important - end; -end; - -procedure TForm1.PythonDelphiVar2ExtSetData(Sender: TObject; - Data: PPyObject); -begin - with GetPythonEngine do - begin - Py_XDecRef(FMyPythonObject); // This is very important - FMyPythonObject := Data; - Py_XIncRef(FMyPythonObject); // This is very important - end; -end; - -end. diff --git a/demos_delphi/Demo05/Project1.dpr b/demos_delphi/Demo05/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo05/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo05/Project1.dproj b/demos_delphi/Demo05/Project1.dproj deleted file mode 100644 index 1a4f4a8..0000000 --- a/demos_delphi/Demo05/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {38ABBD9D-A0AD-422F-959B-062CAB828F37} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo05/Project1.res b/demos_delphi/Demo05/Project1.res deleted file mode 100644 index 6008d58..0000000 Binary files a/demos_delphi/Demo05/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo05/Unit1.dfm b/demos_delphi/Demo05/Unit1.dfm deleted file mode 100644 index 58012c7..0000000 Binary files a/demos_delphi/Demo05/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo05/Unit1.pas b/demos_delphi/Demo05/Unit1.pas deleted file mode 100644 index ba44d2f..0000000 --- a/demos_delphi/Demo05/Unit1.pas +++ /dev/null @@ -1,90 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - PythonModule1: TPythonModule; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure PythonModule1Initialization(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - - function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; - -var - Form1: TForm1; - -implementation -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -// Here's an example of functions defined for the module spam - -function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - ShowMessage( 'args of foo: '+PyObjectAsString(args) ); - Result := ReturnNone; - end; -end; - -procedure TForm1.PythonModule1Initialization(Sender: TObject); -begin - // In a module initialization, we just need to add our - // new methods - with Sender as TPythonModule do - begin - AddMethod( 'foo', spam_foo, 'foo' ); - end; -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -end. diff --git a/demos_delphi/Demo06/Project1.dpr b/demos_delphi/Demo06/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo06/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo06/Project1.dproj b/demos_delphi/Demo06/Project1.dproj deleted file mode 100644 index 7dc3bed..0000000 --- a/demos_delphi/Demo06/Project1.dproj +++ /dev/null @@ -1,134 +0,0 @@ - - - {2E88E1AD-C1A3-403E-8AEE-28895B68FBF7} - Project1.dpr - Debug - DCC32 - 13.4 - VCL - True - Win32 - 1 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - 1033 - Project1.exe - 00400000 - x86 - - - Project1_Icon.ico - - - true - Project1_Icon.ico - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - $(BDS)\bin\default_app.manifest - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - False - True - - - 12 - - -
diff --git a/demos_delphi/Demo06/Project1.res b/demos_delphi/Demo06/Project1.res deleted file mode 100644 index 3f7606c..0000000 Binary files a/demos_delphi/Demo06/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo06/Unit1.dfm b/demos_delphi/Demo06/Unit1.dfm deleted file mode 100644 index 832fdbd..0000000 Binary files a/demos_delphi/Demo06/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo06/Unit1.pas b/demos_delphi/Demo06/Unit1.pas deleted file mode 100644 index 4d06f02..0000000 --- a/demos_delphi/Demo06/Unit1.pas +++ /dev/null @@ -1,295 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - PythonType1: TPythonType; - PythonModule1: TPythonModule; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonDelphiVar1: TPythonDelphiVar; - Button4: TButton; - Edit1: TEdit; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure PythonModule1Initialization(Sender: TObject); - procedure PythonType1Initialization(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - procedure PythonDelphiVar1Change(Sender: TObject); - procedure PythonDelphiVar1GetData(Sender: TObject; var Data: Variant); - procedure PythonDelphiVar1SetData(Sender: TObject; Data: Variant); - private - public - end; - - PyPointRec = record - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - po_x : Integer; - po_y : Integer; - end; - PPyPoint = ^PyPointRec; - - function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; - function spam_CreatePoint( self, args : PPyObject ) : PPyObject; cdecl; - function spam_getdouble( self, args : PPyObject ) : PPyObject; cdecl; - - procedure PyPoint_dealloc(obj : PPyObject); cdecl; - function PyPoint_getattr(obj : PPyObject; key : PAnsiChar) : PPyObject; cdecl; - function PyPoint_setattrfunc(obj : PPyObject; key : PAnsiChar; value : PPyObject) : Integer; cdecl; - function PyPoint_repr(obj : PPyObject) : PPyObject; cdecl; - -var - Form1: TForm1; - -implementation -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -// Here's an example of functions defined for the module spam - -function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - ShowMessage( 'args of foo: '+PyObjectAsString(args) ); - Result := ReturnNone; - end; -end; - -// This function is used to create a PyPoint instance -function spam_CreatePoint( self, args : PPyObject ) : PPyObject; cdecl; -var - x, y : Integer; - p : PPyPoint; -begin - with GetPythonEngine do - begin - // We want x and y values as argument - if PyArg_ParseTuple( args, 'ii:CreatePoint',@x, @y) <> 0 then - begin - new(p); - with p^ do - begin - ob_refcnt := 1; - ob_type := TypeByName('Point'); - // or we could write, because it's quicker: - // ob_type := Form1.PythonType1.TheTypePtr; - po_x := x; - po_y := y; - end; - Result := PPyObject(p); - end - else - Result := nil; - end; -end; - -function spam_getdouble( self, args : PPyObject ) : PPyObject; cdecl; -// you need to pass floating point numbers as doubles to Py_BuildValue -Const - x : double = 2.7172; - y : double = 3.14159; - z : double = 1.2e-12; -begin - with GetPythonEngine do - begin - Result := Py_BuildValue('(iiddid)',42,815,x,y,4711,z); - end; -end; - -procedure TForm1.PythonModule1Initialization(Sender: TObject); -begin - // In a module initialization, we just need to add our - // new methods - with Sender as TPythonModule do - begin - AddMethod( 'foo', spam_foo, 'foo' ); - AddMethod( 'CreatePoint', spam_CreatePoint, - 'function CreatePoint'+LF+ - 'Args: x, y'+LF+ - 'Result: a new Point object' ); - AddMethod( 'getdouble', spam_getdouble, 'getdouble' ); - end; -end; - -// Here's an example of a new type object. -// That's more complex than a new module, but here's a -// template that you can follow. - -// Here's the destructor of the object -procedure PyPoint_dealloc(obj : PPyObject); cdecl; -begin - Dispose(obj); -end; - -// Here's the read access to the attributes of an object. -// In fact it is called each time you write: -// object.value -// object.method(args) -function PyPoint_getattr(obj : PPyObject; key : PAnsiChar) : PPyObject; cdecl; -begin - with GetPythonEngine, PPyPoint(obj)^ do - begin - // Check for attribute x - if key = 'x' then - Result := PyInt_FromLong( po_x ) - // Check for attribute y - else if key = 'y' then - Result := PyInt_FromLong( po_y ) - else - begin - // Else check for a method - Result := PyObject_GenericGetAttr(obj, PyString_FromString(key)); - if not Assigned(Result) then - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown attribute "%s"',[key]))); - end; - end; -end; - -// Here's the write access to the attributes of an object. -// In fact it is called each time you write: -// object.value = 1 -function PyPoint_setattrfunc(obj : PPyObject; key : PAnsiChar; value : PPyObject) : Integer; cdecl; -begin - Result := -1; - with GetPythonEngine, PPyPoint(obj)^ do - begin - // Check for attribute x - if key = 'x' then begin - if PyInt_Check(value) then - begin - po_x := PyInt_AsLong(value); - Result := 0; - end - else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Attribute "%s" needs an integer',[key]))); - // Check for attribute y - end else if key = 'y' then begin - if PyInt_Check(value) then - begin - po_y := PyInt_AsLong(value); - Result := 0; - end - else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Attribute "%s" needs an integer',[key]))); - end else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown attribute "%s"',[key]))); - end; -end; - -// Here's how an object should be represented, when printed for instance. -function PyPoint_repr(obj : PPyObject) : PPyObject; cdecl; -begin - with GetPythonEngine, PPyPoint(obj)^ do - begin - Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[po_x, po_y]) ) ); - end; -end; - -// Here's a method of the object PyPoint -function PyPoint_OffsetBy(self, args : PPyObject) : PPyObject; cdecl; -var - x, y : Integer; -begin - with GetPythonEngine, PPyPoint(self)^ do - begin - if PyArg_ParseTuple( args, 'ii:OffsetBy',@x, @y) <> 0 then - begin - Inc( po_x, x ); - Inc( po_y, y ); - Result := ReturnNone; - end - else - Result := nil; - end; -end; - -procedure TForm1.PythonType1Initialization(Sender: TObject); -Var - PyType : PyTypeObject; -begin - with (Sender as TPythonType) do - begin - // In the initialization of a new type, we must - // define the attributes of this type - PyType := TheType; - with PyType do - begin - tp_basicsize := sizeof(PyPointRec); - tp_dealloc := PyPoint_dealloc; - tp_getattr := PyPoint_getattr; - tp_setattr := PyPoint_setattrfunc; - tp_repr := PyPoint_repr; - tp_str := PyPoint_repr; - end; - TheType := PyType; - // And then add the methods of the object, if needed - AddMethod( 'OffsetBy', PyPoint_OffsetBy, 'OffsetBy(dx, dy)' ); - end; -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.Button4Click(Sender: TObject); -begin - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1Change(Sender: TObject); -begin - with Sender as TPythonDelphiVar do - ShowMessage( 'Var test changed: ' + ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1GetData(Sender: TObject; - var Data: Variant); -begin - Data := Edit1.Text; -end; - -procedure TForm1.PythonDelphiVar1SetData(Sender: TObject; Data: Variant); -begin - Edit1.Text := Data; -end; - -end. diff --git a/demos_delphi/Demo07/Project1.dpr b/demos_delphi/Demo07/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo07/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo07/Project1.dproj b/demos_delphi/Demo07/Project1.dproj deleted file mode 100644 index 7a373b7..0000000 --- a/demos_delphi/Demo07/Project1.dproj +++ /dev/null @@ -1,134 +0,0 @@ - - - {241C5DB1-E30A-4305-9F0A-4B7DD00FAD59} - Project1.dpr - Debug - DCC32 - 13.4 - VCL - True - Win32 - 1 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - 1033 - Project1.exe - 00400000 - x86 - - - Project1_Icon1.ico - - - true - Project1_Icon1.ico - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - $(BDS)\bin\default_app.manifest - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - False - True - - - 12 - - -
diff --git a/demos_delphi/Demo07/Project1.res b/demos_delphi/Demo07/Project1.res deleted file mode 100644 index 3f7606c..0000000 Binary files a/demos_delphi/Demo07/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo07/Unit1.dfm b/demos_delphi/Demo07/Unit1.dfm deleted file mode 100644 index e4d9257..0000000 Binary files a/demos_delphi/Demo07/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo07/Unit1.pas b/demos_delphi/Demo07/Unit1.pas deleted file mode 100644 index 394dd9d..0000000 --- a/demos_delphi/Demo07/Unit1.pas +++ /dev/null @@ -1,335 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - PythonType1: TPythonType; - PythonModule1: TPythonModule; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonDelphiVar1: TPythonDelphiVar; - Button4: TButton; - Edit1: TEdit; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure PythonModule1Initialization(Sender: TObject); - procedure PythonType1Initialization(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - procedure PythonDelphiVar1Change(Sender: TObject); - procedure PythonDelphiVar1GetData(Sender: TObject; var Data: Variant); - procedure PythonDelphiVar1SetData(Sender: TObject; Data: Variant); - private - { D�clarations priv�es } - function spam_foo( pself, args : PPyObject ) : PPyObject; cdecl; - function spam_CreatePoint( pself, args : PPyObject ) : PPyObject; cdecl; - function spam_getdouble( pself, args : PPyObject ) : PPyObject; cdecl; - function spam_getdouble2( pself, args : PPyObject ) : PPyObject; cdecl; - public - { D�clarations publiques } - end; - - PyPointRec = record - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - po_x : Integer; - po_y : Integer; - end; - PPyPoint = ^PyPointRec; - - procedure PyPoint_dealloc(obj : PPyObject); cdecl; - function PyPoint_getattr(obj : PPyObject; key : PAnsiChar) : PPyObject; cdecl; - function PyPoint_setattrfunc(obj : PPyObject; key : PAnsiChar; value : PPyObject) : Integer; cdecl; - function PyPoint_repr(obj : PPyObject) : PPyObject; cdecl; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -// Here's an example of functions defined for the module spam - -function TForm1.spam_foo( pself, args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - ShowMessage( 'args of foo: '+PyObjectAsString(args) ); - ShowMessage( 'Form''s caption = ' + Caption ); - Result := ReturnNone; - end; -end; - -// This function is used to create a PyPoint instance -function TForm1.spam_CreatePoint( pself, args : PPyObject ) : PPyObject; cdecl; -var - x, y : Integer; - p : PPyPoint; -begin - with GetPythonEngine do - begin - // We want x and y values as argument - if PyArg_ParseTuple( args, 'ii:CreatePoint',@x, @y) <> 0 then - begin - new(p); - with p^ do - begin - ob_refcnt := 1; - ob_type := TypeByName('Point'); - // or we could write, because it's quicker: - // ob_type := Form1.PythonType1.TheTypePtr; - po_x := x; - po_y := y; - end; - Result := PPyObject(p); - end - else - Result := nil; - end; -end; - -function TForm1.spam_getdouble( pself, args : PPyObject ) : PPyObject; cdecl; -// you need to pass floating point numbers as doubles to Py_BuildValue -Const - d1 : double = 2.7172; - d2 : double = 3.14159; - d3 : double = 1.2e-12; -var x: Currency; - y: Double; - s: PAnsiChar; - i: integer; -begin - with GetPythonEngine do - begin - self.PythonGUIInputOutput1.write('Hello, World!'+LF); - x := 13.5; - y := 42.0; - i := 42; - s := 'Hallo'; - Result := Py_BuildValue('(sddiiddid)',s,x,y,i,815,d1,d2,4711,d3); - end; -end; - -function TForm1.spam_getdouble2( pself, args : PPyObject ) : PPyObject; cdecl; -var x: Currency; - y: Double; - s: PAnsiChar; - i: integer; -begin - // this is the same function as the previous one, - // except it uses ArrayToPyTuple - with GetPythonEngine do - begin - self.PythonGUIInputOutput1.write('Hello, World!'+LF); - x := 13.5; - y := 42.0; - i := 42; - s := 'Hallo'; - Result := ArrayToPyTuple( [ s,x,y,i,815,2.7172,3.14159,4711,1.2e-12, PyInt_FromLong(333) ] ); - end; -end; - -procedure TForm1.PythonModule1Initialization(Sender: TObject); -begin - // In a module initialization, we just need to add our - // new methods - with Sender as TPythonModule do - begin - AddDelphiMethod( 'foo', - spam_foo, - 'foo' ); - AddDelphiMethod( 'CreatePoint', - spam_CreatePoint, - 'function CreatePoint'+LF+ - 'Args: x, y'+LF+ - 'Result: a new Point object' ); - AddDelphiMethod( 'getdouble', - spam_getdouble, - 'getdouble' ); - AddDelphiMethod( 'getdouble2', - spam_getdouble2, - 'getdouble2' ); - end; -end; - -// Here's an example of a new type object. -// That's more complex than a new module, but here's a -// template that you can follow. - -// Here's the destructor of the object -procedure PyPoint_dealloc(obj : PPyObject); cdecl; -begin - Dispose(obj); -end; - -// Here's the read access to the attributes of an object. -// In fact it is called each time you write: -// object.value -// object.method(args) -function PyPoint_getattr(obj : PPyObject; key : PAnsiChar) : PPyObject; cdecl; -begin - with GetPythonEngine, PPyPoint(obj)^ do - begin - // Check for attribute x - if key = 'x' then - Result := PyInt_FromLong( po_x ) - // Check for attribute y - else if key = 'y' then - Result := PyInt_FromLong( po_y ) - else - begin - // Else check for a method - Result := PyObject_GenericGetAttr(obj, PyString_FromString(key)); - if not Assigned(Result) then - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown attribute "%s"',[key]))); - end; - end; -end; - -// Here's the write access to the attributes of an object. -// In fact it is called each time you write: -// object.value = 1 -function PyPoint_setattrfunc(obj : PPyObject; key : PAnsiChar; value : PPyObject) : Integer; cdecl; -begin - Result := -1; - with GetPythonEngine, PPyPoint(obj)^ do - begin - // Check for attribute x - if key = 'x' then begin - if PyInt_Check(value) then - begin - po_x := PyInt_AsLong(value); - Result := 0; - end - else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Attribute "%s" needs an integer',[key]))); - // Check for attribute y - end else if key = 'y' then begin - if PyInt_Check(value) then - begin - po_y := PyInt_AsLong(value); - Result := 0; - end - else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Attribute "%s" needs an integer',[key]))); - end else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown attribute "%s"',[key]))); - end; -end; - -// Here's how an object should be represented, when printed for instance. -function PyPoint_repr(obj : PPyObject) : PPyObject; cdecl; -begin - with GetPythonEngine, PPyPoint(obj)^ do - begin - Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[po_x, po_y]) ) ); - end; -end; - -// Here's a method of the object PyPoint -function PyPoint_OffsetBy(self, args : PPyObject) : PPyObject; cdecl; -var - x, y : Integer; -begin - with GetPythonEngine, PPyPoint(self)^ do - begin - if PyArg_ParseTuple( args, 'ii:OffsetBy',@x, @y) <> 0 then - begin - Inc( po_x, x ); - Inc( po_y, y ); - Result := ReturnNone; - end - else - Result := nil; - end; -end; - -procedure TForm1.PythonType1Initialization(Sender: TObject); -Var - PyType : PyTypeObject; -begin - with (Sender as TPythonType) do - begin - // In the initialization of a new type, we must - // define the attributes of this type - PyType := TheType; - with PyType do - begin - tp_basicsize := sizeof(PyPointRec); - tp_dealloc := PyPoint_dealloc; - tp_getattr := PyPoint_getattr; - tp_setattr := PyPoint_setattrfunc; - tp_repr := PyPoint_repr; - tp_str := PyPoint_repr; - end; - TheType := PyType; - // And then add the methods of the object, if needed - AddMethod( 'OffsetBy', PyPoint_OffsetBy, 'OffsetBy(dx, dy)' ); - end; -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.Button4Click(Sender: TObject); -begin - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1Change(Sender: TObject); -begin - with Sender as TPythonDelphiVar do - ShowMessage( 'Var test changed: ' + ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1GetData(Sender: TObject; - var Data: Variant); -begin - Data := Edit1.Text; -end; - -procedure TForm1.PythonDelphiVar1SetData(Sender: TObject; Data: Variant); -begin - Edit1.Text := Data; -end; - -end. diff --git a/demos_delphi/Demo07/test.py b/demos_delphi/Demo07/test.py deleted file mode 100644 index 2cb5775..0000000 --- a/demos_delphi/Demo07/test.py +++ /dev/null @@ -1,13 +0,0 @@ -import sys -print "Win version:", sys.winver -import spam -print spam.foo('hello world', 1) -p = spam.CreatePoint( 10, 25 ) -print "Point:", p -p.x = 58 -print p.x, p -p.OffsetBy( 5, 5 ) -print p -print "Current value of var test is: ", test -test.Value = "New value set by Python" -print spam.getdouble() \ No newline at end of file diff --git a/demos_delphi/Demo08/Project1.dpr b/demos_delphi/Demo08/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo08/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo08/Project1.dproj b/demos_delphi/Demo08/Project1.dproj deleted file mode 100644 index f3fe018..0000000 --- a/demos_delphi/Demo08/Project1.dproj +++ /dev/null @@ -1,134 +0,0 @@ - - - {237903A4-03D0-4047-A134-AAF207C6AC42} - Project1.dpr - Debug - DCC32 - 13.4 - VCL - True - Win32 - 1 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - 1033 - Project1.exe - 00400000 - x86 - - - Project1_Icon.ico - - - true - Project1_Icon.ico - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - $(BDS)\bin\default_app.manifest - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - False - True - - - 12 - - -
diff --git a/demos_delphi/Demo08/Project1.res b/demos_delphi/Demo08/Project1.res deleted file mode 100644 index 3f7606c..0000000 Binary files a/demos_delphi/Demo08/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo08/Unit1.dfm b/demos_delphi/Demo08/Unit1.dfm deleted file mode 100644 index 22aef1f..0000000 Binary files a/demos_delphi/Demo08/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo08/Unit1.pas b/demos_delphi/Demo08/Unit1.pas deleted file mode 100644 index 763edb1..0000000 --- a/demos_delphi/Demo08/Unit1.pas +++ /dev/null @@ -1,273 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - PythonEngine1: TPythonEngine; - PythonModule1: TPythonModule; - PythonType1: TPythonType; - Panel1: TPanel; - Button1: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure PythonType1Initialization(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - - // This is a Delphi class implementing a new Python type - // it must derive from TPyObject or one of its descendants. - // Then it must override some methods, like the constructors, - // the RegisterMethods and the type services' virtual methods. - TPyPoint = class(TPyObject) - x, y : Integer; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - function Repr : PPyObject; override; - function RichCompare( obj : PPyObject; Op : TRichComparisonOpcode) : PPyObject; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyPoint - procedure OffsetBy( dx, dy : Integer ); - - // Interface methods - function DoOffsetBy( args : PPyObject ) : PPyObject; cdecl; - function DoRaiseError( args : PPyObject ) : PPyObject; cdecl; - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -// First, we need to initialize the property PyObjectClass with -// the class of our Type object -procedure TForm1.PythonType1Initialization(Sender: TObject); -begin - PythonType1.PyObjectClass := TPyPoint; -end; - -// We override the constructors - -constructor TPyPoint.Create( APythonType : TPythonType ); -begin - inherited; - x := 0; - y := 0; -end; - -// Don't call the Create constructor of TPyPoint, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyPoint.Create will be automatically be called. - -constructor TPyPoint.CreateWith( PythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'ii:CreatePoint',@x, @y ) = 0 then - exit; - end; -end; - -// Then we override the needed services - -function TPyPoint.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if key = 'x' then - Result := VariantAsPyObject( x ) - // Or Result := PyInt_FromLong( x ) - else if key = 'y' then - Result := PyInt_FromLong( y ) - // or Result := PyInt_FromLong( y ) - else - Result := inherited GetAttr(key); - end; -end; - -function TPyPoint.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := 0; - with GetPythonEngine do - begin - if key = 'x' then - begin - if PyArg_Parse( value, 'i:Point.SetAttr', @x ) = 0 then - Result := -1; - end - else if key = 'y' then - begin - if PyArg_Parse( value, 'i:Point.SetAttr', @y ) = 0 then - Result := -1; - end - else - Result := inherited SetAttr(key, value); - end; -end; - -function TPyPoint.Repr : PPyObject; -begin - with GetPythonEngine do - Result := VariantAsPyObject(Format('(%d, %d)',[x, y])); - // or Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[x, y])) ); -end; - -function TPyPoint.RichCompare( obj : PPyObject; Op : TRichComparisonOpcode) : PPyObject; -begin - with GetPythonEngine do - Result := PyInt_FromLong(1); // Return True by default, just for testing the API. -end; - -// Class methods -// We register the methods of our type - -class procedure TPyPoint.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - AddMethod( 'OffsetBy', @TPyPoint.DoOffsetBy, 'Point.OffsetBy( dx, dy )' ); - AddMethod( 'RaiseError', @TPyPoint.DoRaiseError, 'Point.RaiseError()' ); - end; -end; - -// Methods of TPyPoint -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -procedure TPyPoint.OffsetBy( dx, dy : Integer ); -begin - Inc( x, dx ); - Inc( y, dy ); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -function TPyPoint.DoOffsetBy( args : PPyObject ) : PPyObject; -var - dx, dy : Integer; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // first we extract the arguments - if PyArg_ParseTuple( args, 'ii:Point.Offset',@dx, @dy ) <> 0 then - begin - // if it's ok, then we call the method that does the job - // with the correct arguments - OffsetBy( dx, dy ); - // Finally, we return nothing - Result := ReturnNone; - end - else // the arguments were not right - Result := nil; - end; -end; - -// Here's an example of how you can raise errors defined -// in the module linked to our type. -function TPyPoint.DoRaiseError( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // This is a simple call: - //GetModule.RaiseError( 'PointError', 'this is an example of raising an error !' ); - // This is an advanced call: - // We provide the instance vars as a dictionary, so that we can intercept the - // error with "except" and extract informations from the error object. - // ArrayToPyDict needs a list of pairs: varName (string), varValue (anything) - GetModule.RaiseErrorObj( 'EBadPoint', 'this is an example of raising an error !', - ArrayToPyDict( ['a', 1, 'b', 2, 'c', 3] ) ); - Result := nil; - end; -end; - -///////////////////////////////////////////////// - - -procedure TForm1.Button1Click(Sender: TObject); -var - DelphiPoint : TPyPoint; - p : PPyObject; -begin - // Here's how you can create/read Python vars from Delphi with - // Delphi/Python objects. - - // You should ask to the TPythonType to create an instance of its type - // because it will do some initialization. You can use CreateInstanceWith - // if you want to transmit some Python arguments. - // We receive a Python object pointer - p := PythonType1.CreateInstance; - // Then we cast the python object to the right delphi type - DelphiPoint := TPyPoint( PythonToDelphi(p) ); - // We do some changes on the delphi object - DelphiPoint.X:=10; - DelphiPoint.Y:=20; - // Add variable "myPoint" in the module "spam". - // So you'll access to the var in the module called spam with: - // import spam - // print spam.myPoint - PythonModule1.SetVar( 'myPoint', p ); - PythonEngine1.Py_DecRef(p); - { - Of course, if you want to retrieve a Python var from a module, - just use the PythonModule1.GetVar or PythonModule1.GetVarAsVariant - Example: - p := PythonModule1.GetVar('myPoint'); - if Assigned(p) then - begin - DelphiPoint := PythonToDelphi(p) as TPyPoint; - ... - Py_XDecRef(p); - end; - - end; } - // Excecute the script - PythonEngine1.ExecStrings( memo1.Lines ); - // Add the following line at the end of the script: - // print spam.myPoint - - // Note, that you must not free the delphi point yourself. - // Instead use the GetPythonEngine.Py_XDECREF(obj) method, - // because the object may be used by another Python object. -end; - -end. diff --git a/demos_delphi/Demo09/Project1.dpr b/demos_delphi/Demo09/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo09/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo09/Project1.dproj b/demos_delphi/Demo09/Project1.dproj deleted file mode 100644 index 9b7f97a..0000000 --- a/demos_delphi/Demo09/Project1.dproj +++ /dev/null @@ -1,100 +0,0 @@ - - - {A9EE3C80-927A-458F-83F8-5388BD57BAF3} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo09/Project1.res b/demos_delphi/Demo09/Project1.res deleted file mode 100644 index f928fd9..0000000 Binary files a/demos_delphi/Demo09/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo09/Unit1.dfm b/demos_delphi/Demo09/Unit1.dfm deleted file mode 100644 index 00fdb70..0000000 --- a/demos_delphi/Demo09/Unit1.dfm +++ /dev/null @@ -1,87 +0,0 @@ -object Form1: TForm1 - Left = 204 - Top = 124 - Width = 544 - Height = 375 - VertScrollBar.Range = 170 - ActiveControl = Button1 - Caption = 'Form1' - Color = clWindow - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = 11 - Font.Name = 'MS Sans Serif' - Font.Pitch = fpVariable - Font.Style = [] - OldCreateOrder = True - PixelsPerInch = 96 - TextHeight = 13 - object Splitter1: TSplitter - Left = 0 - Top = 129 - Width = 528 - Height = 3 - Cursor = crVSplit - Align = alTop - ExplicitWidth = 536 - end - object Memo1: TMemo - Left = 0 - Top = 132 - Width = 528 - Height = 164 - Align = alClient - Lines.Strings = ( - 'import sys' - 'print (sys.version_info)' - 'import demodll' - 'print (dir(demodll))' - 'print (demodll.add( 2, 2 ))') - TabOrder = 1 - end - object Panel1: TPanel - Left = 0 - Top = 296 - Width = 528 - Height = 41 - Align = alBottom - BevelOuter = bvNone - ParentBackground = False - TabOrder = 0 - object Button1: TButton - Left = 8 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Execute' - TabOrder = 0 - OnClick = Button1Click - end - end - object Memo2: TMemo - Left = 0 - Top = 0 - Width = 528 - Height = 129 - Align = alTop - Lines.Strings = ( - '') - TabOrder = 2 - end - object PythonEngine1: TPythonEngine - DllName = 'python32.dll' - APIVersion = 1013 - RegVersion = '3.2' - UseLastKnownVersion = False - IO = PythonGUIInputOutput1 - Left = 16 - Top = 16 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = True - RawOutput = False - Output = Memo2 - Left = 56 - Top = 16 - end -end diff --git a/demos_delphi/Demo09/Unit1.pas b/demos_delphi/Demo09/Unit1.pas deleted file mode 100644 index cdf7358..0000000 --- a/demos_delphi/Demo09/Unit1.pas +++ /dev/null @@ -1,40 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - PythonEngine1: TPythonEngine; - Panel1: TPanel; - Button1: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - private - public - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( memo1.Lines ); -end; - - -end. diff --git a/demos_delphi/Demo09/demodll.dpr b/demos_delphi/Demo09/demodll.dpr deleted file mode 100644 index 9cbcfd7..0000000 --- a/demos_delphi/Demo09/demodll.dpr +++ /dev/null @@ -1,25 +0,0 @@ -// JCL_DEBUG_EXPERT_GENERATEJDBG OFF -// JCL_DEBUG_EXPERT_INSERTJDBG OFF -// JCL_DEBUG_EXPERT_DELETEMAPFILE OFF -library demodll; - -{$I Definition.Inc} - -uses - SysUtils, - Classes, - module in 'module.pas'; - -exports - initdemodll, - PyInit_demodll; -{$IFDEF MSWINDOWS} -{$E pyd} -{$ENDIF} -{$IFDEF LINUX} -{$SONAME 'demodll'} - -{$ENDIF} - -begin -end. diff --git a/demos_delphi/Demo09/demodll.dproj b/demos_delphi/Demo09/demodll.dproj deleted file mode 100644 index 9912da8..0000000 --- a/demos_delphi/Demo09/demodll.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {FFF278A4-CBAE-4C3F-B542-8C88A2EFDA53} - demodll.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - demodll.pyd - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - true - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - - - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - - - - - Delphi.Personality.12 - VCLApplication - - - - demodll.dpr - - - False - True - False - C:\Delphi\progs32\Python\P4D\PythonForDelphi\Demos\Demo09\Project1.exe - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - - diff --git a/demos_delphi/Demo09/module.pas b/demos_delphi/Demo09/module.pas deleted file mode 100644 index db607c5..0000000 --- a/demos_delphi/Demo09/module.pas +++ /dev/null @@ -1,74 +0,0 @@ -unit module; - -interface -uses PythonEngine; - -// for python 2.x -procedure initdemodll; cdecl; -// for python 3.x -function PyInit_demodll : PPyObject; cdecl; - -var - gEngine : TPythonEngine; - gModule : TPythonModule; - -implementation - -function Add( Self, Args : PPyObject ) : PPyObject; far; cdecl; -var - a, b : Integer; -begin - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'ii:Add',@a, @b ) <> 0 then - begin - Result := PyInt_FromLong( a + b ); - end - else - Result := nil; - end; -end; - -procedure initdemodll; -begin - try - gEngine := TPythonEngine.Create(nil); - gEngine.AutoFinalize := False; - gEngine.LoadDll; - gModule := TPythonModule.Create(nil); - gModule.Engine := gEngine; - gModule.ModuleName := 'demodll'; - gModule.AddMethod( 'add', @Add, 'add(a,b) -> a+b' ); - gModule.Initialize; - except - end; -end; - -function PyInit_demodll : PPyObject; -begin - Result := nil; - try - gEngine := TPythonEngine.Create(nil); - gEngine.AutoFinalize := False; - gEngine.UseLastKnownVersion := False; - gEngine.RegVersion := '3.2'; //<-- Use the same version as the python 3.x your main program uses - gEngine.APIVersion := 1013; - gEngine.DllName := 'python32.dll'; - gEngine.LoadDll; - gModule := TPythonModule.Create(nil); - gModule.Engine := gEngine; - gModule.ModuleName := 'demodll'; - gModule.AddMethod( 'add', @Add, 'add(a,b) -> a+b' ); - gModule.Initialize; - Result := gModule.Module; - except - end; -end; - -initialization -finalization - gEngine.Free; - gModule.Free; -end. - - diff --git a/demos_delphi/Demo10/Demo10.dpr b/demos_delphi/Demo10/Demo10.dpr deleted file mode 100644 index 642afff..0000000 --- a/demos_delphi/Demo10/Demo10.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Demo10; - -uses - Forms, - fmMain in 'fmMain.pas' {Main}, - pyDBTables in 'pyDBTables.pas', - pyDB in 'pyDB.pas'; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TMain, Main); - Application.Run; -end. diff --git a/demos_delphi/Demo10/Demo10.dproj b/demos_delphi/Demo10/Demo10.dproj deleted file mode 100644 index 2c5dab1..0000000 --- a/demos_delphi/Demo10/Demo10.dproj +++ /dev/null @@ -1,107 +0,0 @@ - - - {1D701B96-D47C-4AD0-BE2E-830C95586BC9} - Demo10.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Demo10.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Main
-
- - - - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Demo10.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1032 - 1253 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - 12 - -
diff --git a/demos_delphi/Demo10/Demo10.res b/demos_delphi/Demo10/Demo10.res deleted file mode 100644 index cfdbb79..0000000 Binary files a/demos_delphi/Demo10/Demo10.res and /dev/null differ diff --git a/demos_delphi/Demo10/Example1.py b/demos_delphi/Demo10/Example1.py deleted file mode 100644 index da916cd..0000000 --- a/demos_delphi/Demo10/Example1.py +++ /dev/null @@ -1,66 +0,0 @@ -import DBTables -True = 1 -False = 0 - -# Create and open the table -T = DBTables.CreateTTable() -T.DatabaseName = "DBDemos" -T.TableName = "customer.db" -T.Active = True #or use T.Open() - -# Display columns -print "Columns: ", T.FieldNamesAsTuple() - -LastInvoiceDate = T.FieldByName("LastInvoiceDate") - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a list - A = [] - for i in xrange( T.FieldCount ): - A.append( T.Fields(i).Value ) - # Print the current record number and the list - print "Rec.", T.RecNo, ":", A - # Edit record - T.Edit() - T.FieldByName("TaxRate").Value = 2.5 - # Increments date by one day - D = LastInvoiceDate.Value - if D[2] < 28: - D2 = D[:2]+(D[2]+1,)+D[3:] # this is tuple arithmetic ! - else: - D2 = D[:2]+(1,)+D[3:] # this is tuple arithmetic ! - LastInvoiceDate.Value = D2 - T.Post() - # Get next record - T.Next() - -# Print some fields by their names -F = T.FieldByName("Company") -print F, F.FieldName, "=", F.Value - -# Use the TFields and print the list of companies -T.First() -while not T.EOF: - print F.AsString - T.Next() - -# Print the fields as a dictionary -D = T.FieldsAsDict() -print D -print D["Company"] - -T.Close() -T.TableName = "Dummy.db" -try: - T.Open() -except DBTables.DBError: - print "could not open table ", T.TableName - -#delete fields -del F -del LastInvoiceDate - -# delete the table -del T diff --git a/demos_delphi/Demo10/Example2.py b/demos_delphi/Demo10/Example2.py deleted file mode 100644 index 252b9d6..0000000 --- a/demos_delphi/Demo10/Example2.py +++ /dev/null @@ -1,87 +0,0 @@ -import DBTables -True = 1 -False = 0 - -# Get the TTable object associated to -# the delphi table displayed on right -# It is done when you click on Execute -T = DBTables.T - -# Display columns -print "Columns: " -for i in T.FieldNamesAsTuple(): - print " ", i - -T.CancelRange() -# For each record of the table -for i in T: - print "Rec.", T.RecNo, ":", i - -# Print some fields by their names -print T.FieldByName("Company") - -# check state -if not T.State in [DBTables.dsEdit, DBTables.dsInsert]: - print "Table is not edited" - -# access the table like an array -print T[10] # Row 11 -print T[10] [1] # second field of row 11 - -# locate a record -if T.Locate( "City;State", ["Largo","FL"], [] ): - print "Found rec:", T.RecNo -if T.Locate( "Company", "BLUE SPORTS", [DBTables.loCaseInsensitive] ): - print "Found rec:", T.RecNo -if T.Locate( "Company", "ISLAND", [DBTables.loCaseInsensitive, DBTables.loPartialKey] ): - print "Found rec:", T.RecNo - -# lookup a record -print T.Lookup( "City;State", ["Largo","FL"], "CustNo;Company" ) - -# define a range -print "-----------------------------------------------------------" -print "Indexes:", T.GetIndexNames() -T.IndexName = "ByCompany" -T.SetRange( ["Unisco"], ["Unisco"] ) -for i in T: - print "Rec.", T.RecNo, ":", i -T.CancelRange() - -print "-----------------------------------------------------------" -# Find a record -if T.FindKey( ['Unisco'] ): - print "Unisco found !" -else: - print "Could not find Unisco !" - -# Find the nearest record -T.FindNearest( ['Ocean'] ) -print "Find nearest Ocean :", T.FieldsAsTuple() - -# Print all doc strings of an instance's methods -def PrintDocOf( inst ): - print "--------------------- Type ", type(inst).__name__, "---------------------" - if type(inst).__doc__: - print type(inst).__doc__ - print "Methods:" - for i in inst.__members__: - doc = getattr(inst, i).__doc__ - if doc: - print " ", doc - print - print "Properties:" - for i in inst.__properties__: - print " ", i -print "-----------------------------------------------------------" -print "Documentation:" -print -print "Module DBTables:" -print DBTables.__doc__ -PrintDocOf(T) -print "-----------------------------------------------------------" -print "Property values of", T -for i in T.__members__: # or T.__properties__ - print i, "=", getattr(T, i) - - diff --git a/demos_delphi/Demo10/Example3.py b/demos_delphi/Demo10/Example3.py deleted file mode 100644 index 6705964..0000000 --- a/demos_delphi/Demo10/Example3.py +++ /dev/null @@ -1,38 +0,0 @@ -import DBTables -True = 1 -False = 0 - -# Get the TTable object created by Delphi -# and connected to a Delphi Datasource -# It is done when you click on Execute -T = DBTables.T -# Select and open a table -T.DatabaseName = "DBDemos" -T.TableName = "customer.db" -T.Open() - -# Display columns -print "Columns: " -for i in T.FieldNamesAsTuple(): - print " ", i - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a tuple - A = T.FieldsAsTuple() - # Print the current record number and the tuple - print "Rec.", T.RecNo, ":", A - # Get next record - T.Next() - -# Print some fields by their names -print T.FieldByName("Company") - -# check state -if not T.State in [DBTables.dsEdit, DBTables.dsInsert]: - print "Table is not edited" - -# clean up -del T -del DBTables.T diff --git a/demos_delphi/Demo10/Example4.py b/demos_delphi/Demo10/Example4.py deleted file mode 100644 index 00ca6f9..0000000 --- a/demos_delphi/Demo10/Example4.py +++ /dev/null @@ -1,39 +0,0 @@ -import DBTables -True = 1 -False = 0 - -# Create and open the table -T = DBTables.CreateTQuery() -T.DatabaseName = "DBDemos" -T.SQL = [ - "SELECT *", - " FROM customer.db" - ] -T.Open() - -# Display columns -print "Columns: ", T.FieldNamesAsTuple() - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a list - A = [] - for i in xrange( T.FieldCount ): - A.append( T.Fields(i).AsString ) - # Print the current record number and the list - print "Rec.", T.RecNo, ":", A - # Get next record - T.Next() - -# Print some fields by their names -print T.FieldByName("Company") - -# Print the fields as a dictionary -D = T.FieldsAsDict() -print D -print D["Company"] - -# delete the table -del T - diff --git a/demos_delphi/Demo10/Example5.py b/demos_delphi/Demo10/Example5.py deleted file mode 100644 index d35af83..0000000 --- a/demos_delphi/Demo10/Example5.py +++ /dev/null @@ -1,112 +0,0 @@ -import DBTables -import pyio - -True = 1 -False = 0 - -# Misc -def DisplayTypesStats(*args): - for i in apply(pyio.GetTypesStats, args): # Requested types - #for i in pyio.GetTypesStats('TTable', 'TField'): # Only the types TTable and TField - print "--------------------------------------------------------------------------------" - print "TYPE ", i[0] - print " Instance count :", i[1] - print " Create Hits :", i[2] - print " Delete Hits :", i[3] - print "--------------------------------------------------------------------------------" - -# Event functions - -def AfterScroll(Dataset): - print "---------> Scrolled to rec #"+str(Dataset.RecNo)+" <--------------" - -# Event methods - -# WARNING : -# --------- -# if you store the TTable in your C instance, and if you use events, -# you must be aware of the reference counting mechanism, and its -# failure on circular references: -# c = C(): c refcount = 1 -# c.T = CreateTTable(): c.T refcount = 1 -# c.T.OnAfterOpen = c.OnAfterOpen: c refcount = 2 -# del c: c refcount = 1 and you loose any reference on your c instance -# which still contains a TTable. -# so if you want to avoid the leaking, then you must clear the events -# before you delete the instance: -# c.T.OnAfterOpen = None: c refcount = 1 -# del c: c refcount = 0 -> c is deleted -# -# Try to use try..finally constructs, in order to avoid -# the leaking if an exception is raised before you can free the -# resources. -# -# Don't forget to close the TTable, if you want to get the Before/After -# close events, because when destroying a TTable, we first clear all -# events. But that's the case with the Delphi behaviour too. - -class C: - def __init__(Self): - # Create and open the table - Self.T = DBTables.CreateTTable() - Self.T.DatabaseName = "DBDemos" - Self.T.TableName = "customer.db" - Self.T.AfterScroll = AfterScroll # a global function - Self.T.BeforeOpen = Self.BeforeOpen # a method of the c instance of class C - Self.T.AfterOpen = Self.AfterOpen # a method of the c instance of class C - Self.T.BeforeClose = Self.BeforeClose # a method of the c instance of class C - Self.T.AfterClose = Self.AfterClose # a method of the c instance of class C - Self.T.OnFilterRecord = Self.OnFilterRecord # a method of the c instance of class C - Self.T.Filtered = True - Self.T.Open() - - def __del__(Self): - print "c instance deleted" - - def Free(Self): - Self.T.Close() - del Self.T - - def BeforeOpen(Self, Dataset): - Self.Name = Dataset.DatabaseName + ":" + Dataset.TableName - print "Before Open of ", Self.Name - - def AfterOpen(Self, Dataset): - print "After Open of ", Self.Name - - def BeforeClose(Self, Dataset): - print "Before close of ", Self.Name - - def AfterClose(Self, Dataset): - print "After Close of ", Self.Name - - def OnFilterRecord(Self, Dataset, Accept): - # Accept is var argument in Delphi, but in Python you can't - # change a function's argument. So we use a special object - # TVarArg which contains a single property : Value - Accept.Value = Dataset.FieldByName("Company").AsString > "E" - if not Accept.Value: - print "$$$$$ Rejected record:", Dataset.FieldsAsTuple() - -DisplayTypesStats() -c = C() -DisplayTypesStats() - -# don't use a "for i in c.T" expression with a filtered table, -# because the BDE will filter the whole table for each movement, -# in order to get the RecordCount. - -try: - c.T.First() - while not c.T.EOF: - print c.T.FieldsAsTuple() - c.T.Next() - -finally: - c.Free() - del c - -DisplayTypesStats() -#DisplayTypesStats('TField', 'TTable') - - diff --git a/demos_delphi/Demo10/Example6.py b/demos_delphi/Demo10/Example6.py deleted file mode 100644 index 44b3901..0000000 --- a/demos_delphi/Demo10/Example6.py +++ /dev/null @@ -1,90 +0,0 @@ -import DBTables -True = 1 -False = 0 - -# Here's how you can use a Proxy class -# in order to inherit from any Python object -# like our TTable or TQuery ! - -class Proxy: - def __init__(Self, Object): - Self.__object__ = Object - - def __getattr__(Self, Key): - return getattr(Self.__dict__['__object__'], Key) - - def __setattr__(Self, Key, Value): - if Key == "__object__": - Self.__dict__[Key] = Value - elif hasattr(Self.__object__, Key): - return setattr(Self.__object__, Key, Value) - else: - Self.__dict__[Key] = Value - - def __len__(Self): - return len(Self.__object__) - - def __getitem__(Self, Item): - return Self.__object__[Item] - -class TMyQuery(Proxy): - def __init__(Self): - Proxy.__init__(Self, DBTables.CreateTQuery() ) - -class TMySubQuery(TMyQuery): - def First(Self): - print "First requested on Query" - Self.__object__.First() - - -# Create and open the table -T = TMySubQuery() -T.DatabaseName = "DBDemos" -T.SQL = [ - "SELECT *", - " FROM customer.db" - ] -T.Open() - -# Display columns -print "Columns: ", T.FieldNamesAsTuple() - -# Test of method override -T.Last() -print "RecNo =", T.RecNo -T.First() -print "RecNo =", T.RecNo - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a list - A = [] - for i in xrange( T.FieldCount ): - A.append( T.Fields(i).AsString ) - # Print the current record number and the list - print "Rec.", T.RecNo, ":", A - # Get next record - T.Next() - -# Print some fields by their names -print T.FieldByName("Company") - -# Print the fields as a dictionary -D = T.FieldsAsDict() -print D["Company"] - -# Iterate our class -print T -for i in T: - print i - -print T - -# Define new instance vars -T.Test1 = 3 -print T.Test1, T.DatabaseName - -# delete the table -del T - diff --git a/demos_delphi/Demo10/fmMain.dfm b/demos_delphi/Demo10/fmMain.dfm deleted file mode 100644 index d01089b..0000000 Binary files a/demos_delphi/Demo10/fmMain.dfm and /dev/null differ diff --git a/demos_delphi/Demo10/fmMain.pas b/demos_delphi/Demo10/fmMain.pas deleted file mode 100644 index ad8930e..0000000 --- a/demos_delphi/Demo10/fmMain.pas +++ /dev/null @@ -1,312 +0,0 @@ -unit fmMain; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - ComCtrls, ExtCtrls, StdCtrls, PythonEngine, PythonGUIInputOutput, Db, - DBTables, Grids, DBGrids; - -type - TMain = class(TForm) - RichEdit1: TRichEdit; - PageControl1: TPageControl; - Splitter1: TSplitter; - TabSheet1: TTabSheet; - TabSheet2: TTabSheet; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo1: TMemo; - Button1: TButton; - typeTable: TPythonType; - modDB: TPythonModule; - Table1: TTable; - Memo2: TMemo; - Panel1: TPanel; - DBGrid1: TDBGrid; - Button2: TButton; - DataSource1: TDataSource; - TabSheet3: TTabSheet; - Table1CustNo: TFloatField; - Table1Company: TStringField; - Table1Addr1: TStringField; - Table1Addr2: TStringField; - Table1City: TStringField; - Table1State: TStringField; - Table1Zip: TStringField; - Table1Country: TStringField; - Table1Phone: TStringField; - Table1FAX: TStringField; - Table1TaxRate: TFloatField; - Table1Contact: TStringField; - Table1LastInvoiceDate: TDateTimeField; - Table1Demo: TStringField; - Label1: TLabel; - typeQuery: TPythonType; - TabSheet4: TTabSheet; - TabSheet5: TTabSheet; - Memo4: TMemo; - Splitter2: TSplitter; - Panel2: TPanel; - Button3: TButton; - Label2: TLabel; - Splitter3: TSplitter; - Memo3: TMemo; - Splitter4: TSplitter; - Panel3: TPanel; - Button4: TButton; - DBGrid2: TDBGrid; - DataSource2: TDataSource; - typeField: TPythonType; - TreeView1: TTreeView; - TabSheet6: TTabSheet; - Label3: TLabel; - Memo5: TMemo; - Panel4: TPanel; - Button5: TButton; - Splitter5: TSplitter; - typeVarArg: TPythonType; - TabSheet7: TTabSheet; - Label4: TLabel; - Memo6: TMemo; - Splitter6: TSplitter; - Panel5: TPanel; - Button6: TButton; - procedure Button1Click(Sender: TObject); - procedure typeTableInitialization(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Table1CalcFields(DataSet: TDataSet); - procedure typeQueryInitialization(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure typeFieldInitialization(Sender: TObject); - procedure modDBAfterInitialization(Sender: TObject); - procedure modDBInitialization(Sender: TObject); - procedure Button5Click(Sender: TObject); - procedure typeVarArgInitialization(Sender: TObject); - procedure Button6Click(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - -var - Main: TMain; - -implementation -uses pyDB, pyDBTables; -{$R *.DFM} - -procedure TMain.Button1Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo1.Lines ); -end; - -procedure TMain.typeTableInitialization(Sender: TObject); -begin - with Sender as TPythonType do - begin - PyObjectClass := TPyTable; - end; -end; - -procedure TMain.Button2Click(Sender: TObject); -var - tbl : TPyTable; - obj : PPyObject; -begin - // Instantiate a new Python object TPyTable - obj := typeTable.CreateInstance; - tbl := PythonToDelphi(obj) as TPyTable; - // Attach our Delphi table to the Python object - tbl.SetDataset( Table1, False ); - with GetPythonEngine do - begin - // Define a new variable "T" in the DB module - modDB.SetVar( 'T', obj ); - Py_XDecRef(obj); - // Excecute the script - ExecStrings( memo2.Lines ); - end; -end; - -procedure TMain.Table1CalcFields(DataSet: TDataSet); -begin - Dataset.FieldByName('Demo').AsString := Dataset.FieldByName('State').AsString + ' - ' + - Dataset.FieldByName('Zip').AsString; -end; - -procedure TMain.typeQueryInitialization(Sender: TObject); -begin - with Sender as TPythonType do - begin - PyObjectClass := TPyQuery; - end; -end; - -procedure TMain.Button3Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo4.Lines ); -end; - -procedure TMain.Button4Click(Sender: TObject); -var - tbl : TPyTable; - obj : PPyObject; -begin - // Instantiate a new Python object TPyTable - obj := typeTable.CreateInstance; - tbl := PythonToDelphi(obj) as TPyTable; - // connect the Datasource2 to the Python TTable - Datasource2.Dataset := tbl.Table; - with GetPythonEngine do - begin - // Define a new variable "T" in the DB module - modDB.SetVar( 'T', obj ); - Py_XDecRef(obj); - // Excecute the script - ExecStrings( memo3.Lines ); - end; -end; - -procedure TMain.FormCreate(Sender: TObject); -begin - Memo1.Lines.LoadFromFile( 'Example1.py' ); - Memo2.Lines.LoadFromFile( 'Example2.py' ); - Memo3.Lines.LoadFromFile( 'Example3.py' ); - Memo4.Lines.LoadFromFile( 'Example4.py' ); - Memo5.Lines.LoadFromFile( 'Example5.py' ); - Memo6.Lines.LoadFromFile( 'Example6.py' ); - PageControl1.ActivePage := TabSheet1; -end; - -procedure TMain.typeFieldInitialization(Sender: TObject); -begin - with Sender as TPythonType do - begin - PyObjectClass := TPyField; - end; - gFieldType := Sender as TPythonType; -end; - -procedure TMain.modDBAfterInitialization(Sender: TObject); -begin - with Sender as TPythonModule do - begin - // Values for type TTableType - SetVarFromVariant( 'ttDefault', 0 ); - SetVarFromVariant( 'ttParadox', 1 ); - SetVarFromVariant( 'ttDBase', 2 ); - SetVarFromVariant( 'ttASCII', 3 ); - // Values for type TDatasetState - SetVarFromVariant( 'dsInactive', 0 ); - SetVarFromVariant( 'dsBrowse', 1 ); - SetVarFromVariant( 'dsEdit', 2 ); - SetVarFromVariant( 'dsInsert', 3 ); - SetVarFromVariant( 'dsSetKey', 4 ); - SetVarFromVariant( 'dsCalcFields', 5 ); - SetVarFromVariant( 'dsFilter', 6 ); - SetVarFromVariant( 'dsNewValue', 7 ); - SetVarFromVariant( 'dsOldValue', 8 ); - SetVarFromVariant( 'dsCurValue', 9 ); - // Values for type TFieldType - SetVarFromVariant( 'ftUnknown', 0 ); - SetVarFromVariant( 'ftString', 1 ); - SetVarFromVariant( 'ftSmallint', 2 ); - SetVarFromVariant( 'ftInteger', 3 ); - SetVarFromVariant( 'ftWord', 4 ); - SetVarFromVariant( 'ftBoolean', 5 ); - SetVarFromVariant( 'ftFloat', 6 ); - SetVarFromVariant( 'ftCurrency', 7 ); - SetVarFromVariant( 'ftBCD', 8 ); - SetVarFromVariant( 'ftDate', 9 ); - SetVarFromVariant( 'ftTime', 10 ); - SetVarFromVariant( 'ftDateTime', 11 ); - SetVarFromVariant( 'ftBytes', 12 ); - SetVarFromVariant( 'ftVarBytes', 13 ); - SetVarFromVariant( 'ftAutoInc', 14 ); - SetVarFromVariant( 'ftBlob', 15 ); - SetVarFromVariant( 'ftMemo', 16 ); - SetVarFromVariant( 'ftGraphic', 17 ); - SetVarFromVariant( 'ftFmtMemo', 18 ); - SetVarFromVariant( 'ftParadoxOle', 19 ); - SetVarFromVariant( 'ftDBaseOle', 20 ); - SetVarFromVariant( 'ftTypedBinary', 21 ); - SetVarFromVariant( 'ftCursor', 22 ); - // Values for type TFieldKind - SetVarFromVariant( 'fkData', 0 ); - SetVarFromVariant( 'fkCalculated', 1 ); - SetVarFromVariant( 'fkLookup', 2 ); - SetVarFromVariant( 'fkInternalCalc', 3 ); - // Values for type TLocateOption - SetVarFromVariant( 'loCaseInsensitive', 0 ); - SetVarFromVariant( 'loPartialKey', 1 ); - // Values for type TLockType - SetVarFromVariant( 'ltReadLock', 0 ); - SetVarFromVariant( 'ltWriteLock', 1 ); - // Values for type TIndexOptions - SetVarFromVariant( 'ixPrimary', 0 ); - SetVarFromVariant( 'ixUnique', 1 ); - SetVarFromVariant( 'ixDescending', 2 ); - SetVarFromVariant( 'ixCaseInsensitive', 3 ); - SetVarFromVariant( 'ixExpression', 4 ); - // Values for type TDataAction - SetVarFromVariant( 'daFail', 0 ); - SetVarFromVariant( 'daAbort', 1 ); - SetVarFromVariant( 'daRetry', 2 ); - // Values for type TUpdateKind - SetVarFromVariant( 'ukModify', 0 ); - SetVarFromVariant( 'ukInsert', 1 ); - SetVarFromVariant( 'ukDelete', 2 ); - // Values for type TUpdateAction - SetVarFromVariant( 'uaFail', 0 ); - SetVarFromVariant( 'uaAbort', 1 ); - SetVarFromVariant( 'uaSkip', 2 ); - SetVarFromVariant( 'uaRetry', 3 ); - SetVarFromVariant( 'uaApplied', 4 ); - end; -end; - -procedure TMain.modDBInitialization(Sender: TObject); -begin - with Sender as TPythonModule do - begin - with DocString do - begin - Add( 'This module contains several Object Types that' ); - Add( 'will let you work with the Borland BDE and access' ); - Add( 'a database.' ); - Add( '' ); - Add( 'CreateTTable() -> creates a TTable instance' ); - Add( 'CreateTQuery() -> creates a TQuery instance' ); - end; - end; -end; - -procedure TMain.Button5Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo5.Lines ); -end; - -procedure TMain.typeVarArgInitialization(Sender: TObject); -begin - with Sender as TPythonType do - begin - PyObjectClass := TVarArg; - end; - gVarArgType := Sender as TPythonType; -end; - -procedure TMain.Button6Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo6.Lines ); -end; - -end. - diff --git a/demos_delphi/Demo10/pyDB.pas b/demos_delphi/Demo10/pyDB.pas deleted file mode 100644 index 498f0e4..0000000 --- a/demos_delphi/Demo10/pyDB.pas +++ /dev/null @@ -1,2913 +0,0 @@ -{$I Definition.Inc} - -unit pyDB; - -{------------------------------------------------------------------------------- - $Header: /P4D/PythonForDelphi/Components/Sources/VCL/pyDB.pas 1 03-04-09 19:25 Morgan $ - Copyright � MMM Inc. 2003 - All Rights Reserved. - ------------------------------------------------------------------------------ - Author: Morgan Martinet - - Description: - - ------------------------------------------------------------------------------ - $Log: /P4D/PythonForDelphi/Components/Sources/VCL/pyDB.pas $ - * - * 1 03-04-09 19:25 Morgan - * initial check-in - --------------------------------------------------------------------------------} - -interface -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - PythonEngine, StdCtrls, ExtCtrls, ComCtrls, DB; -type - TCallBackSplit = record - method: Pointer; - self: TObject; - end; - -{********************************************************************* - * DB module * - *********************************************************************} - TPythonDB = class(TPythonModule) - public - constructor Create( AOwner : TComponent ); override; - procedure Initialize; override; - end; - -{********************************************************************* - * Shared object * - *********************************************************************} - - TSharedObject = class - protected - FRefCount : Integer; - FData : TObject; - FOwner : Boolean; - - procedure DoDecRef; - procedure SetData( value : TObject ); - - public - constructor Create; - constructor CreateWith( value : TObject; isOwner : Boolean ); - destructor Destroy; override; - - procedure IncRef; - procedure DecRef; - procedure FreeData; - - property Data : TObject read FData write SetData; - property Owner : Boolean read FOwner write FOwner; - end; - - {********************************************************************* - * Interface of TCommon * - *********************************************************************} - - TCommon = class(TPyObject) - function GetProperties : PPyObject; - procedure AppendProperties( List : PPyObject ); virtual; - procedure AppendProp( List : PPyObject; const prop : String ); - function GetAttr(key : PAnsiChar) : PPyObject; override; - procedure RaiseDBError( E : Exception ); - function EventBelongsToObject( Event : TCallbackSplit ) : Boolean; - end; - - {********************************************************************* - * Interface of TField * - *********************************************************************} - // This is a Delphi class implementing a new Python type - // it must derive from TPyObject or one of its descendants. - // Then it must override some methods, like the constructors, - // the RegisterMethods and the type services' virtual methods. - TPyField = class(TCommon) - FSharedObject : TSharedObject; - FField : TField; - FOnChange : PPyObject; - FOnGetText : PPyObject; - FOnSetText : PPyObject; - FOnValidate : PPyObject; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - destructor Destroy; override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - function Repr : PPyObject; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyField - function CheckDataset : Boolean; - function CheckField : Boolean; - procedure AppendProperties( List : PPyObject ); override; - - // Interface methods - function DoClear( args : PPyObject ) : PPyObject; cdecl; - function DoFocusControl( args : PPyObject ) : PPyObject; cdecl; - function DoIsValidChar( args : PPyObject ) : PPyObject; cdecl; - function DoRefreshLookupList( args : PPyObject ) : PPyObject; cdecl; - - // Events - //////////////// - procedure OnChange( Sender : TField ); - procedure OnGetText( Sender: TField; var Text: String; DisplayText: Boolean ); - procedure OnSetText( Sender : TField; const Text: String ); - procedure OnValidate( Sender : TField ); - end; - - TPythonField = class( TPythonType) - public - constructor Create( AOwner : TComponent ); override; - end; - -{********************************************************************* - * Interface of TDataset * - *********************************************************************} - - - // This is a Delphi class implementing a new Python type - // it must derive from TPyObject or one of its descendants. - // Then it must override some methods, like the constructors, - // the RegisterMethods and the type services' virtual methods. - TPyDataset = class(TCommon) - FSharedObject : TSharedObject; - // Python functions or methods for each event - FAfterClose : PPyObject; - FAfterOpen : PPyObject; - FAfterScroll : PPyObject; - FBeforeClose : PPyObject; - FBeforeOpen : PPyObject; - FBeforeScroll : PPyObject; - FAfterCancel : PPyObject; - FAfterDelete : PPyObject; - FAfterEdit : PPyObject; - FAfterInsert : PPyObject; - FAfterPost : PPyObject; - FBeforeCancel : PPyObject; - FBeforeDelete : PPyObject; - FBeforeEdit : PPyObject; - FBeforeInsert : PPyObject; - FBeforePost : PPyObject; - FOnCalcFields : PPyObject; - FOnDeleteError : PPyObject; - FOnEditError : PPyObject; - FOnFilterRecord : PPyObject; - FOnNewRecord : PPyObject; - FOnPostError : PPyObject; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - destructor Destroy; override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - function Repr : PPyObject; override; - - // Sequence services - function SqLength : NativeInt; override; - function SqItem( idx : NativeInt ) : PPyObject; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyDataset - function CheckDataset : Boolean; - function Dataset : TDataset; - procedure SetDataset( val : TDataset; owner : Boolean ); - function FieldNamesAsTuple : PPyObject; - function FieldsAsTuple : PPyObject; - function FieldsAsDict : PPyObject; - function Locate( const keyFields : String; keyValues, options : PPyObject ) : PPyObject; - function Lookup( const keyFields : String; keyValues : PPyObject; const resultFields : String ) : PPyObject; - procedure AppendProperties( List : PPyObject ); override; - - // Interface methods - function DoOpen( args : PPyObject ) : PPyObject; cdecl; - function DoClose( args : PPyObject ) : PPyObject; cdecl; - function DoFirst( args : PPyObject ) : PPyObject; cdecl; - function DoLast( args : PPyObject ) : PPyObject; cdecl; - function DoNext( args : PPyObject ) : PPyObject; cdecl; - function DoPrior( args : PPyObject ) : PPyObject; cdecl; - function DoEdit( args : PPyObject ) : PPyObject; cdecl; - function DoInsert( args : PPyObject ) : PPyObject; cdecl; - function DoAppend( args : PPyObject ) : PPyObject; cdecl; - function DoPost( args : PPyObject ) : PPyObject; cdecl; - function DoCancel( args : PPyObject ) : PPyObject; cdecl; - function DoDisableControls( args : PPyObject ) : PPyObject; cdecl; - function DoEnableControls( args : PPyObject ) : PPyObject; cdecl; - function DoLocate( args : PPyObject ) : PPyObject; cdecl; - function DoLookup( args : PPyObject ) : PPyObject; cdecl; - function DoMoveBy( args : PPyObject ) : PPyObject; cdecl; - function DoRefresh( args : PPyObject ) : PPyObject; cdecl; - function DoFields( args : PPyObject ) : PPyObject; cdecl; - function DoFieldByName( args : PPyObject ) : PPyObject; cdecl; - function DoFindField( args : PPyObject ) : PPyObject; cdecl; - function DoFieldNamesAsTuple( args : PPyObject ) : PPyObject; cdecl; - function DoFieldsAsTuple( args : PPyObject ) : PPyObject; cdecl; - function DoFieldsAsDict( args : PPyObject ) : PPyObject; cdecl; - - // Events - //////////////// - procedure AfterClose( Dataset : TDataset ); - procedure AfterOpen( Dataset : TDataset ); - procedure AfterScroll( Dataset : TDataset ); - procedure BeforeClose( Dataset : TDataset ); - procedure BeforeOpen( Dataset : TDataset ); - procedure BeforeScroll( Dataset : TDataset ); - procedure AfterCancel ( Dataset : TDataset ); - procedure AfterDelete ( Dataset : TDataset ); - procedure AfterEdit ( Dataset : TDataset ); - procedure AfterInsert ( Dataset : TDataset ); - procedure AfterPost ( Dataset : TDataset ); - procedure BeforeCancel ( Dataset : TDataset ); - procedure BeforeDelete ( Dataset : TDataset ); - procedure BeforeEdit ( Dataset : TDataset ); - procedure BeforeInsert ( Dataset : TDataset ); - procedure BeforePost ( Dataset : TDataset ); - procedure OnCalcFields ( Dataset : TDataset ); - procedure OnDeleteError ( Dataset : TDataset; E: EDatabaseError; var Action: TDataAction ); - procedure OnEditError ( Dataset : TDataset; E: EDatabaseError; var Action: TDataAction ); - procedure OnFilterRecord ( Dataset : TDataset; var Accept : Boolean ); - procedure OnNewRecord ( Dataset : TDataset ); - procedure OnPostError ( Dataset : TDataset; E: EDatabaseError; var Action: TDataAction ); - end; - - TPythonDataset = class( TPythonType) - public - constructor Create( AOwner : TComponent ); override; - end; - - {********************************************************************* - * Interface of TVarArg * - *********************************************************************} - - TVarArg = class(TPyObject) - FValue : PPyObject; - - // Constructors & Destructors - constructor CreateWith( APythonType : TPythonType; args : PPyObject ); override; - destructor Destroy; override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - function Repr : PPyObject; override; - end; - - TPythonVarArg = class( TPythonType) - public - constructor Create( AOwner : TComponent ); override; - end; - - {********************************************************************* - * Global functions * - *********************************************************************} - procedure CreateComponents( AOwner : TComponent ); - procedure SetEvent( var EventSlot : PPyObject; Event : PPyObject; const EventName, ClassName : String ); - function SetDatasetEvent( EventSlot : PPyObject; dsEvent : TDataSetNotifyEvent ) : TDataSetNotifyEvent; - function SetDatasetErrorEvent( EventSlot : PPyObject; dsEvent : TDataSetErrorEvent ) : TDataSetErrorEvent; - procedure ClearEvent( var EventSlot : PPyObject ); - function ReturnEvent( Event : PPyObject ) : PPyObject; - procedure ExecuteEvent( Event : PPyObject; Args : array of Const ); - function NewDataset( aDataset : TDataset; IsOwner : Boolean ) : PPyObject; - - {******************************************************************** - * Global variables * - *********************************************************************} -var - gDatasetType : TPythonType; - gFieldType : TPythonType; - gVarArgType : TPythonType; - gDBModule : TPythonModule; - - -implementation - -{********************************************************************* - * DB module * - *********************************************************************} - -constructor TPythonDB.Create( AOwner : TComponent ); -begin - inherited; - ModuleName := 'DB'; - Name := 'modDB'; - with DocString do - begin - Add( 'This module contains several Object Types that' ); - Add( 'will let you work with the Borland BDE and access' ); - Add( 'a database.' ); - Add( '' ); - end; - with Errors.Add do - Name := 'DBError'; -end; - -procedure TPythonDB.Initialize; -begin - inherited; - // Values for type TTableType - SetVarFromVariant( 'ttDefault', 0 ); - SetVarFromVariant( 'ttParadox', 1 ); - SetVarFromVariant( 'ttDBase', 2 ); - SetVarFromVariant( 'ttASCII', 3 ); - // Values for type TDatasetState - SetVarFromVariant( 'dsInactive', 0 ); - SetVarFromVariant( 'dsBrowse', 1 ); - SetVarFromVariant( 'dsEdit', 2 ); - SetVarFromVariant( 'dsInsert', 3 ); - SetVarFromVariant( 'dsSetKey', 4 ); - SetVarFromVariant( 'dsCalcFields', 5 ); - SetVarFromVariant( 'dsFilter', 6 ); - SetVarFromVariant( 'dsNewValue', 7 ); - SetVarFromVariant( 'dsOldValue', 8 ); - SetVarFromVariant( 'dsCurValue', 9 ); - // Values for type TFieldType - SetVarFromVariant( 'ftUnknown', 0 ); - SetVarFromVariant( 'ftString', 1 ); - SetVarFromVariant( 'ftSmallint', 2 ); - SetVarFromVariant( 'ftInteger', 3 ); - SetVarFromVariant( 'ftWord', 4 ); - SetVarFromVariant( 'ftBoolean', 5 ); - SetVarFromVariant( 'ftFloat', 6 ); - SetVarFromVariant( 'ftCurrency', 7 ); - SetVarFromVariant( 'ftBCD', 8 ); - SetVarFromVariant( 'ftDate', 9 ); - SetVarFromVariant( 'ftTime', 10 ); - SetVarFromVariant( 'ftDateTime', 11 ); - SetVarFromVariant( 'ftBytes', 12 ); - SetVarFromVariant( 'ftVarBytes', 13 ); - SetVarFromVariant( 'ftAutoInc', 14 ); - SetVarFromVariant( 'ftBlob', 15 ); - SetVarFromVariant( 'ftMemo', 16 ); - SetVarFromVariant( 'ftGraphic', 17 ); - SetVarFromVariant( 'ftFmtMemo', 18 ); - SetVarFromVariant( 'ftParadoxOle', 19 ); - SetVarFromVariant( 'ftDBaseOle', 20 ); - SetVarFromVariant( 'ftTypedBinary', 21 ); - SetVarFromVariant( 'ftCursor', 22 ); - // Values for type TFieldKind - SetVarFromVariant( 'fkData', 0 ); - SetVarFromVariant( 'fkCalculated', 1 ); - SetVarFromVariant( 'fkLookup', 2 ); - SetVarFromVariant( 'fkInternalCalc', 3 ); - // Values for type TLocateOption - SetVarFromVariant( 'loCaseInsensitive', 0 ); - SetVarFromVariant( 'loPartialKey', 1 ); - // Values for type TDataAction - SetVarFromVariant( 'daFail', 0 ); - SetVarFromVariant( 'daAbort', 1 ); - SetVarFromVariant( 'daRetry', 2 ); - // Values for type TUpdateKind - SetVarFromVariant( 'ukModify', 0 ); - SetVarFromVariant( 'ukInsert', 1 ); - SetVarFromVariant( 'ukDelete', 2 ); -end; - -{********************************************************************* - * Shared object * - *********************************************************************} - -procedure TSharedObject.DoDecRef; -begin - if FRefCount > 0 then - Dec(FRefCount); - if (FRefCount = 0) then - FreeData; -end; - -procedure TSharedObject.SetData( value : TObject ); -begin - DoDecRef; - FRefCount := 0; - FData := value; - IncRef; -end; - -constructor TSharedObject.Create; -begin - inherited; - Owner := True; -end; - -constructor TSharedObject.CreateWith( value : TObject; isOwner : Boolean ); -begin - inherited; - Data := value; - Owner := isOwner; -end; - -destructor TSharedObject.Destroy; -begin - FreeData; - inherited; -end; - -procedure TSharedObject.IncRef; -begin - Inc(FRefCount); -end; - -procedure TSharedObject.DecRef; -begin - if not Assigned(Self) then - Exit; - DoDecRef; - if (FRefCount = 0) then - Free; -end; - -procedure TSharedObject.FreeData; -begin - if Owner and Assigned(FData) then - FData.Free; - FData := nil; -end; - -{********************************************************************* - * TCommon * - *********************************************************************} - -function TCommon.GetProperties : PPyObject; -begin - with GetPythonEngine do - begin - Result := PyList_New(0); - AppendProperties( Result ); - PyList_Sort(Result); - end; -end; - -procedure TCommon.AppendProperties( List : PPyObject ); -begin - // Override this method in the subclasses and add your - // properties to the list -end; - -procedure TCommon.AppendProp( List : PPyObject; const prop : String ); -var - obj : PPyObject; -begin - with GetPythonEngine do - begin - obj := PyString_FromString(PAnsiChar(AnsiString(prop))); - PyList_Append( List, obj ); - Py_XDecRef(obj); - end; -end; - -function TCommon.GetAttr(key : PAnsiChar) : PPyObject; -begin - try - if (CompareText( string(key), '__properties__' ) = 0) or - (CompareText( string(key), '__members__' ) = 0) then - Result := GetProperties - else - Result := inherited GetAttr(key); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; -end; - -procedure TCommon.RaiseDBError( E : Exception ); -begin - if gDBModule <> nil then - gDBModule.RaiseError( 'DBError', AnsiString(E.Message) ); -end; - -function TCommon.EventBelongsToObject( Event : TCallbackSplit ) : Boolean; -begin - Result := Event.Self = Self; -end; - -{********************************************************************* - * TField * - *********************************************************************} - -// We override the constructors - -constructor TPyField.Create( APythonType : TPythonType ); -begin - inherited; -end; - -// Don't call the Create constructor of TPyField, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyDataset.Create will be automatically be called. - -constructor TPyField.CreateWith( PythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine do - begin - //if PyArg_ParseTuple( args, 'ii:CreateTDataset',@x, @y ) = 0 then - // exit; - end; -end; - -destructor TPyField.Destroy; -begin - if Assigned(FField) then - begin - if EventBelongsToObject( TCallbackSplit(FField.OnChange) ) then - FField.OnChange := nil; - if EventBelongsToObject( TCallbackSplit(FField.OnGetText) ) then - FField.OnGetText := nil; - if EventBelongsToObject( TCallbackSplit(FField.OnSetText) ) then - FField.OnSetText := nil; - if EventBelongsToObject( TCallbackSplit(FField.OnValidate) ) then - FField.OnValidate := nil; - end; - FSharedObject.DecRef; - FSharedObject := nil; - FField := nil; - ClearEvent( FOnChange ); - ClearEvent( FOnGetText ); - ClearEvent( FOnSetText ); - ClearEvent( FOnValidate ); - inherited; -end; - -// Then we override the needed services - -function TPyField.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if not CheckField then - begin - Result := nil; - Exit; - end; - try - if CompareText( string(key), 'Alignment' ) = 0 then - Result := VariantAsPyObject( Integer(FField.Alignment) ) - else if CompareText( string(key), 'AsBoolean' ) = 0 then - Result := VariantAsPyObject( FField.AsBoolean ) - else if CompareText( string(key), 'AsDateTime' ) = 0 then - Result := VariantAsPyObject( FField.AsDateTime ) - else if CompareText( string(key), 'AsFloat' ) = 0 then - Result := VariantAsPyObject( FField.AsFloat ) - else if CompareText( string(key), 'AsInteger' ) = 0 then - Result := VariantAsPyObject( FField.AsInteger ) - else if CompareText( string(key), 'AsString' ) = 0 then - Result := VariantAsPyObject( FField.AsString ) - else if CompareText( string(key), 'CanModify' ) = 0 then - Result := VariantAsPyObject( FField.CanModify ) - else if CompareText( string(key), 'ConstraintErrorMessage' ) = 0 then - Result := VariantAsPyObject( FField.ConstraintErrorMessage ) - else if CompareText( string(key), 'CurValue' ) = 0 then - Result := VariantAsPyObject( FField.CurValue ) - else if CompareText( string(key), 'CustomConstraint' ) = 0 then - Result := VariantAsPyObject( FField.CustomConstraint ) - else if CompareText( string(key), 'DataSize' ) = 0 then - Result := VariantAsPyObject( FField.DataSize ) - else if CompareText( string(key), 'DataType' ) = 0 then - Result := VariantAsPyObject( FField.DataType ) - else if CompareText( string(key), 'DefaultExpression' ) = 0 then - Result := VariantAsPyObject( FField.DefaultExpression ) - else if CompareText( string(key), 'DisplayLabel' ) = 0 then - Result := VariantAsPyObject( FField.DisplayLabel ) - else if CompareText( string(key), 'DisplayName' ) = 0 then - Result := VariantAsPyObject( FField.DisplayName ) - else if CompareText( string(key), 'DisplayText' ) = 0 then - Result := VariantAsPyObject( FField.DisplayText ) - else if CompareText( string(key), 'DisplayWidth' ) = 0 then - Result := VariantAsPyObject( FField.DisplayWidth ) - else if CompareText( string(key), 'EditMask' ) = 0 then - Result := VariantAsPyObject( FField.EditMask ) - else if CompareText( string(key), 'FieldKind' ) = 0 then - Result := VariantAsPyObject( FField.FieldKind ) - else if CompareText( string(key), 'FieldName' ) = 0 then - Result := VariantAsPyObject( FField.FieldName) - else if CompareText( string(key), 'FieldNo' ) = 0 then - Result := VariantAsPyObject( FField.FieldNo ) - else if CompareText( string(key), 'HasConstraints' ) = 0 then - Result := VariantAsPyObject( FField.HasConstraints ) - else if CompareText( string(key), 'ImportedConstraint' ) = 0 then - Result := VariantAsPyObject( FField.ImportedConstraint ) - else if CompareText( string(key), 'Index' ) = 0 then - Result := VariantAsPyObject( FField.Index ) - else if CompareText( string(key), 'IsBlob' ) = 0 then - Result := VariantAsPyObject( FField.IsBlob) - else if CompareText( string(key), 'IsIndexField' ) = 0 then - Result := VariantAsPyObject( FField.IsIndexField ) - else if CompareText( string(key), 'IsNull' ) = 0 then - Result := VariantAsPyObject( FField.IsNull ) - else if CompareText( string(key), 'KeyFields' ) = 0 then - Result := VariantAsPyObject( FField.KeyFields ) - else if CompareText( string(key), 'Lookup' ) = 0 then - Result := VariantAsPyObject( FField.Lookup ) - else if CompareText( string(key), 'LookupCache' ) = 0 then - Result := VariantAsPyObject( FField.LookupCache ) - else if CompareText( string(key), 'LookupDataset' ) = 0 then - Result := ReturnNone - else if CompareText( string(key), 'LookupKeyFields' ) = 0 then - Result := VariantAsPyObject( FField.LookupKeyFields ) - else if CompareText( string(key), 'LookupList' ) = 0 then - Result := ReturnNone - else if CompareText( string(key), 'LookupResultField' ) = 0 then - Result := VariantAsPyObject( FField.LookupResultField ) - else if CompareText( string(key), 'NewValue' ) = 0 then - Result := VariantAsPyObject( FField.NewValue ) - else if CompareText( string(key), 'Offset' ) = 0 then - Result := VariantAsPyObject( FField.Offset ) - else if CompareText( string(key), 'OldValue' ) = 0 then - Result := VariantAsPyObject( FField.OldValue ) - else if CompareText( string(key), 'Origin' ) = 0 then - Result := VariantAsPyObject( FField.Origin ) - else if CompareText( string(key), 'ReadOnly' ) = 0 then - Result := VariantAsPyObject( FField.ReadOnly ) - else if CompareText( string(key), 'Required' ) = 0 then - Result := VariantAsPyObject( FField.Required ) - else if CompareText( string(key), 'Size' ) = 0 then - Result := VariantAsPyObject( FField.Size ) - else if CompareText( string(key), 'Text' ) = 0 then - Result := VariantAsPyObject( FField.Text ) - else if CompareText( string(key), 'ValidChars' ) = 0 then - Result := ReturnNone - else if CompareText( string(key), 'Value' ) = 0 then - Result := VariantAsPyObject( FField.Value ) - else if CompareText( string(key), 'Visible' ) = 0 then - Result := VariantAsPyObject( FField.Visible ) - else if CompareText( string(key), 'OnChange' ) = 0 then - Result := ReturnEvent( FOnChange ) - else if CompareText( string(key), 'OnGetText' ) = 0 then - Result := ReturnEvent( FOnGetText ) - else if CompareText( string(key), 'OnSetText' ) = 0 then - Result := ReturnEvent( FOnSetText ) - else if CompareText( string(key), 'OnValidate' ) = 0 then - Result := ReturnEvent( FOnValidate ) - else - Result := inherited GetAttr(key); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyField.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := -1; - with GetPythonEngine do - begin - if not CheckField then - Exit; - try - if CompareText( string(key), 'Alignment' ) = 0 then - begin - FField.Alignment := TAlignment(PyObjectAsVariant( value )); - Result := 0; - end - else if CompareText( string(key), 'AsBoolean' ) = 0 then - begin - FField.AsBoolean := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'AsDateTime' ) = 0 then - begin - FField.AsDateTime := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'AsFloat' ) = 0 then - begin - FField.AsFloat := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'AsInteger' ) = 0 then - begin - FField.AsInteger := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'AsString' ) = 0 then - begin - FField.AsString := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'CanModify' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'ConstraintErrorMessage' ) = 0 then - begin - FField.ConstraintErrorMessage := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'CurValue' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'CustomConstraint' ) = 0 then - begin - FField.CustomConstraint := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'DataSize' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'DataType' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'DefaultExpression' ) = 0 then - begin - FField.DefaultExpression := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'DisplayLabel' ) = 0 then - begin - FField.DisplayLabel := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'DisplayName' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'DisplayText' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'DisplayWidth' ) = 0 then - begin - FField.DisplayWidth := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'EditMask' ) = 0 then - begin - FField.EditMask := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'FieldKind' ) = 0 then - begin - FField.FieldKind := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'FieldName' ) = 0 then - begin - FField.FieldName:= PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'FieldNo' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'HasConstraints' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'ImportedConstraint' ) = 0 then - begin - FField.ImportedConstraint := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Index' ) = 0 then - begin - FField.Index := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'IsBlob' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'IsIndexField' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'IsNull' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'KeyFields' ) = 0 then - begin - FField.KeyFields := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Lookup' ) = 0 then - begin - FField.Lookup := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'LookupCache' ) = 0 then - begin - FField.LookupCache := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'LookupDataset' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'LookupKeyFields' ) = 0 then - begin - FField.LookupKeyFields := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'LookupList' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'LookupResultField' ) = 0 then - begin - FField.LookupResultField := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'NewValue' ) = 0 then - begin - FField.NewValue := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Offset' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'OldValue' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'Origin' ) = 0 then - begin - FField.Origin := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'ReadOnly' ) = 0 then - begin - FField.ReadOnly := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Required' ) = 0 then - begin - FField.Required := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Size' ) = 0 then - begin - FField.Size := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Text' ) = 0 then - begin - FField.Text := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'ValidChars' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'Value' ) = 0 then - begin - FField.Value := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Visible' ) = 0 then - begin - FField.Visible := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'OnChange' ) = 0 then - begin - SetEvent( FOnChange, Value, 'OnChange', 'TField' ); - if Assigned(FOnChange) then - FField.OnChange := OnChange - else - FField.OnChange := nil; - Result := 0; - end - else if CompareText( string(key), 'OnGetText' ) = 0 then - begin - SetEvent( FOnGetText, Value, 'OnGetText', 'TField' ); - if Assigned(FOnGetText) then - FField.OnGetText := OnGetText - else - FField.OnGetText := nil; - Result := 0; - end - else if CompareText( string(key), 'OnSetText' ) = 0 then - begin - SetEvent( FOnSetText, Value, 'OnSetText', 'TField' ); - if Assigned(FOnSetText) then - FField.OnSetText := OnSetText - else - FField.OnSetText := nil; - Result := 0; - end - else if CompareText( string(key), 'OnValidate' ) = 0 then - begin - SetEvent( FOnValidate, Value, 'OnValidate', 'TField' ); - if Assigned(FOnValidate) then - FField.OnValidate := OnValidate - else - FField.OnValidate := nil; - Result := 0; - end - else - Result := inherited SetAttr(key, value); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := -1; - end; - end; - end; -end; - -function TPyField.Repr : PPyObject; -begin - Result := inherited Repr; -end; - - -// Class methods -// We register the methods of our type - -class procedure TPyField.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - AddMethod( 'Clear', @TPyField.DoClear, 'TField.Clear() -> None' ); - AddMethod( 'FocusControl', @TPyField.DoFocusControl, 'TField.FocusControl() -> None' ); - AddMethod( 'IsValidChar', @TPyField.DoIsValidChar, 'TField.IsValidChar( InputChar : String ) -> True or False' ); - AddMethod( 'RefreshLookupList', @TPyField.DoRefreshLookupList, 'TField.RefreshLookupList() -> None' ); - end; -end; - -// Methods of TPyField -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -function TPyField.CheckDataset : Boolean; -begin - if (FSharedObject = nil) or (FSharedObject.Data = nil) then - begin - Result := False; - with GetPythonEngine do - PyErr_SetString (PyExc_RuntimeError^, 'No Dataset defined !'); - end - else - Result := True; -end; - -function TPyField.CheckField : Boolean; -begin - if not Assigned(FField) then - begin - Result := False; - with GetPythonEngine do - PyErr_SetString (PyExc_RuntimeError^, 'No field defined !'); - end - else - Result := True; - Result := Result and CheckDataset; -end; - -procedure TPyField.AppendProperties( List : PPyObject ); -begin - inherited; - AppendProp( List, 'Alignment'); - AppendProp( List, 'AsBoolean'); - AppendProp( List, 'AsDateTime'); - AppendProp( List, 'AsFloat'); - AppendProp( List, 'AsInteger'); - AppendProp( List, 'AsString'); - AppendProp( List, 'CanModify'); - AppendProp( List, 'ConstraintErrorMessage'); - AppendProp( List, 'CurValue'); - AppendProp( List, 'CustomConstraint'); - AppendProp( List, 'DataSize'); - AppendProp( List, 'DataType'); - AppendProp( List, 'DefaultExpression'); - AppendProp( List, 'DisplayLabel'); - AppendProp( List, 'DisplayName'); - AppendProp( List, 'DisplayText'); - AppendProp( List, 'DisplayWidth'); - AppendProp( List, 'EditMask'); - AppendProp( List, 'FieldKind'); - AppendProp( List, 'FieldName'); - AppendProp( List, 'FieldNo'); - AppendProp( List, 'HasConstraints'); - AppendProp( List, 'ImportedConstraint'); - AppendProp( List, 'Index'); - AppendProp( List, 'IsBlob'); - AppendProp( List, 'IsIndexField'); - AppendProp( List, 'IsNull'); - AppendProp( List, 'KeyFields'); - AppendProp( List, 'Lookup'); - AppendProp( List, 'LookupCache'); - AppendProp( List, 'LookupDataset'); - AppendProp( List, 'LookupKeyFields'); - AppendProp( List, 'LookupList'); - AppendProp( List, 'LookupResultField'); - AppendProp( List, 'NewValue'); - AppendProp( List, 'Offset'); - AppendProp( List, 'OldValue'); - AppendProp( List, 'Origin'); - AppendProp( List, 'ReadOnly'); - AppendProp( List, 'Required'); - AppendProp( List, 'Size'); - AppendProp( List, 'Text'); - AppendProp( List, 'ValidChars'); - AppendProp( List, 'Value'); - AppendProp( List, 'Visible'); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -function TPyField.DoClear( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - // Do action - if CheckField then - begin - FField.Clear; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyField.DoFocusControl( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - // Do action - if CheckField then - begin - FField.FocusControl; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyField.DoIsValidChar( args : PPyObject ) : PPyObject; -var - c : Char; - s : PAnsiChar; - str : String; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - // Do action - if CheckField then - begin - if PyArg_ParseTuple( args, 's:TField.IsValidChar',@s ) <> 0 then - begin - str := string(s); - if Length(str) > 0 then - c := str[1] - else - c := #0; - Result := VariantAsPyObject( FField.IsValidChar( c ) ) - end - else - Result := nil; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyField.DoRefreshLookupList( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - // Do action - if CheckField then - begin - FField.RefreshLookupList; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -// Events -//////////////// -procedure TPyField.OnChange( Sender : TField ); -begin - IncRef; - ExecuteEvent( FOnChange, [GetSelf] ); -end; - -procedure TPyField.OnGetText( Sender: TField; var Text: String; DisplayText: Boolean ); -var - v : PPyObject; -begin - IncRef; - with GetPythonEngine do - begin - v := gVarArgType.CreateInstanceWith( VariantAsPyObject( Text ) ); - Py_XIncRef(v); - try - ExecuteEvent( FOnGetText, [GetSelf, v, DisplayText] ); - with PythonToDelphi(v) as TVarArg do - Text := PyObjectAsVariant(FValue); - finally - Py_XDecRef(v); - end; - end; -end; - -procedure TPyField.OnSetText( Sender : TField; const Text: String ); -begin - IncRef; - ExecuteEvent( FOnSetText, [GetSelf, Text] ); -end; - -procedure TPyField.OnValidate( Sender : TField ); -begin - IncRef; - ExecuteEvent( FOnValidate, [GetSelf] ); -end; - -constructor TPythonField.Create( AOwner : TComponent ); -begin - inherited; - Name := 'typeField'; - TypeName := 'TField'; - Module := gDBModule; - TypeFlags := TypeFlags + [tpfBaseType]; - PyObjectClass := TPyField; - with DocString do - begin - Add( 'The TField type implements the Delphi TField VCL Object inside Python.' ); - Add( 'The properties and methods are the same as in Delphi.' ); - end; -end; - -{********************************************************************* - * Implementation of TDataset * - *********************************************************************} - -// We override the constructors - -constructor TPyDataset.Create( APythonType : TPythonType ); -begin - inherited; - FSharedObject := TSharedObject.Create; - FSharedObject.Owner := True; -end; - -// Don't call the Create constructor of TPyDataset, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyDataset.Create will be automatically be called. - -constructor TPyDataset.CreateWith( PythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine do - begin - //if PyArg_ParseTuple( args, 'ii:CreateTDataset',@x, @y ) = 0 then - // exit; - end; -end; - -destructor TPyDataset.Destroy; -begin - if EventBelongsToObject( TCallbackSplit(Dataset.AfterClose) ) then - Dataset.AfterClose := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.AfterOpen) ) then - Dataset.AfterOpen := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.AfterScroll) ) then - Dataset.AfterScroll := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforeClose) ) then - Dataset.BeforeClose := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforeOpen) ) then - Dataset.BeforeOpen := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforeScroll) ) then - Dataset.BeforeScroll := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.AfterCancel) ) then - Dataset.AfterCancel := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.AfterDelete) ) then - Dataset.AfterDelete := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.AfterEdit) ) then - Dataset.AfterEdit := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.AfterInsert) ) then - Dataset.AfterInsert := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.AfterPost) ) then - Dataset.AfterPost := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforeCancel) ) then - Dataset.BeforeCancel := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforeDelete) ) then - Dataset.BeforeDelete := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforeEdit) ) then - Dataset.BeforeEdit := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforeInsert) ) then - Dataset.BeforeInsert := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.BeforePost) ) then - Dataset.BeforePost := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.OnCalcFields) ) then - Dataset.OnCalcFields := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.OnDeleteError) ) then - Dataset.OnDeleteError := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.OnEditError) ) then - Dataset.OnEditError := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.OnFilterRecord) ) then - Dataset.OnFilterRecord := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.OnNewRecord) ) then - Dataset.OnNewRecord := nil; - if EventBelongsToObject( TCallbackSplit(Dataset.OnPostError) ) then - Dataset.OnPostError := nil; - FSharedObject.FreeData; - FSharedObject.DecRef; - FSharedObject := nil; - ClearEvent( FAfterClose ); - ClearEvent( FAfterOpen ); - ClearEvent( FAfterScroll ); - ClearEvent( FBeforeClose ); - ClearEvent( FBeforeOpen ); - ClearEvent( FBeforeScroll ); - ClearEvent( FAfterCancel ); - ClearEvent( FAfterDelete ); - ClearEvent( FAfterEdit ); - ClearEvent( FAfterInsert ); - ClearEvent( FAfterPost ); - ClearEvent( FBeforeCancel ); - ClearEvent( FBeforeDelete ); - ClearEvent( FBeforeEdit ); - ClearEvent( FBeforeInsert ); - ClearEvent( FBeforePost ); - ClearEvent( FOnCalcFields ); - ClearEvent( FOnDeleteError ); - ClearEvent( FOnEditError ); - ClearEvent( FOnFilterRecord ); - ClearEvent( FOnNewRecord ); - ClearEvent( FOnPostError ); - inherited; -end; - -// Then we override the needed services - -function TPyDataset.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if not CheckDataset then - begin - Result := nil; - Exit; - end; - try - if CompareText( string(key), 'Active' ) = 0 then - Result := VariantAsPyObject( Dataset.Active ) - else if CompareText( string(key), 'BOF' ) = 0 then - Result := VariantAsPyObject( Dataset.BOF ) - else if CompareText( string(key), 'CanModify' ) = 0 then - Result := VariantAsPyObject( Dataset.CanModify ) - else if CompareText( string(key), 'EOF' ) = 0 then - Result := VariantAsPyObject( Dataset.EOF ) - else if CompareText( string(key), 'FieldCount' ) = 0 then - Result := VariantAsPyObject( Dataset.FieldCount ) - else if CompareText( string(key), 'Filter' ) = 0 then - Result := VariantAsPyObject( Dataset.Filter ) - else if CompareText( string(key), 'Filtered' ) = 0 then - Result := VariantAsPyObject( Dataset.Filtered ) - else if CompareText( string(key), 'Found' ) = 0 then - Result := VariantAsPyObject( Dataset.Found ) - else if CompareText( string(key), 'Modified' ) = 0 then - Result := VariantAsPyObject( Dataset.Modified ) - else if CompareText( string(key), 'RecNo' ) = 0 then - Result := VariantAsPyObject( Dataset.RecNo ) - else if CompareText( string(key), 'RecordCount' ) = 0 then - Result := VariantAsPyObject( Dataset.RecordCount ) - else if CompareText( string(key), 'RecordSize' ) = 0 then - Result := VariantAsPyObject( Dataset.RecordSize ) - else if CompareText( string(key), 'State' ) = 0 then - Result := VariantAsPyObject( Integer(Dataset.State) ) - else if CompareText( string(key), 'AfterClose' ) = 0 then - Result := ReturnEvent( FAfterClose ) - else if CompareText( string(key), 'AfterOpen' ) = 0 then - Result := ReturnEvent( FAfterOpen ) - else if CompareText( string(key), 'AfterScroll' ) = 0 then - Result := ReturnEvent( FAfterScroll ) - else if CompareText( string(key), 'BeforeClose' ) = 0 then - Result := ReturnEvent( FBeforeClose ) - else if CompareText( string(key), 'BeforeOpen' ) = 0 then - Result := ReturnEvent( FBeforeOpen ) - else if CompareText( string(key), 'BeforeScroll' ) = 0 then - Result := ReturnEvent( FBeforeScroll ) - else if CompareText( string(key), 'AfterCancel' ) = 0 then - Result := ReturnEvent( FAfterCancel) - else if CompareText( string(key), 'AfterDelete' ) = 0 then - Result := ReturnEvent( FAfterDelete) - else if CompareText( string(key), 'AfterEdit' ) = 0 then - Result := ReturnEvent( FAfterEdit) - else if CompareText( string(key), 'AfterInsert' ) = 0 then - Result := ReturnEvent( FAfterInsert) - else if CompareText( string(key), 'AfterPost' ) = 0 then - Result := ReturnEvent( FAfterPost) - else if CompareText( string(key), 'BeforeCancel' ) = 0 then - Result := ReturnEvent( FBeforeCancel) - else if CompareText( string(key), 'BeforeDelete' ) = 0 then - Result := ReturnEvent( FBeforeDelete) - else if CompareText( string(key), 'BeforeEdit' ) = 0 then - Result := ReturnEvent( FBeforeEdit) - else if CompareText( string(key), 'BeforeInsert' ) = 0 then - Result := ReturnEvent( FBeforeInsert) - else if CompareText( string(key), 'BeforePost' ) = 0 then - Result := ReturnEvent( FBeforePost) - else if CompareText( string(key), 'OnCalcFields' ) = 0 then - Result := ReturnEvent( FOnCalcFields) - else if CompareText( string(key), 'OnDeleteError' ) = 0 then - Result := ReturnEvent( FOnDeleteError) - else if CompareText( string(key), 'OnEditError' ) = 0 then - Result := ReturnEvent( FOnEditError) - else if CompareText( string(key), 'OnFilterRecord' ) = 0 then - Result := ReturnEvent( FOnFilterRecord) - else if CompareText( string(key), 'OnNewRecord' ) = 0 then - Result := ReturnEvent( FOnNewRecord) - else if CompareText( string(key), 'OnPostError' ) = 0 then - Result := ReturnEvent( FOnPostError) - else - Result := inherited GetAttr(key); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := -1; - with GetPythonEngine do - begin - if not CheckDataset then - Exit; - try - if CompareText( string(key), 'Active' ) = 0 then - begin - Dataset.Active := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'BOF' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'CanModify' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'EOF' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'FieldCount' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'Filter' ) = 0 then - begin - Dataset.Filter := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Filtered' ) = 0 then - begin - Dataset.Filtered := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Found' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'Modified' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'RecNo' ) = 0 then - begin - Dataset.RecNo := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'RecordCount' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'RecordSize' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'State' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'AfterClose' ) = 0 then - begin - SetEvent( FAfterClose, Value, 'AfterClose', 'TDataset' ); - Dataset.AfterClose := SetDatasetEvent( FAfterClose, AfterClose ); - Result := 0; - end - else if CompareText( string(key), 'AfterOpen' ) = 0 then - begin - SetEvent( FAfterOpen, Value, 'AfterOpen', 'TDataset' ); - Dataset.AfterOpen := SetDatasetEvent( FAfterOpen, AfterOpen ); - Result := 0; - end - else if CompareText( string(key), 'AfterScroll' ) = 0 then - begin - SetEvent( FAfterScroll, Value, 'AfterScroll', 'TDataset' ); - Dataset.AfterScroll := SetDatasetEvent( FAfterScroll, AfterScroll ); - Result := 0; - end - else if CompareText( string(key), 'BeforeClose' ) = 0 then - begin - SetEvent( FBeforeClose, Value, 'BeforeClose', 'TDataset' ); - Dataset.BeforeClose := SetDatasetEvent( FBeforeClose, BeforeClose ); - Result := 0; - end - else if CompareText( string(key), 'BeforeOpen' ) = 0 then - begin - SetEvent( FBeforeOpen, Value, 'BeforeOpen', 'TDataset' ); - Dataset.BeforeOpen := SetDatasetEvent( FBeforeOpen, BeforeOpen ); - Result := 0; - end - else if CompareText( string(key), 'BeforeScroll' ) = 0 then - begin - SetEvent( FBeforeScroll, Value, 'BeforeScroll', 'TDataset' ); - Dataset.BeforeScroll := SetDatasetEvent( FBeforeScroll, BeforeScroll ); - Result := 0; - end - else if CompareText( string(key), 'AfterCancel' ) = 0 then - begin - SetEvent( FAfterCancel, Value, 'AfterCancel', 'TDataset' ); - Dataset.AfterCancel := SetDatasetEvent( FAfterCancel, AfterCancel); - Result := 0; - end - else if CompareText( string(key), 'AfterDelete' ) = 0 then - begin - SetEvent( FAfterDelete, Value, 'AfterDelete', 'TDataset' ); - Dataset.AfterDelete := SetDatasetEvent( FAfterDelete, AfterDelete); - Result := 0; - end - else if CompareText( string(key), 'AfterEdit' ) = 0 then - begin - SetEvent( FAfterEdit, Value, 'AfterEdit', 'TDataset' ); - Dataset.AfterEdit := SetDatasetEvent( FAfterEdit, AfterEdit); - Result := 0; - end - else if CompareText( string(key), 'AfterInsert' ) = 0 then - begin - SetEvent( FAfterInsert, Value, 'AfterInsert', 'TDataset' ); - Dataset.AfterInsert := SetDatasetEvent( FAfterInsert, AfterInsert); - Result := 0; - end - else if CompareText( string(key), 'AfterPost' ) = 0 then - begin - SetEvent( FAfterPost, Value, 'AfterPost', 'TDataset' ); - Dataset.AfterPost := SetDatasetEvent( FAfterPost, AfterPost); - Result := 0; - end - else if CompareText( string(key), 'BeforeCancel' ) = 0 then - begin - SetEvent( FBeforeCancel, Value, 'BeforeCancel', 'TDataset' ); - Dataset.BeforeCancel := SetDatasetEvent( FBeforeCancel, BeforeCancel); - Result := 0; - end - else if CompareText( string(key), 'BeforeDelete' ) = 0 then - begin - SetEvent( FBeforeDelete, Value, 'BeforeDelete', 'TDataset' ); - Dataset.BeforeDelete := SetDatasetEvent( FBeforeDelete, BeforeDelete); - Result := 0; - end - else if CompareText( string(key), 'BeforeEdit' ) = 0 then - begin - SetEvent( FBeforeEdit, Value, 'BeforeEdit', 'TDataset' ); - Dataset.BeforeEdit := SetDatasetEvent( FBeforeEdit, BeforeEdit); - Result := 0; - end - else if CompareText( string(key), 'BeforeInsert' ) = 0 then - begin - SetEvent( FBeforeInsert, Value, 'BeforeInsert', 'TDataset' ); - Dataset.BeforeInsert := SetDatasetEvent( FBeforeInsert, BeforeInsert); - Result := 0; - end - else if CompareText( string(key), 'BeforePost' ) = 0 then - begin - SetEvent( FBeforePost, Value, 'BeforePost', 'TDataset' ); - Dataset.BeforePost := SetDatasetEvent( FBeforePost, BeforePost); - Result := 0; - end - else if CompareText( string(key), 'OnCalcFields' ) = 0 then - begin - SetEvent( FOnCalcFields, Value, 'OnCalcFields', 'TDataset' ); - Dataset.OnCalcFields := SetDatasetEvent( FOnCalcFields, OnCalcFields); - Result := 0; - end - else if CompareText( string(key), 'OnDeleteError' ) = 0 then - begin - SetEvent( FOnDeleteError, Value, 'OnDeleteError', 'TDataset' ); - Dataset.OnDeleteError := SetDatasetErrorEvent( FOnDeleteError, OnDeleteError ); - Result := 0; - end - else if CompareText( string(key), 'OnEditError' ) = 0 then - begin - SetEvent( FOnEditError, Value, 'OnEditError', 'TDataset' ); - Dataset.OnEditError := SetDatasetErrorEvent( FOnEditError, OnEditError ); - Result := 0; - end - else if CompareText( string(key), 'OnFilterRecord' ) = 0 then - begin - SetEvent( FOnFilterRecord, Value, 'OnFilterRecord', 'TDataset' ); - if Assigned(FOnFilterRecord) then - Dataset.OnFilterRecord := OnFilterRecord - else - Dataset.OnFilterRecord := nil; - Result := 0; - end - else if CompareText( string(key), 'OnNewRecord' ) = 0 then - begin - SetEvent( FOnNewRecord, Value, 'OnNewRecord', 'TDataset' ); - Dataset.OnNewRecord := SetDatasetEvent( FOnNewRecord, OnNewRecord); - Result := 0; - end - else if CompareText( string(key), 'OnPostError' ) = 0 then - begin - SetEvent( FOnPostError, Value, 'OnPostError', 'TDataset' ); - Dataset.OnPostError := SetDatasetErrorEvent( FOnPostError, OnPostError ); - Result := 0; - end - else - Result := inherited SetAttr(key, value); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := -1; - end; - end; - end; -end; - -function TPyDataset.Repr : PPyObject; -begin - Result := inherited Repr; -end; - -// Sequence services - -function TPyDataset.SqLength : NativeInt; -begin - if CheckDataset then - Result := Dataset.RecordCount - else - Result := -1; -end; - -function TPyDataset.SqItem( idx : NativeInt ) : PPyObject; -begin - if CheckDataset then - begin - // Check if empty - if Dataset.RecordCount = 0 then - begin - Result := nil; - with GetPythonEngine do - PyErr_SetString (PyExc_IndexError^, PAnsiChar('Table is empty')); - Exit; - end; - // Check range - if (idx < 0) or (idx+1 > Dataset.RecordCount) then - begin - Result := nil; - with GetPythonEngine do - PyErr_SetString (PyExc_IndexError^, PAnsiChar(AnsiString(Format('Index %d out of range (%d,%d)',[idx, 0, Dataset.RecordCount-1])))); - Exit; - end; - try - Dataset.RecNo := idx+1; - Result := FieldsAsTuple - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end - else - Result := nil; -end; - -// Class methods -// We register the methods of our type - -class procedure TPyDataset.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - AddMethod( 'Open', @TPyDataset.DoOpen, 'TDataset.Open() -> None' ); - AddMethod( 'Close', @TPyDataset.DoClose, 'TDataset.Close() -> None' ); - AddMethod( 'First', @TPyDataset.DoFirst, 'TDataset.First() -> None' ); - AddMethod( 'Last', @TPyDataset.DoLast, 'TDataset.Last() -> None' ); - AddMethod( 'Next', @TPyDataset.DoNext, 'TDataset.Next() -> None' ); - AddMethod( 'Prior', @TPyDataset.DoPrior, 'TDataset.Prior() -> None' ); - AddMethod( 'Edit', @TPyDataset.DoEdit, 'TDataset.Edit() -> None' ); - AddMethod( 'Insert', @TPyDataset.DoInsert, 'TDataset.Insert() -> None' ); - AddMethod( 'Append', @TPyDataset.DoAppend, 'TDataset.Append() -> None' ); - AddMethod( 'Post', @TPyDataset.DoPost, 'TDataset.Post() -> None' ); - AddMethod( 'Cancel', @TPyDataset.DoCancel, 'TDataset.Cancel() -> None' ); - AddMethod( 'DisableControls', @TPyDataset.DoDisableControls, 'TDataset.DisableControls() -> None' ); - AddMethod( 'EnableControls', @TPyDataset.DoEnableControls, 'TDataset.EnableControls() -> None' ); - AddMethod( 'Locate', @TPyDataset.DoLocate, 'TDataset.Locate( KeyFields : String, KeyValues : Object or Sequence, Options : TLocateOptions ) -> True or False' ); - AddMethod( 'Lookup', @TPyDataset.DoLookup, 'TDataset.Lookup( KeyFields : String, KeyValues : Object or Sequence, ResultFields : String ) -> a list containing all Result fields' ); - AddMethod( 'MoveBy', @TPyDataset.DoMoveBy, 'TDataset.MoveBy( Distance : Integer ) : Integer' ); - AddMethod( 'Refresh',@TPyDataset.DoRefresh,'TDataset.Refresh() -> None' ); - AddMethod( 'Fields', @TPyDataset.DoFields, 'TDataset.Fields( index : Integer ) -> TField' ); - AddMethod( 'FieldByName', @TPyDataset.DoFieldByName, 'TDataset.FieldByName( FieldName : String ) -> TField' ); - AddMethod( 'FindField', @TPyDataset.DoFindField, 'TDataset.FindField( FieldName : String ) -> TField' ); - AddMethod( 'FieldNamesAsTuple', @TPyDataset.DoFieldNamesAsTuple, 'TDataset.FieldNamesAsTuple() -> a tuple containing all field names' ); - AddMethod( 'FieldsAsTuple', @TPyDataset.DoFieldsAsTuple, 'TDataset.FieldsAsTuple() -> a tuple containing all TFields' ); - AddMethod( 'FieldsAsDict', @TPyDataset.DoFieldsAsDict, 'TDataset.FieldsAsDict() -> a dictionary containing all TFields, with FieldName as Key, and TField as Value' ); - end; -end; - -// Methods of TPyDataset -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -function TPyDataset.CheckDataset : Boolean; -begin - if (FSharedObject = nil) or (FSharedObject.Data = nil) then - begin - Result := False; - with GetPythonEngine do - PyErr_SetString (PyExc_RuntimeError^, 'No Dataset defined !'); - end - else - Result := True; -end; - -function TPyDataset.Dataset : TDataset; -begin - Result := FSharedObject.Data as TDataset; -end; - -procedure TPyDataset.SetDataset( val : TDataset; owner : Boolean ); -begin - FSharedObject.Data := val; - FSharedObject.Owner := owner; -end; - -function TPyDataset.FieldNamesAsTuple : PPyObject; -var - i : Integer; -begin - with GetPythonEngine do - begin - Result := PyTuple_New(Dataset.FieldCount); - for i := 0 to Dataset.FieldCount - 1 do - with Dataset.Fields[i] do - PyTuple_SetItem( Result, i, VariantAsPyObject(Variant(FieldName)) ); - end; -end; - -function TPyDataset.FieldsAsTuple : PPyObject; -var - i : Integer; -begin - with GetPythonEngine do - begin - Result := PyTuple_New(Dataset.FieldCount); - for i := 0 to Dataset.FieldCount - 1 do - with Dataset.Fields[i] do - PyTuple_SetItem( Result, i, VariantAsPyObject( AsVariant ) ); - end; -end; - -function TPyDataset.FieldsAsDict : PPyObject; -var - i : Integer; - obj : PPyObject; - _fieldName : PPyObject; -begin - with GetPythonEngine do - begin - Result := PyDict_New; - for i := 0 to Dataset.FieldCount - 1 do - with Dataset.Fields[i] do - begin - obj := VariantAsPyObject( AsVariant ); - _fieldName := VariantAsPyObject(Variant(FieldName)); - PyDict_SetItem( Result, _fieldName, obj ); - Py_XDecRef(obj); - Py_XDecRef(_fieldName); - end; - end; -end; - -function TPyDataset.Locate( const keyFields : String; keyValues, options : PPyObject ) : PPyObject; -var - rslt : Boolean; - vvalues : Variant; - opt : TLocateOptions; -begin - Result := nil; - with GetPythonEngine do - begin - if PySequence_Check(options) = 0 then - begin - PyErr_SetString (PyExc_AttributeError^, 'Third argument of Locate must be a sequence.'); - Exit; - end; - // Prepare the locate options - ListToSet( options, @opt, sizeof(opt) ); - // Create a variant containing the key values - vvalues := PyObjectAsVariant( keyValues ); - // Execute the locate - rslt := Dataset.Locate( keyFields, vvalues, opt ); - // Return its result - Result := VariantAsPyObject( rslt ); - end; -end; - -function TPyDataset.Lookup( const keyFields : String; keyValues : PPyObject; const resultFields : String ) : PPyObject; -var - rslt : Variant; - vvalues : Variant; -begin - with GetPythonEngine do - begin - // Create a variant containing the key values - vvalues := PyObjectAsVariant( keyValues ); - // Execute the lookup - rslt := Dataset.Lookup( keyFields, vvalues, resultFields ); - // Return its result - Result := VariantAsPyObject( rslt ); - end; -end; - -procedure TPyDataset.AppendProperties( List : PPyObject ); -begin - inherited; - AppendProp( List, 'Active'); - AppendProp( List, 'BOF'); - AppendProp( List, 'CanModify'); - AppendProp( List, 'EOF'); - AppendProp( List, 'FieldCount'); - AppendProp( List, 'Filter'); - AppendProp( List, 'Filtered'); - AppendProp( List, 'Found'); - AppendProp( List, 'Modified'); - AppendProp( List, 'RecNo'); - AppendProp( List, 'RecordCount'); - AppendProp( List, 'RecordSize'); - AppendProp( List, 'State'); - AppendProp( List, 'AfterClose'); - AppendProp( List, 'AfterOpen'); - AppendProp( List, 'AfterScroll'); - AppendProp( List, 'BeforeClose'); - AppendProp( List, 'BeforeOpen'); - AppendProp( List, 'BeforeScroll'); - AppendProp( List, 'AfterCancel'); - AppendProp( List, 'AfterDelete'); - AppendProp( List, 'AfterEdit'); - AppendProp( List, 'AfterInsert'); - AppendProp( List, 'AfterPost'); - AppendProp( List, 'BeforeCancel'); - AppendProp( List, 'BeforeDelete'); - AppendProp( List, 'BeforeEdit'); - AppendProp( List, 'BeforeInsert'); - AppendProp( List, 'BeforePost'); - AppendProp( List, 'OnCalcFields'); - AppendProp( List, 'OnDeleteError'); - AppendProp( List, 'OnEditError'); - AppendProp( List, 'OnFilterRecord'); - AppendProp( List, 'OnNewRecord'); - AppendProp( List, 'OnPostError'); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -function TPyDataset.DoOpen( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Open; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoClose( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Close; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoFirst( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.First; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoLast( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Last; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoNext( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Next; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoPrior( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Prior; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoEdit( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Edit; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoInsert( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Insert; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoAppend( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Append; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoPost( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Post; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoCancel( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Cancel; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoDisableControls( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.DisableControls; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoEnableControls( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.EnableControls; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoLocate( args : PPyObject ) : PPyObject; -var - keyFields : PAnsiChar; - keyValues, options : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'sOO:TDataset.Locate',@keyFields, @keyValues, @options ) <> 0) then - begin - // Do action - Result := Locate( String(keyFields), keyValues, options ); - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoLookup( args : PPyObject ) : PPyObject; -var - keyFields, resultFields : PAnsiChar; - keyValues : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'sOs:TDataset.Lookup',@keyFields, @keyValues, @resultFields ) <> 0) then - begin - // Do action - Result := Lookup( String(keyFields), keyValues, String(resultFields) ); - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; -function TPyDataset.DoMoveBy( args : PPyObject ) : PPyObject; -var - dist, rslt : Integer; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'i:TDataset.MoveBy',@dist ) <> 0) then - begin - // Do action - rslt := Dataset.MoveBy( dist ); - // Finally, we return nothing - Result := PyInt_FromLong(rslt); - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoRefresh( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Dataset.Refresh; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoFields( args : PPyObject ) : PPyObject; -var - idx : Integer; - F : TPyField; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - // first we extract the arguments - if CheckDataset and (PyArg_ParseTuple( args, 'i:TDataset.Fields',@idx ) <> 0) then - begin - if (idx >= 0) and (idx < Dataset.FieldCount) then - begin - Result := gFieldType.CreateInstance; - F := PythonToDelphi(Result) as TPyField; - F.FField := Dataset.Fields[idx]; - F.FSharedObject := FSharedObject; - F.FSharedObject.IncRef; - end - else - begin - Result := nil; - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(AnsiString(Format('Value out of range : %d', [idx])))); - end; - end - else // the arguments were not right - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoFieldByName( args : PPyObject ) : PPyObject; -var - s : PAnsiChar; - fld : TField; - F : TPyField; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - // first we extract the arguments - if CheckDataset and (PyArg_ParseTuple( args, 's:TDataset.FieldByName',@s ) <> 0) then - begin - fld := Dataset.FindField(String(s)); - if Assigned(fld) then - begin - Result := gFieldType.CreateInstance; - F := PythonToDelphi(Result) as TPyField; - F.FField := fld; - F.FSharedObject := FSharedObject; - F.FSharedObject.IncRef; - end - else - begin - Result := nil; - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(AnsiString(Format('Unknown field "%s"', [String(s)])))); - end; - end - else // the arguments were not right - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoFindField( args : PPyObject ) : PPyObject; -var - s : PAnsiChar; - fld : TField; - F : TPyField; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - // first we extract the arguments - if CheckDataset and (PyArg_ParseTuple( args, 's:TDataset.FindField',@s ) <> 0) then - begin - fld := Dataset.FindField(String(s)); - if Assigned(fld) then - begin - Result := gFieldType.CreateInstance; - F := PythonToDelphi(Result) as TPyField; - F.FField := fld; - F.FSharedObject := FSharedObject; - F.FSharedObject.IncRef; - end - else - begin - Result := ReturnNone; - end; - end - else // the arguments were not right - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoFieldNamesAsTuple( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Result := FieldNamesAsTuple; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoFieldsAsTuple( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Result := FieldsAsTuple; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDataset.DoFieldsAsDict( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Result := FieldsAsDict; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -// Events -//////////////// - -procedure TPyDataset.AfterClose( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterClose, [GetSelf] ); -end; - -procedure TPyDataset.AfterOpen( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterOpen, [GetSelf] ); -end; - -procedure TPyDataset.AfterScroll( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterScroll, [GetSelf] ); -end; - -procedure TPyDataset.BeforeClose( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforeClose, [GetSelf] ); -end; - -procedure TPyDataset.BeforeOpen( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforeOpen, [GetSelf] ); -end; - -procedure TPyDataset.BeforeScroll( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforeScroll, [GetSelf] ); -end; - -procedure TPyDataset.AfterCancel( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterCancel, [GetSelf] ); -end; - -procedure TPyDataset.AfterDelete( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterDelete, [GetSelf] ); -end; - -procedure TPyDataset.AfterEdit( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterEdit, [GetSelf] ); -end; - -procedure TPyDataset.AfterInsert( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterInsert, [GetSelf] ); -end; - -procedure TPyDataset.AfterPost( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FAfterPost, [GetSelf] ); -end; - -procedure TPyDataset.BeforeCancel( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforeCancel, [GetSelf] ); -end; - -procedure TPyDataset.BeforeDelete( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforeDelete, [GetSelf] ); -end; - -procedure TPyDataset.BeforeEdit( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforeEdit, [GetSelf] ); -end; - -procedure TPyDataset.BeforeInsert( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforeInsert, [GetSelf] ); -end; - -procedure TPyDataset.BeforePost( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FBeforePost, [GetSelf] ); -end; - -procedure TPyDataset.OnCalcFields( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FOnCalcFields, [GetSelf] ); -end; - -procedure TPyDataset.OnDeleteError( Dataset : TDataset; E: EDatabaseError; var Action: TDataAction ); -var - v : PPyObject; -begin - IncRef; - with GetPythonEngine do - begin - v := gVarArgType.CreateInstanceWith( VariantAsPyObject( NativeInt(Action) ) ); - Py_XIncRef(v); - try - ExecuteEvent( FOnDeleteError, [GetSelf, ArrayToPyTuple([E.ClassName, E.Message]), v] ); - with PythonToDelphi(v) as TVarArg do - Action := TDataAction(NativeInt(PyObjectAsVariant(FValue))); - finally - Py_XDecRef(v); - end; - end; -end; - -procedure TPyDataset.OnEditError( Dataset : TDataset; E: EDatabaseError; var Action: TDataAction ); -var - v : PPyObject; -begin - IncRef; - with GetPythonEngine do - begin - v := gVarArgType.CreateInstanceWith( VariantAsPyObject( NativeInt(Action) ) ); - Py_XIncRef(v); - try - ExecuteEvent( FOnEditError, [GetSelf, ArrayToPyTuple([E.ClassName, E.Message]), v] ); - with PythonToDelphi(v) as TVarArg do - Action := TDataAction(NativeInt(PyObjectAsVariant(FValue))); - finally - Py_XDecRef(v); - end; - end; -end; - -procedure TPyDataset.OnFilterRecord( Dataset : TDataset; var Accept : Boolean ); -var - v : PPyObject; -begin - IncRef; - with GetPythonEngine do - begin - v := gVarArgType.CreateInstanceWith( VariantAsPyObject( Accept ) ); - Py_XIncRef(v); - try - ExecuteEvent( FOnFilterRecord, [GetSelf, v] ); - with PythonToDelphi(v) as TVarArg do - Accept := PyObjectAsVariant(FValue); - finally - Py_XDecRef(v); - end; - end; -end; - -procedure TPyDataset.OnNewRecord( Dataset : TDataset ); -begin - IncRef; - ExecuteEvent( FOnNewRecord, [GetSelf] ); -end; - -procedure TPyDataset.OnPostError( Dataset : TDataset; E: EDatabaseError; var Action: TDataAction ); -var - v : PPyObject; -begin - IncRef; - with GetPythonEngine do - begin - v := gVarArgType.CreateInstanceWith( VariantAsPyObject( NativeInt(Action) ) ); - Py_XIncRef(v); - try - ExecuteEvent( FOnPostError, [GetSelf, ArrayToPyTuple([E.ClassName, E.Message]), v] ); - with PythonToDelphi(v) as TVarArg do - Action := TDataAction(NativeInt(PyObjectAsVariant(FValue))); - finally - Py_XDecRef(v); - end; - end; -end; - -constructor TPythonDataset.Create( AOwner : TComponent ); -begin - inherited; - Name := 'typeDataset'; - TypeName := 'TDataset'; - Services.Sequence := [ssLength, ssItem]; - Module := gDBModule; - TypeFlags := TypeFlags + [tpfBaseType]; - PyObjectClass := TPyDataset; - with DocString do - begin - Add( 'The TDataset type implements the Delphi TDataset VCL Object inside Python.' ); - Add( 'The properties and methods are the same as in Delphi.' ); - Add( 'A TDataset can not be instancied, because it''s a virtual class.' ); - Add( 'It''s used as an interface to any Dataset subclass.'); - end; -end; - - -{********************************************************************* - * Implementation of TVarArg * - *********************************************************************} - -// Constructors & Destructors -constructor TVarArg.CreateWith( APythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine do - begin - if PyTuple_Check(args) and (PyTuple_Size(args)>=1) then - begin - FValue := PyTuple_GetItem( args, 0 ); - Py_XIncRef(FValue); - end; - end; -end; - -destructor TVarArg.Destroy; -begin - with GetPythonEngine do - Py_XDecRef(FValue); - inherited; -end; - - -// Basic services -function TVarArg.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if CompareText( string(key), 'Value' ) = 0 then - begin - Result := FValue; - if not Assigned(Result) then - Result := Py_None; - Py_XIncRef(Result); - end - else - Result := inherited GetAttr(key); - end; -end; - -function TVarArg.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - with GetPythonEngine do - begin - if CompareText( string(key), 'Value' ) = 0 then - begin - Py_XDecRef(FValue); - FValue := value; - Py_XIncRef(FValue); - Result := 0; - end - else - Result := inherited SetAttr(key, value); - end; -end; - -function TVarArg.Repr : PPyObject; -begin - with GetPythonEngine do - Result := PyString_FromString( PAnsiChar(AnsiString(PyObjectAsString(FValue))) ); -end; - -constructor TPythonVarArg.Create( AOwner : TComponent ); -begin - inherited; - Name := 'typeVarArg'; - TypeName := 'VarArg'; - Module := gDBModule; - PyObjectClass := TVarArg; - with DocString do - begin - Add( 'a VarArg object contains a single property Value,' ); - Add( 'which you can read and write in order to change' ); - Add( 'an argument in an Event.' ); - Add( 'if you try to print the VarArg, it will print the Value' ); - Add( 'property.' ); - end; -end; - -{********************************************************************* -* Global functions * -*********************************************************************} - -procedure CreateComponents( AOwner : TComponent ); -begin - if Assigned(gDBModule) then - Exit; - gDBModule := TPythonDB.Create(AOwner); - gDatasetType := TPythonDataset.Create(AOwner); - gFieldType := TPythonField.Create(AOwner); - gVarArgType := TPythonVarArg.Create(AOwner); -end; - -procedure SetEvent( var EventSlot : PPyObject; Event : PPyObject; const EventName, ClassName : String ); -begin - with GetPythonEngine do - begin - if Assigned(Event) and not (Event = Py_None) then - begin - if PyFunction_Check(Event) or PyMethod_Check(Event) then - begin - EventSlot := Event; - Py_IncRef(EventSlot); - end - else - raise Exception.CreateFmt( 'Event %s of class %s needs a function or a method', [EventName, ClassName] ); - end - else - begin - Py_XDecRef(EventSlot); - EventSlot := nil; - end; - end; -end; - -function SetDatasetEvent( EventSlot : PPyObject; dsEvent : TDataSetNotifyEvent ) : TDataSetNotifyEvent; -begin - if Assigned(EventSlot) then - Result := dsEvent - else - Result := nil; -end; - -function SetDatasetErrorEvent( EventSlot : PPyObject; dsEvent : TDataSetErrorEvent ) : TDataSetErrorEvent; -begin - if Assigned(EventSlot) then - Result := dsEvent - else - Result := nil; -end; - -procedure ClearEvent( var EventSlot : PPyObject ); -begin - with GetPythonEngine do - Py_XDecRef( EventSlot ); - EventSlot := nil; -end; - -function ReturnEvent( Event : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - if Assigned(Event) then - begin - Result := Event; - Py_IncRef(Event); - end - else - Result := ReturnNone; - end; -end; - -procedure ExecuteEvent( Event : PPyObject; Args : array of Const ); -var - L : PPyObject; - Result : PPyObject; -begin - Result := nil; - if not Assigned(Event) then - Exit; - with GetPythonEngine do - begin - L := ArrayToPyTuple( Args ); - try - Result := PyEval_CallObjectWithKeywords( Event, L, nil ); - finally - Py_XDecRef(Result); - Py_XDecRef(L); - end; - CheckError; - end; -end; - -function NewDataset( aDataset : TDataset; IsOwner : Boolean ) : PPyObject; -begin - if not Assigned(gDBModule) then - begin - CreateComponents(nil); - gDBModule.Engine := GetPythonEngine; - gDBModule.Initialize; - gDatasetType.Engine := GetPythonEngine; - gDatasetType.Initialize; - gFieldType.Engine := GetPythonEngine; - gFieldType.Initialize; - gVarArgType.Engine := GetPythonEngine; - gVarArgType.Initialize; - end; - Result := gDatasetType.CreateInstance; - with PythonToDelphi(Result) as TPyDataset do - begin - FSharedObject.Owner := IsOwner; - FSharedObject.Data := aDataset; - end; -end; - -end. diff --git a/demos_delphi/Demo10/pyDBTables.pas b/demos_delphi/Demo10/pyDBTables.pas deleted file mode 100644 index d1e6a84..0000000 --- a/demos_delphi/Demo10/pyDBTables.pas +++ /dev/null @@ -1,1743 +0,0 @@ -{$I Definition.Inc} - -unit pyDBTables; - -{------------------------------------------------------------------------------- - $Header: /P4D/PythonForDelphi/Components/Sources/VCL/pyDBTables.pas 1 03-04-09 19:25 Morgan $ - Copyright � MMM Inc. 2003 - All Rights Reserved. - ------------------------------------------------------------------------------ - Author: Morgan Martinet - - Description: - - ------------------------------------------------------------------------------ - $Log: /P4D/PythonForDelphi/Components/Sources/VCL/pyDBTables.pas $ - * - * 1 03-04-09 19:25 Morgan - * initial check-in - --------------------------------------------------------------------------------} - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - Variants, PythonEngine, StdCtrls, ExtCtrls, ComCtrls, - DB, DBTables, pyDB; -type - -{********************************************************************* - * DBTables module * - *********************************************************************} - TPythonDBTables = class(TPythonModule) - public - constructor Create( AOwner : TComponent ); override; - procedure Initialize; override; - end; - -{********************************************************************* - * Interface of TBDEDataset * - *********************************************************************} - TPyBDEDataset = class(TPyDataset) - FOnUpdateError : PPyObject; - FOnUpdateRecord : PPyObject; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - destructor Destroy; override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyDBDataset - function BDEDataset : TBDEDataset; - procedure AppendProperties( List : PPyObject ); override; - - // Interface methods - - // Events - //////////////// - procedure OnUpdateError( Dataset : TDataset; E: EDatabaseError; UpdateKind: TUpdateKind; var ua:TUpdateAction); - procedure OnUpdateRecord( Dataset : TDataset; UpdateKind: TUpdateKind; var ua:TUpdateAction); - end; - - {********************************************************************* - * Interface of TDBDataset * - *********************************************************************} - TPyDBDataset = class(TPyBDEDataset) - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyDBDataset - function DBDataset : TDBDataset; - procedure AppendProperties( List : PPyObject ); override; - - // Interface methods - end; - - {********************************************************************* - * Interface of TTable * - *********************************************************************} - TPyTable = class(TPyDBDataset) - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyTTable - function Table : TTable; - function SetRange( startValues, endValues : PPyObject ) : PPyObject; - procedure AddIndex(const Name, Fields: string; Options: PPyObject); - function GetIndexNames : PPyObject; - procedure GotoCurrent( tbl : PPyObject ); - function FindKey( KeyValues : PPyObject ) : Boolean; - procedure FindNearest( KeyValues : PPyObject ); - procedure AppendProperties( List : PPyObject ); override; - - // Interface methods - function DoSetKey( args : PPyObject ) : PPyObject; cdecl; - function DoSetRangeStart( args : PPyObject ) : PPyObject; cdecl; - function DoSetRangeEnd( args : PPyObject ) : PPyObject; cdecl; - function DoSetRange( args : PPyObject ) : PPyObject; cdecl; - function DoEditKey( args : PPyObject ) : PPyObject; cdecl; - function DoEditRangeStart( args : PPyObject ) : PPyObject; cdecl; - function DoEditRangeEnd( args : PPyObject ) : PPyObject; cdecl; - function DoApplyRange( args : PPyObject ) : PPyObject; cdecl; - function DoCancelRange( args : PPyObject ) : PPyObject; cdecl; - function DoLockTable( args : PPyObject ) : PPyObject; cdecl; - function DoUnlockTable( args : PPyObject ) : PPyObject; cdecl; - function DoAddIndex( args : PPyObject ) : PPyObject; cdecl; - function DoCloseIndexFile( args : PPyObject ) : PPyObject; cdecl; - function DoCreateTable( args : PPyObject ) : PPyObject; cdecl; - function DoDeleteIndex( args : PPyObject ) : PPyObject; cdecl; - function DoDeleteTable( args : PPyObject ) : PPyObject; cdecl; - function DoEmptyTable( args : PPyObject ) : PPyObject; cdecl; - function DoGetIndexNames( args : PPyObject ) : PPyObject; cdecl; - function DoOpenIndexFile( args : PPyObject ) : PPyObject; cdecl; - function DoRenameTable( args : PPyObject ) : PPyObject; cdecl; - function DoGotoCurrent( args : PPyObject ) : PPyObject; cdecl; - function DoGotoNearest( args : PPyObject ) : PPyObject; cdecl; - function DoGotoKey( args : PPyObject ) : PPyObject; cdecl; - function DoFindKey( args : PPyObject ) : PPyObject; cdecl; - function DoFindNearest( args : PPyObject ) : PPyObject; cdecl; - end; - - TPythonTable = class( TPythonType) - public - constructor Create( AOwner : TComponent ); override; - end; - - {********************************************************************* - * Interface of TQuery * - *********************************************************************} - - TPyQuery = class(TPyDBDataset) - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyTTable - function Query : TQuery; - procedure AppendProperties( List : PPyObject ); override; - - // Interface methods - function DoPrepare( args : PPyObject ) : PPyObject; cdecl; - function DoUnPrepare( args : PPyObject ) : PPyObject; cdecl; - function DoExecSQL( args : PPyObject ) : PPyObject; cdecl; - end; - - TPythonQuery = class( TPythonType) - public - constructor Create( AOwner : TComponent ); override; - end; - - {********************************************************************* - * Global functions * - *********************************************************************} - procedure CreateComponents( AOwner : TComponent ); - - {******************************************************************** - * Global variables * - *********************************************************************} -var - gDBTablesModule : TPythonModule; - gTableType : TPythonType; - gQueryType : TPythonType; - -implementation - -{********************************************************************* - * DBTables module * - *********************************************************************} - -constructor TPythonDBTables.Create( AOwner : TComponent ); -begin - inherited; - ModuleName := 'DBTables'; - Name := 'modDBTables'; - with DocString do - begin - Add( 'This module contains several Object Types that' ); - Add( 'will let you work with the Borland BDE and access' ); - Add( 'a database.' ); - Add( '' ); - Add( 'CreateTTable() -> creates a TTable instance' ); - Add( 'CreateTQuery() -> creates a TQuery instance' ); - end; -end; - -procedure TPythonDBTables.Initialize; -begin - inherited; - // Values for type TLockType - SetVarFromVariant( 'ltReadLock', 0 ); - SetVarFromVariant( 'ltWriteLock', 1 ); - // Values for type TIndexOptions - SetVarFromVariant( 'ixPrimary', 0 ); - SetVarFromVariant( 'ixUnique', 1 ); - SetVarFromVariant( 'ixDescending', 2 ); - SetVarFromVariant( 'ixCaseInsensitive', 3 ); - SetVarFromVariant( 'ixExpression', 4 ); - // Values for type TUpdateAction - SetVarFromVariant( 'uaFail', 0 ); - SetVarFromVariant( 'uaAbort', 1 ); - SetVarFromVariant( 'uaSkip', 2 ); - SetVarFromVariant( 'uaRetry', 3 ); - SetVarFromVariant( 'uaApplied', 4 ); -end; - -{********************************************************************* - * Implementation of TBDEDataset * - *********************************************************************} - -// We override the constructors - -constructor TPyBDEDataset.Create( APythonType : TPythonType ); -begin - inherited; -end; - -destructor TPyBDEDataset.Destroy; -begin - if EventBelongsToObject( TCallbackSplit(BDEDataset.OnUpdateError) ) then - BDEDataset.OnUpdateError := nil; - if EventBelongsToObject( TCallbackSplit(BDEDataset.OnUpdateRecord) ) then - BDEDataset.OnUpdateRecord := nil; - ClearEvent( FOnUpdateError ); - ClearEvent( FOnUpdateRecord ); - inherited; -end; - - -// Then we override the needed services - -function TPyBDEDataset.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if not CheckDataset then - begin - Result := nil; - Exit; - end; - try - if CompareText( string(key), 'OnUpdateError' ) = 0 then - Result := ReturnEvent( FOnUpdateError ) - else if CompareText( string(key), 'OnUpdateRecord' ) = 0 then - Result := ReturnEvent( FOnUpdateRecord ) - else - Result := inherited GetAttr(key); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyBDEDataset.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := -1; - with GetPythonEngine do - begin - if not CheckDataset then - Exit; - try - if CompareText( string(key), 'OnUpdateError' ) = 0 then - begin - SetEvent( FOnUpdateError, Value, 'OnUpdateError', 'TField' ); - if Assigned(FOnUpdateError) then - BDEDataset.OnUpdateError := OnUpdateError - else - BDEDataset.OnUpdateError := nil; - Result := 0; - end - else if CompareText( string(key), 'OnUpdateRecord' ) = 0 then - begin - SetEvent( FOnUpdateRecord, Value, 'OnUpdateRecord', 'TField' ); - if Assigned(FOnUpdateRecord) then - BDEDataset.OnUpdateRecord := OnUpdateRecord - else - BDEDataset.OnUpdateRecord := nil; - Result := 0; - end - else - Result := inherited SetAttr(key, value); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := -1; - end; - end; - end; -end; - - -// Class methods -// We register the methods of our type - -class procedure TPyBDEDataset.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - //AddMethod( 'First', @TPyDataset.DoFirst, 'TDataset.First' ); - end; -end; - -// Methods of TPyBDEDataset -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -function TPyBDEDataset.BDEDataset : TBDEDataset; -begin - Result := Dataset as TBDEDataset; -end; - -procedure TPyBDEDataset.AppendProperties( List : PPyObject ); -begin - inherited; - //AppendProp( List, ''); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -// Events -//////////////// -procedure TPyBDEDataset.OnUpdateError( Dataset : TDataset; E: EDatabaseError; UpdateKind: TUpdateKind; var ua:TUpdateAction); -var - v : PPyObject; -begin - IncRef; - with GetPythonEngine do - begin - v := gVarArgType.CreateInstanceWith( VariantAsPyObject( NativeInt(ua) ) ); - Py_XIncRef(v); - try - ExecuteEvent( FOnUpdateError, [GetSelf, ArrayToPyTuple([E.ClassName, E.Message]), Integer(UpdateKind), v] ); - with PythonToDelphi(v) as TVarArg do - ua := TUpdateAction(NativeInt(PyObjectAsVariant(FValue))); - finally - Py_XDecRef(v); - end; - end; -end; - -procedure TPyBDEDataset.OnUpdateRecord( Dataset : TDataset; UpdateKind: TUpdateKind; var ua:TUpdateAction); -var - v : PPyObject; -begin - IncRef; - with GetPythonEngine do - begin - v := gVarArgType.CreateInstanceWith( VariantAsPyObject( NativeInt(ua) ) ); - Py_XIncRef(v); - try - ExecuteEvent( FOnUpdateError, [GetSelf, Integer(UpdateKind), v] ); - with PythonToDelphi(v) as TVarArg do - ua := TUpdateAction(NativeInt(PyObjectAsVariant(FValue))); - finally - Py_XDecRef(v); - end; - end; -end; - - -{********************************************************************* - * Implementation of TDBDataset * - *********************************************************************} - -// We override the constructors - -constructor TPyDBDataset.Create( APythonType : TPythonType ); -begin - inherited; -end; - - - -// Then we override the needed services - -function TPyDBDataset.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if not CheckDataset then - begin - Result := nil; - Exit; - end; - try - if CompareText( string(key), 'DatabaseName' ) = 0 then - Result := VariantAsPyObject( DBDataset.DatabaseName ) - else if CompareText( string(key), 'SessionName' ) = 0 then - Result := VariantAsPyObject( DBDataset.SessionName ) - else - Result := inherited GetAttr(key); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyDBDataset.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := -1; - with GetPythonEngine do - begin - if not CheckDataset then - Exit; - try - if CompareText( string(key), 'DatabaseName' ) = 0 then - begin - DBDataset.DatabaseName := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'SessionName' ) = 0 then - begin - DBDataset.SessionName := PyObjectAsVariant( value ); - Result := 0; - end - else - Result := inherited SetAttr(key, value); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := -1; - end; - end; - end; -end; - - -// Class methods -// We register the methods of our type - -class procedure TPyDBDataset.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - //AddMethod( 'First', @TPyDataset.DoFirst, 'TDataset.First' ); - end; -end; - -// Methods of TPyDBDataset -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -function TPyDBDataset.DBDataset : TDBDataset; -begin - Result := Dataset as TDBDataset; -end; - -procedure TPyDBDataset.AppendProperties( List : PPyObject ); -begin - inherited; - AppendProp( List, 'DatabaseName'); - AppendProp( List, 'SessionName'); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - - -{********************************************************************* - * Implementation of TTable * - *********************************************************************} - -// We override the constructors - -constructor TPyTable.Create( APythonType : TPythonType ); -begin - inherited; - FSharedObject.Data := TTable.Create(APythonType); -end; - - - -// Then we override the needed services - -function TPyTable.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if not CheckDataset then - begin - Result := nil; - Exit; - end; - try - if CompareText( string(key), 'IndexName' ) = 0 then - Result := VariantAsPyObject( Table.IndexName ) - else if CompareText( string(key), 'ReadOnly' ) = 0 then - Result := VariantAsPyObject( Table.ReadOnly ) - else if CompareText( string(key), 'TableLevel' ) = 0 then - Result := VariantAsPyObject( Table.TableLevel ) - else if CompareText( string(key), 'TableName' ) = 0 then - Result := VariantAsPyObject( Table.TableName ) - else if CompareText( string(key), 'TableType' ) = 0 then - Result := VariantAsPyObject( Integer(Table.TableType) ) - else - Result := inherited GetAttr(key); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := -1; - with GetPythonEngine do - begin - if not CheckDataset then - Exit; - try - if CompareText( string(key), 'IndexName' ) = 0 then - begin - Table.IndexName := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'ReadOnly' ) = 0 then - begin - Table.ReadOnly := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'TableLevel' ) = 0 then - begin - Table.TableLevel := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'TableName' ) = 0 then - begin - Table.TableName := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'TableType' ) = 0 then - begin - Table.TableType := TTableType(PyObjectAsVariant( value )); - Result := 0; - end - else - Result := inherited SetAttr(key, value); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := -1; - end; - end; - end; -end; - -// Class methods -// We register the methods of our type - -class procedure TPyTable.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - AddMethod( 'SetKey', @TPyTable.DoSetKey, 'TTable.SetKey() -> None' ); - AddMethod( 'SetRangeStart', @TPyTable.DoSetRangeStart, 'TTable.SetRangeStart() -> None' ); - AddMethod( 'SetRangeEnd', @TPyTable.DoSetRangeEnd, 'TTable.SetRangeEnd() -> None' ); - AddMethod( 'SetRange', @TPyTable.DoSetRange, 'TTable.SetRange( sequence of RangeStart values, sequence of RangeEnd values ) -> None' ); - AddMethod( 'EditKey', @TPyTable.DoEditKey, 'TTable.EditKey() -> None' ); - AddMethod( 'EditRangeStart', @TPyTable.DoEditRangeStart, 'TTable.EditRangeStart() -> None' ); - AddMethod( 'EditRangeEnd', @TPyTable.DoEditRangeEnd, 'TTable.EditRangeEnd() -> None' ); - AddMethod( 'ApplyRange', @TPyTable.DoApplyRange, 'TTable.ApplyRange() -> None' ); - AddMethod( 'CancelRange', @TPyTable.DoCancelRange, 'TTable.CancelRange() -> None' ); - AddMethod( 'LockTable', @TPyTable.DoLockTable, 'TTable.LockTable( LockType : TLockType ) -> None' ); - AddMethod( 'UnlockTable', @TPyTable.DoUnlockTable, 'TTable.UnlockTable( LockType : TLockType ) -> None' ); - AddMethod( 'AddIndex', @TPyTable.DoAddIndex, 'TTable.AddIndex( Name : String, Fields : String, Options : TIndexOptions ) -> None' ); - AddMethod( 'CloseIndexFile', @TPyTable.DoCloseIndexFile, 'TTable.CloseIndexFile( IndexFileName : String ) -> None' ); - AddMethod( 'CreateTable', @TPyTable.DoCreateTable, 'TTable.CreateTable() -> None' ); - AddMethod( 'DeleteIndex', @TPyTable.DoDeleteIndex, 'TTable.DeleteIndex( Name : String ) -> None' ); - AddMethod( 'DeleteTable', @TPyTable.DoDeleteTable, 'TTable.DeleteTable() -> None' ); - AddMethod( 'EmptyTable', @TPyTable.DoEmptyTable, 'TTable.EmptyTable() -> None' ); - AddMethod( 'GetIndexNames', @TPyTable.DoGetIndexNames, 'TTable.GetIndexNames() -> list of Index Names' ); - AddMethod( 'OpenIndexFile', @TPyTable.DoOpenIndexFile, 'TTable.OpenIndexFile( IndexFileName : String ) -> None' ); - AddMethod( 'RenameTable', @TPyTable.DoRenameTable, 'TTable.RenameTable( NewName : String ) -> None' ); - AddMethod( 'GotoCurrent', @TPyTable.DoGotoCurrent, 'TTable.GotoCurrent( table : TTable ) -> None' ); - AddMethod( 'GotoNearest', @TPyTable.DoGotoNearest, 'TTable.GotoNearest() -> None' ); - AddMethod( 'GotoKey', @TPyTable.DoGotoKey, 'TTable.GotoKey() -> True or False' ); - AddMethod( 'FindKey', @TPyTable.DoFindKey, 'TTable.FindKey( KeyValues : Sequence ) -> True or False' ); - AddMethod( 'FindNearest', @TPyTable.DoFindNearest, 'TTable.FindNearest( KeyValues : Sequence ) -> None' ); - end; -end; - -// Methods of TPyTable -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -function TPyTable.Table : TTable; -begin - Result := FSharedObject.Data as TTable; -end; - -function TPyTable.SetRange( startValues, endValues : PPyObject ) : PPyObject; -var - i : Integer; -begin - Result := nil; - with GetPythonEngine do - begin - if PySequence_Check(startValues) = 0 then - begin - PyErr_SetString (PyExc_AttributeError^, 'First argument of SetRange must be a sequence.'); - Exit; - end; - if PySequence_Check(endValues) = 0 then - begin - PyErr_SetString (PyExc_AttributeError^, 'Second argument of SetRange must be a sequence.'); - Exit; - end; - with Table do - begin - SetRangeStart; - for i := 0 to PySequence_Length(startValues)-1 do - begin - IndexFields[i].Value := PyObjectAsVariant(PySequence_GetItem(startValues, i)); - end; - SetRangeEnd; - for i := 0 to PySequence_Length(endValues)-1 do - begin - IndexFields[i].Value := PyObjectAsVariant(PySequence_GetItem(endValues, i)); - end; - ApplyRange; - end; - Result := ReturnNone; - end; -end; - -procedure TPyTable.AddIndex(const Name, Fields: string; Options: PPyObject); -var - opt : TIndexOptions; -begin - with GetPythonEngine do - begin - ListToSet( Options, @opt, sizeof(opt) ); - Table.AddIndex( Name, Fields, opt ); - end; -end; - -function TPyTable.GetIndexNames : PPyObject; -var - L : TStringList; -begin - L := TStringList.Create; - try - Table.GetIndexNames( L ); - Result := GetPythonEngine.StringsToPyList( L ); - finally - L.Free; - end; -end; - -procedure TPyTable.GotoCurrent( tbl : PPyObject ); -var - obj : TPyObject; -begin - with GetPythonEngine do - begin - if IsDelphiObject( tbl ) then - begin - obj := PythonToDelphi(tbl); - if obj is TPyTable then - begin - Table.GotoCurrent( TPyTable(obj).Table ); - end - else - raise EPythonError.Create( 'TTable.GotoCurrent: the Delphi Type class is not a TPyTable, or one of its descendants' ); - end - else - raise EPythonError.Create( 'TTable.GotoCurrent: need a TTable object as argument' ); - end; -end; - -function TPyTable.FindKey( KeyValues : PPyObject ) : Boolean; -var - V : Variant; - i : Integer; -begin - with GetPythonEngine do - begin - if PySequence_Check( KeyValues ) <> 0 then - begin - V := PyObjectAsVariant( KeyValues ); - Table.CheckBrowseMode; - Table.SetKey; - for i := 0 to VarArrayHighBound(V, 1) do - Table.IndexFields[i].AsVariant := V[i]; - Result := Table.GotoKey; - end - else - Result := False; - end; -end; - -procedure TPyTable.FindNearest( KeyValues : PPyObject ); -var - V : Variant; - i : Integer; -begin - with GetPythonEngine do - begin - if PySequence_Check( KeyValues ) <> 0 then - begin - V := PyObjectAsVariant( KeyValues ); - Table.CheckBrowseMode; - Table.SetKey; - for i := 0 to VarArrayHighBound(V, 1) do - Table.IndexFields[i].AsVariant := V[i]; - Table.GotoNearest; - end; - end; -end; - -procedure TPyTable.AppendProperties( List : PPyObject ); -begin - inherited; - AppendProp( List, 'IndexName'); - AppendProp( List, 'ReadOnly'); - AppendProp( List, 'TableLevel'); - AppendProp( List, 'TableName'); - AppendProp( List, 'TableType'); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. -function TPyTable.DoSetKey( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.SetKey; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoSetRangeStart( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.SetRangeStart; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoSetRangeEnd( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.SetRangeEnd; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoSetRange( args : PPyObject ) : PPyObject; cdecl; -var - startValues, endValues : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'OO:TDataset.SetRange',@startValues, @endValues ) <> 0) then - begin - // Do action - Result := SetRange( startValues, endValues ); - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoEditKey( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.EditKey; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoEditRangeStart( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.EditRangeStart; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoEditRangeEnd( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.EditRangeEnd; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoApplyRange( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.ApplyRange; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoCancelRange( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.CancelRange; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoLockTable( args : PPyObject ) : PPyObject; cdecl; -var - t : Integer; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'i:TTable.LockTable',@t ) <> 0) then - begin - // Do action - Table.LockTable(TLockType(t)); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoUnlockTable( args : PPyObject ) : PPyObject; cdecl; -var - t : Integer; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'i:TTable.LockTable',@t ) <> 0) then - begin - // Do action - Table.UnlockTable(TLockType(t)); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoAddIndex( args : PPyObject ) : PPyObject; cdecl; -var - aName, fields : PAnsiChar; - options : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'ssO:TTable.AddIndex',@aName, @fields, @options ) <> 0) then - begin - // Do action - AddIndex( string(aName), string(fields), options ); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoCloseIndexFile( args : PPyObject ) : PPyObject; cdecl; -var - aName : PAnsiChar; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 's:TTable.CloseIndexFile',@aName ) <> 0) then - begin - // Do action - Table.CloseIndexFile( string(aName) ); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoCreateTable( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.CreateTable; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoDeleteIndex( args : PPyObject ) : PPyObject; cdecl; -var - aName : PAnsiChar; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 's:TTable.DeleteIndex',@aName ) <> 0) then - begin - // Do action - Table.DeleteIndex( string(aName) ); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoDeleteTable( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.DeleteTable; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoEmptyTable( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.EmptyTable; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoGetIndexNames( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Result := GetIndexNames; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoOpenIndexFile( args : PPyObject ) : PPyObject; cdecl; -var - aName : PAnsiChar; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 's:TTable.OpenIndexFile',@aName ) <> 0) then - begin - // Do action - Table.OpenIndexFile( string(aName) ); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoRenameTable( args : PPyObject ) : PPyObject; cdecl; -var - newName : PAnsiChar; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 's:TTable.RenameTable',@newName ) <> 0) then - begin - // Do action - Table.RenameTable( string(newName) ); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoGotoCurrent( args : PPyObject ) : PPyObject; cdecl; -var - tbl : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'O:TTable.GotoCurrent',@tbl ) <> 0) then - begin - // Do action - GotoCurrent( tbl ); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoGotoNearest( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Table.GotoNearest; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoGotoKey( args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Result := VariantAsPyObject( Table.GotoKey ); - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoFindKey( args : PPyObject ) : PPyObject; cdecl; -var - KeyValues : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'O:TTable.FindKey',@KeyValues ) <> 0) then - begin - // Do action - Result := VariantAsPyObject( FindKey( KeyValues ) ); - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyTable.DoFindNearest( args : PPyObject ) : PPyObject; cdecl; -var - KeyValues : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset and (PyArg_ParseTuple( args, 'O:TTable.FindNearest',@KeyValues ) <> 0) then - begin - // Do action - FindNearest(KeyValues); - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -constructor TPythonTable.Create( AOwner : TComponent ); -begin - inherited; - Name := 'typeTable'; - TypeName := 'TTable'; - Services.Sequence := [ssLength, ssItem]; - Module := gDBTablesModule; - TypeFlags := TypeFlags + [tpfBaseType]; - PyObjectClass := TPyTable; - with DocString do - begin - Add( 'The TTable type implements the Delphi TTable VCL Object inside Python.' ); - Add( 'The properties and methods are the same as in Delphi.' ); - end; -end; - -{********************************************************************* - * Implementation of TQuery * - *********************************************************************} - -// We override the constructors - -constructor TPyQuery.Create( APythonType : TPythonType ); -begin - inherited; - FSharedObject.Data := TQuery.Create(APythonType); -end; - - - -// Then we override the needed services - -function TPyQuery.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if not CheckDataset then - begin - Result := nil; - Exit; - end; - try - if CompareText( string(key), 'Constrained' ) = 0 then - Result := VariantAsPyObject( Query.Constrained ) - else if CompareText( string(key), 'Local' ) = 0 then - Result := VariantAsPyObject( Query.Local) - else if CompareText( string(key), 'ParamCheck' ) = 0 then - Result := VariantAsPyObject( Query.ParamCheck ) - else if CompareText( string(key), 'ParamCount' ) = 0 then - Result := VariantAsPyObject( Query.ParamCount ) - else if CompareText( string(key), 'Prepared' ) = 0 then - Result := VariantAsPyObject( Query.Prepared ) - else if CompareText( string(key), 'RequestLive' ) = 0 then - Result := VariantAsPyObject( Query.RequestLive ) - else if CompareText( string(key), 'RowsAffected' ) = 0 then - Result := VariantAsPyObject( Query.RowsAffected ) - else if CompareText( string(key), 'SQL' ) = 0 then - Result := StringsToPyList( Query.SQL) - else if CompareText( string(key), 'UniDirectional' ) = 0 then - Result := VariantAsPyObject( Query.UniDirectional ) - else - Result := inherited GetAttr(key); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyQuery.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := -1; - with GetPythonEngine do - begin - if not CheckDataset then - Exit; - try - if CompareText( string(key), 'Constrained' ) = 0 then - begin - Query.Constrained := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'Local' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'ParamCheck' ) = 0 then - begin - Query.ParamCheck := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'ParamCount' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'Prepared' ) = 0 then - begin - Query.Prepared := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'RequestLive' ) = 0 then - begin - Query.RequestLive := PyObjectAsVariant( value ); - Result := 0; - end - else if CompareText( string(key), 'RowsAffected' ) = 0 then - begin - Result := 0; - end - else if CompareText( string(key), 'SQL' ) = 0 then - begin - PyListToStrings( value, Query.SQL ); - Result := 0; - end - else if CompareText( string(key), 'UniDirectional' ) = 0 then - begin - Query.UniDirectional := PyObjectAsVariant( value ); - Result := 0; - end - else - Result := inherited SetAttr(key, value); - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := -1; - end; - end; - end; -end; - - -// Class methods -// We register the methods of our type - -class procedure TPyQuery.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - AddMethod( 'Prepare', @TPyQuery.DoPrepare, 'TQuery.Prepare() -> None' ); - AddMethod( 'Unprepare', @TPyQuery.DoUnprepare, 'TQuery.Unprepare() -> None' ); - AddMethod( 'ExecSQL', @TPyQuery.DoExecSQL, 'TQuery.ExecSQL() -> None' ); - end; -end; - -// Methods of TPyQuery -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -function TPyQuery.Query : TQuery; -begin - Result := FSharedObject.Data as TQuery; -end; - -procedure TPyQuery.AppendProperties( List : PPyObject ); -begin - inherited; - AppendProp( List, 'Constrained'); - AppendProp( List, 'Local'); - AppendProp( List, 'ParamCheck'); - AppendProp( List, 'ParamCount'); - AppendProp( List, 'Prepared'); - AppendProp( List, 'RequestLive'); - AppendProp( List, 'RowsAffected'); - AppendProp( List, 'SQL'); - AppendProp( List, 'UniDirectional'); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -function TPyQuery.DoPrepare( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Query.Prepare; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyQuery.DoUnPrepare( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Query.UnPrepare; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -function TPyQuery.DoExecSQL( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - try - if CheckDataset then - begin - // Do action - Query.ExecSQL; - // Finally, we return nothing - Result := ReturnNone; - end - else - Result := nil; - except // Remap Delphi exception to a Python exception - on E : Exception do - begin - RaiseDBError( E ); - Result := nil; - end; - end; - end; -end; - -constructor TPythonQuery.Create( AOwner : TComponent ); -begin - inherited; - Name := 'typeQuery'; - TypeName := 'TQuery'; - Services.Sequence := [ssLength, ssItem]; - Module := gDBTablesModule; - PyObjectClass := TPyQuery; - with DocString do - begin - Add( 'The TQuery type implements the Delphi TQuery VCL Object inside Python.' ); - Add( 'The properties and methods are the same as in Delphi.' ); - end; -end; - -{********************************************************************* -* Global functions * -*********************************************************************} - -procedure CreateComponents( AOwner : TComponent ); -begin - if Assigned(gDBTablesModule) then - Exit; - gDBTablesModule := TPythonDBTables.Create(AOwner); - gTableType := TPythonTable.Create(AOwner); - gQueryType := TPythonQuery.Create(AOwner); -end; - -end. diff --git a/demos_delphi/Demo10_FireDAC/Demo.ini b/demos_delphi/Demo10_FireDAC/Demo.ini deleted file mode 100644 index c39632a..0000000 --- a/demos_delphi/Demo10_FireDAC/Demo.ini +++ /dev/null @@ -1,26 +0,0 @@ -[MSSQL_DB] -BaseDriverID=MSSQL -DriverID=MSSQL_2008 -ODBCDriver=SQL Server Native Client 11.0 -Server=XXX\YYY -Database=XXX -OSAuthent=No -User_Name=XXX -Password=XXX -MetaDefCatalog=XX -MetaDefSchema=XXX -ExtendedMetadata=True -VariantFormat=Binary -Encrypt=No -MARS=Yes - -[Ora_DB] -DriverID=OraXE -Database=localhost:1521/XE -User_Name=XXX -Password=YYY -CharacterSet=UTF8 - -[SQLite_DB] -DriverID=SQLite -Database=Demo.s3db diff --git a/demos_delphi/Demo10_FireDAC/Demo.s3db b/demos_delphi/Demo10_FireDAC/Demo.s3db deleted file mode 100644 index b330da8..0000000 Binary files a/demos_delphi/Demo10_FireDAC/Demo.s3db and /dev/null differ diff --git a/demos_delphi/Demo10_FireDAC/Demo10.dpr b/demos_delphi/Demo10_FireDAC/Demo10.dpr deleted file mode 100644 index 6bde7c5..0000000 --- a/demos_delphi/Demo10_FireDAC/Demo10.dpr +++ /dev/null @@ -1,13 +0,0 @@ -program Demo10; - -uses - Forms, - fmMain in 'fmMain.pas' {Main}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TMain, Main); - Application.Run; -end. diff --git a/demos_delphi/Demo10_FireDAC/Demo10.dproj b/demos_delphi/Demo10_FireDAC/Demo10.dproj deleted file mode 100644 index dfb7993..0000000 --- a/demos_delphi/Demo10_FireDAC/Demo10.dproj +++ /dev/null @@ -1,566 +0,0 @@ - - - {1D701B96-D47C-4AD0-BE2E-830C95586BC9} - Demo10.dpr - Debug - DCC32 - 18.3 - VCL - True - Win64 - 2 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - Demo10.exe - 00400000 - x86 - Demo10 - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - 1032 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - .\$(Platform)\$(Config) - ..\..\Components\Sources\Core;$(DCC_UnitSearchPath) - - - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 - $(BDS)\bin\default_app.manifest - Demo10_Icon1.ico - true - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - Demo10_Icon1.ico - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 1033 - $(BDS)\bin\default_app.manifest - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - true - true - - - true - true - - - DEBUG;USE_FASTMM4_LEAK_MONITOR;FullDebugMode;LogMemoryLeakDetailToFile;$(DCC_Define) - - - true - true - true - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - - - true - true - 1033 - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - false - $(BDS)\bin\delphi_PROJECTICON.ico - - - - MainSource - - -
Main
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Demo10.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1032 - 1253 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - False - True - - - - - Demo10.exe - true - - - - - 1 - - - Contents\MacOS - 0 - - - - - classes - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - - - res\values - 1 - - - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - 1 - - - 1 - - - 1 - - - - - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - 12 - - - -
diff --git a/demos_delphi/Demo10_FireDAC/Demo10.res b/demos_delphi/Demo10_FireDAC/Demo10.res deleted file mode 100644 index 3c461d3..0000000 Binary files a/demos_delphi/Demo10_FireDAC/Demo10.res and /dev/null differ diff --git a/demos_delphi/Demo10_FireDAC/Example1.py b/demos_delphi/Demo10_FireDAC/Example1.py deleted file mode 100644 index c7065f2..0000000 --- a/demos_delphi/Demo10_FireDAC/Example1.py +++ /dev/null @@ -1,65 +0,0 @@ -import DBFireDac - -# Create and open the table -T = DBFireDac.TFDTable(None) -T.ConnectionDefName = "SQLite_DB" -T.TableName = "Customer" -T.Active = True #or use T.Open() - -# Display columns -print ("Columns: ", T.FieldNamesAsTuple()) - -LastInvoiceDate = T.FieldByName("LastInvoiceDate") - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a list - A = [] - for i in range( 0, T.FieldCount ): - A.append( T.Fields(i).Value ) - # Print the current record number and the list - print ("Rec.", T.RecNo, ":", A) - # Edit record - T.Edit() - T.FieldByName("TaxRate").Value = 2.5 - # Increments date by one day - D = LastInvoiceDate.Value - if D[2] < 28: - D2 = D[:2]+(D[2]+1,)+D[3:] # this is tuple arithmetic ! - else: - D2 = D[:2]+(1,)+D[3:] # this is tuple arithmetic ! - LastInvoiceDate.Value = D2 - T.Post() - # Get next record - T.Next() - -# Print some fields by their names -F = T.FieldByName("Company") -print (F, F.FieldName, "=", F.Value) - -# Use the TFields and print the list of companies -T.First() -while not T.EOF: - print (F.AsString) - T.Next() - -# Print the fields as a dictionary -D = T.FieldsAsDict() -print (D) -print ("COMPANY:", D["COMPANY"]) # <- case-sensitive - -T.Close() - -T.TableName = "Dummy" -try: - T.Open() -except DBFireDac.DBError: - print ("could not open table ", T.TableName) - -#delete fields -del F -del LastInvoiceDate - -# delete the table -del T diff --git a/demos_delphi/Demo10_FireDAC/Example2.py b/demos_delphi/Demo10_FireDAC/Example2.py deleted file mode 100644 index 3b6ef1e..0000000 --- a/demos_delphi/Demo10_FireDAC/Example2.py +++ /dev/null @@ -1,76 +0,0 @@ -import DBFireDac - -# Get the TTable object associated to -# the delphi table displayed on right -# It is done when you click on Execute -T = DBFireDac.T - -# Display TableName -print ("TableName: ", T.TableName) - -# Display columns -print ("Columns: ") -for i in T.FieldNamesAsTuple(): - print (" ", i) - -T.CancelRange() -# For each record of the table -for i in T: # <- required ContainerAccess !!! - print ("Rec.", T.RecNo, ":", i) - -# Print some fields by their names -print ("Rec.", T.RecNo, ": ", "Company: ", T.FieldByName("Company").Value) - -# check state -if not T.State in [DBFireDac.dsEdit, DBFireDac.dsInsert]: - print ("Table is not edited") - -# access the table like an array -print ("Index 10; Row 11: ", T[10]) # Row 11 <- required ContainerAccess !!! -print ("Index 10; Row 11 - First field: ", T[10][1]) # second field of row 11 <- required ContainerAccess !!! - -# locate a record -if T.Locate( "City;State", ["Largo","FL"], [] ): - print ("Found RecNo:", T.RecNo, " for Locate(Key: 'City;State', Value: [Largo,FL])") -if T.Locate( "Company", "BLUE SPORTS", [DBFireDac.loCaseInsensitive] ): - print ("Found RecNo:", T.RecNo, " for Locate(Key: 'Company', Value: [BLUE SPORTS])") -if T.Locate( "Company", "ISLAND", [DBFireDac.loCaseInsensitive, DBFireDac.loPartialKey] ): - print ("Found RecNo:", T.RecNo, " for Locate(Key: 'Company', Value: [ISLAND])") - -# lookup a record -print ("Lookup 'CustNo;Company' for Key: 'City;State', Value: [Largo,FL] -> ", T.Lookup( "City;State", ["Largo","FL"], "CustNo;Company" )) - -# define a range -print ("-----------------------------------------------------------") -print ("Names of Indexes:", T.GetIndexNames()) -T.IndexName = "SK1_CUSTOMER" -T.SetRange( ["Unisco"], ["Unisco"] ) -for i in T: - print ("Rec.", T.RecNo, ":", i) -T.CancelRange() - -print ("-----------------------------------------------------------") -# Find a record -if T.FindKey( ['Unisco'] ): - print ("Unisco found !") -else: - print ("Could not find Unisco !") - -# Find the nearest record -T.FindNearest( ['Ocean'] ) -print ("Find nearest Ocean :", T.FieldsAsTuple()) - -# Print all doc strings of an instance's methods -def PrintDocOf( inst ): - print ("--------------------- Type ", type(inst).__name__, "---------------------") - if type(inst).__doc__: - print (type(inst).__doc__) -print ("-----------------------------------------------------------") -print ("Documentation:") -print -print ("Module DBFireDac:") -print (DBFireDac.__doc__) -PrintDocOf(T) -print ("-----------------------------------------------------------") - - diff --git a/demos_delphi/Demo10_FireDAC/Example3.py b/demos_delphi/Demo10_FireDAC/Example3.py deleted file mode 100644 index 419f64d..0000000 --- a/demos_delphi/Demo10_FireDAC/Example3.py +++ /dev/null @@ -1,54 +0,0 @@ -import DBFireDac -from datetime import datetime - -# Get the TTable object associated to -# the delphi table displayed on right -# It is done when you click on Execute -T = DBFireDac.T - -# Display columns -print ("Columns: ") -for i in T.FieldNamesAsTuple(): - print (" ", i) - -# For each record of the table -print ("Company name for each record of table : ") -T.First() -while not T.EOF: - # Print the current record number and the Company - print ("Rec.", T.RecNo, "; Company: ", T.FieldByName("Company").Value) - # Get next record - T.Next() - -# check state -if not T.State in [DBFireDac.dsEdit, DBFireDac.dsInsert]: - print ("Table is not edited") - -# Find and edit a record -T.IndexName = "SK1_CUSTOMER" -if T.FindKey( ['Unisco'] ): - print ("Unisco found !") - T.Edit() - T.FieldByName('ADDR2').AsString = 'Egal' - T.FieldByName('LASTINVOICEDATE').AsDateTime = datetime.today() - T.Post() - print ("New values for ADDR2='", T.FieldByName('ADDR2').AsString, "'and LASTINVOICEDATE=", T.FieldByName('LASTINVOICEDATE').AsString) -else: - print ("Could not find Unisco !") - -# New Company: Append or Delete -if T.FindKey( ['Test-Company'] ): - # Delete record - T.Delete() - print ("New Company 'Test-Company' deleted !") -else: - # New record - T.Append() - T.FieldByName('COMPANY').AsString = 'Test-Company' - T.FieldByName('ADDR1').AsString = 'Marktplatz 1' - T.FieldByName('CITY').AsString = 'Köln' - T.FieldByName('LASTINVOICEDATE').AsDateTime = datetime.today() - T.Post() - print ("New Company 'Test-Company' created !") - - diff --git a/demos_delphi/Demo10_FireDAC/Example4.py b/demos_delphi/Demo10_FireDAC/Example4.py deleted file mode 100644 index 3db19c4..0000000 --- a/demos_delphi/Demo10_FireDAC/Example4.py +++ /dev/null @@ -1,30 +0,0 @@ -import DBFireDac - -# Create and open the Query -Q = DBFireDac.TFDQuery(None) -Q.ConnectionDefName = "SQLite_DB" -Q.SQL.Text = """select * -from ORDERS -""" - -Q.Open() # or Q.Active = True - -# Display columns -print ("Columns: ", Q.FieldNamesAsTuple()) -# For each record of the table -Q.First() -while not Q.EOF: - # Get all the fields in a list - A = [] - for i in range( 0, Q.FieldCount ): - A.append( Q.Fields(i).AsString ) - # Print the current record number and the list - print ("Rec.", Q.RecNo, ":", A) - # Get next record - Q.Next() -# -Q.Close() - -# delete the Query -del Q - diff --git a/demos_delphi/Demo10_FireDAC/FDDrivers.ini b/demos_delphi/Demo10_FireDAC/FDDrivers.ini deleted file mode 100644 index 6711ca6..0000000 --- a/demos_delphi/Demo10_FireDAC/FDDrivers.ini +++ /dev/null @@ -1,19 +0,0 @@ -[ADDrivers.ini] -Encoding=UTF8 - -[OraXE] -BaseDriverID=Ora -VendorHome=XE - -[MSSQL_2005] -BaseDriverID=MSSQL -ODBCDriver=SQL SERVER - -[MSSQL_2008] -BaseDriverID=MSSQL -ODBCDriver=SQL Server Native Client 11.0 - -[MSSQL_2012] -BaseDriverID=MSSQL -ODBCDriver=SQL Server Native Client 11.0 - diff --git a/demos_delphi/Demo10_FireDAC/fmMain.dfm b/demos_delphi/Demo10_FireDAC/fmMain.dfm deleted file mode 100644 index f0bc771..0000000 Binary files a/demos_delphi/Demo10_FireDAC/fmMain.dfm and /dev/null differ diff --git a/demos_delphi/Demo10_FireDAC/fmMain.pas b/demos_delphi/Demo10_FireDAC/fmMain.pas deleted file mode 100644 index 6e0607e..0000000 --- a/demos_delphi/Demo10_FireDAC/fmMain.pas +++ /dev/null @@ -1,302 +0,0 @@ -unit fmMain; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - System.Types, System.UITypes, - ComCtrls, ExtCtrls, StdCtrls, PythonEngine, PythonGUIInputOutput, Db, - Grids, DBGrids, Datasnap.DBClient, FireDAC.Stan.Intf, FireDAC.Stan.Option, - FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, - FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.FMXUI.Wait, - FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, - FireDAC.Comp.Client, FireDAC.Comp.DataSet, FireDAC.Comp.UI, - FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs, - WrapDelphi, WrapFireDac, SynEditHighlighter, SynHighlighterPython, SynEdit, - SynEditCodeFolding, sqlTimSt, FireDAC.VCLUI.Wait; - -type - TMain = class(TForm) - RichEdit1: TRichEdit; - Splitter1: TSplitter; - PythonGUIInputOutput: TPythonGUIInputOutput; - modDBFireDac: TPythonModule; - dsrcCustomer: TDataSource; - DataSource2: TDataSource; - Panel6: TPanel; - btnSQLTest: TButton; - cobxConnSQLServer: TComboBox; - Label5: TLabel; - Connection: TFDConnection; - mqSrcTables: TFDMetaInfoQuery; - SynPythonSyn: TSynPythonSyn; - PythonEngine: TPythonEngine; - tblCustomer: TFDTable; - PageControl: TPageControl; - TabSheet1: TTabSheet; - Splitter7: TSplitter; - SynEditScript1: TSynEdit; - Panel7: TPanel; - Label1: TLabel; - Label2: TLabel; - btnExecuteExample1: TButton; - TabSheet2: TTabSheet; - Splitter3: TSplitter; - Panel1: TPanel; - btnExecuteExample2: TButton; - DBGrid1: TDBGrid; - SynEditScript2: TSynEdit; - TabSheet4: TTabSheet; - Splitter4: TSplitter; - Panel3: TPanel; - btnExecuteExample3: TButton; - DBGrid2: TDBGrid; - SynEditScript3: TSynEdit; - TabSheet5: TTabSheet; - Splitter2: TSplitter; - Panel2: TPanel; - btnExecuteExample4: TButton; - SynEditScript4: TSynEdit; - PyDelphiWrapper: TPyDelphiWrapper; - procedure btnExecuteExample1Click(Sender: TObject); - procedure btnExecuteExample2Click(Sender: TObject); - procedure Table1CalcFields(DataSet: TDataSet); - procedure btnExecuteExample4Click(Sender: TObject); - procedure btnExecuteExample3Click(Sender: TObject); - procedure modDBFireDacInitialization(Sender: TObject); - procedure FormShow(Sender: TObject); - procedure btnSQLTestClick(Sender: TObject); - procedure FormDestroy(Sender: TObject); - procedure PageControlChange(Sender: TObject); - private - function DBConnectionClosedCheck(aConnectionDefName: String): Boolean; - public - end; - -var - Main: TMain; - - -implementation - -{$R *.DFM} - - -procedure TMain.FormShow(Sender: TObject); -var - i: Integer; - l_sStr: String; -begin - SynEditScript1.Lines.LoadFromFile( 'Example1.py' ); - SynEditScript2.Lines.LoadFromFile( 'Example2.py' ); - SynEditScript3.Lines.LoadFromFile( 'Example3.py' ); - SynEditScript4.Lines.LoadFromFile( 'Example4.py' ); - // - PageControl.ActivePage := TabSheet1; - // - RichEdit1.Lines.Clear; - cobxConnSQLServer.ItemIndex := -1; - if FileExists('FDDrivers.ini') then begin - FDManager.DriverDefFileName := 'FDDrivers.ini'; - FDManager.DriverDefFileAutoLoad := True; - end - else begin - l_sStr := 'Die Ini-Datei "FDDrivers.ini" existiert nicht!'; - RichEdit1.Lines.Add(l_sStr); - MessageDlg(l_sStr, TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0); - Close; - end; - if FileExists('Demo.ini') then begin - FDManager.ConnectionDefFileName := 'Demo.ini'; - try - FDManager.LoadConnectionDefFile; - FDManager.GetConnectionNames(cobxConnSQLServer.Items); - for i := 0 to cobxConnSQLServer.Items.Count-1 do begin - l_sStr := UpperCase(cobxConnSQLServer.Items[i]); - if (Pos('SQLITE',l_sStr) > 0) and (cobxConnSQLServer.ItemIndex < 0) then begin - cobxConnSQLServer.ItemIndex := i; - break; - end; - end; - except - on E: Exception do begin - l_sStr := 'Exception: ' + E.Message; - RichEdit1.Lines.Add(l_sStr); - MessageDlg(l_sStr, TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0); - end; - end; - end - else begin - l_sStr := 'Die Ini-Datei "Demo.ini" existiert nicht!'; - RichEdit1.Lines.Add(l_sStr); - MessageDlg(l_sStr, TMsgDlgType.mtError, [TMsgDlgBtn.mbOK], 0); - Close; - end; -end; - -procedure TMain.FormDestroy(Sender: TObject); -begin - if Connection.Connected then - Connection.Close; -end; - -procedure TMain.btnSQLTestClick(Sender: TObject); -var - l_sStr, l_sConnName: String; -begin - RichEdit1.Lines.Clear; - l_sConnName := cobxConnSQLServer.Items[cobxConnSQLServer.ItemIndex]; - l_sStr := UpperCase(l_sConnName); - if Pos('ORA',l_sStr) > 0 then begin - RichEdit1.Lines.Add('Oracle Parameter:'); - end - else if Pos('MSSQL',l_sStr) > 0 then begin - RichEdit1.Lines.Add('MS SQL Server Parameter:'); - end - else if Pos('SQLITE',l_sStr) > 0 then begin - RichEdit1.Lines.Add('SQLite Parameter:'); - end - else begin - RichEdit1.Lines.Add('Unkown database type!'); - exit; - end; - if self.DBConnectionClosedCheck(l_sConnName) then - RichEdit1.Lines.Add('Database was connected!') - else - RichEdit1.Lines.Add('Database was not connected!'); -end; - -function TMain.DBConnectionClosedCheck(aConnectionDefName: String): Boolean; -var - l_sStr: String; - l_oDef: IFDStanConnectionDef; -begin - Result := True; - if Connection.Connected then - Connection.Close; - if Connection.ConnectionDefName <> aConnectionDefName then begin - l_oDef := FDManager.ConnectionDefs.ConnectionDefByName(aConnectionDefName); - Connection.Params.Clear; - Connection.Params.AddStrings(l_oDef.Params); - Connection.ConnectionDefName := aConnectionDefName; - // - try - Connection.Connected := True; - if Connection.Connected then begin - Result := True; - Connection.Close; - end; - except - on E: Exception do begin - Result := False; - l_sStr := 'Exception: ' + E.Message; - RichEdit1.Lines.Add(l_sStr); - end; - end; - end; -end; - -procedure TMain.Table1CalcFields(DataSet: TDataSet); -begin - Dataset.FieldByName('Demo').AsString := Dataset.FieldByName('State').AsString + ' - ' + - Dataset.FieldByName('Zip').AsString; -end; - -procedure TMain.modDBFireDacInitialization(Sender: TObject); -begin -// pyDBFireDac.g_oDBModule := Sender as TPythonModule; - with Sender as TPythonModule do begin - with DocString do begin - Add( 'This module contains several Object Types that' ); - Add( 'will let you work with FireDAC and access' ); - Add( 'a database.' ); - Add( '' ); - Add( 'CreateDBTable() -> creates a TFDTable instance' ); - Add( 'CreateDBQuery() -> creates a TFDQuery instance' ); - end; - with Errors.Add do begin - Name := 'DBError'; - ErrorType := etClass; // <- !!! Must ... - end; - end; -end; - -procedure TMain.PageControlChange(Sender: TObject); -begin - if PageControl.TabIndex = 1 then begin - // Example2 - if not tblCustomer.Active then - tblCustomer.Active := True; - end - else begin - if tblCustomer.Active then - tblCustomer.Active := False; - end; -end; - -procedure TMain.btnExecuteExample1Click(Sender: TObject); -var - l_sConnName: String; -begin - l_sConnName := cobxConnSQLServer.Items[cobxConnSQLServer.ItemIndex]; - if self.DBConnectionClosedCheck(l_sConnName) then begin - with GetPythonEngine do begin - ExecStrings( SynEditScript1.Lines ); - end; - end; -end; - -procedure TMain.btnExecuteExample2Click(Sender: TObject); -var - pyObj : PPyObject; -begin - // Instantiate a new Python object TPyTable - pyObj := PyDelphiWrapper.Wrap(tblCustomer); - with GetPythonEngine do begin - // Define a new variable "T" in the DB module - modDBFireDac.SetVar( 'T', pyObj ); - Py_XDecRef(pyObj); - // Excecute the script - ExecStrings( SynEditScript2.Lines ); - end; -end; - -procedure TMain.btnExecuteExample3Click(Sender: TObject); -var - pyObj : PPyObject; - l_oTable: TFDTable; -begin - // connect the Datasource2 to the Python Table - l_oTable := TFDTable.Create(Self); - l_oTable.TableName := 'Customer'; - l_oTable.Connection := Connection; - Datasource2.Dataset := l_oTable; - l_oTable.Open(); - - pyObj := PyDelphiWrapper.Wrap(l_oTable, soOwned); - with GetPythonEngine do begin - // Define a new variable "T" in the DB module - modDBFireDac.SetVar( 'T', pyObj ); - Py_XDecRef(pyObj); - // Excecute the script - ExecStrings( SynEditScript3.Lines ); - end; -end; - -procedure TMain.btnExecuteExample4Click(Sender: TObject); -var - l_sConnName: String; -begin - l_sConnName := cobxConnSQLServer.Items[cobxConnSQLServer.ItemIndex]; - if self.DBConnectionClosedCheck(l_sConnName) then begin - with PythonEngine do - ExecStrings( SynEditScript4.Lines ); - end; -end; - -initialization - ReportMemoryLeaksOnShutdown := True; -finalization - CheckSynchronize; -end. - diff --git a/demos_delphi/Demo11/SortThds.pas b/demos_delphi/Demo11/SortThds.pas deleted file mode 100644 index a6dc02b..0000000 --- a/demos_delphi/Demo11/SortThds.pas +++ /dev/null @@ -1,141 +0,0 @@ -unit SortThds; - -{$I Definition.Inc} - -interface - -uses - Classes, - Graphics, ExtCtrls, - PythonEngine; - -type - -{ TSortThread } - - PSortArray = ^TSortArray; - TSortArray = array[0..MaxInt div SizeOf(Integer) - 1] of Integer; - - TSortThread = class(TPythonThread) - private - FModule: TPythonModule; - FScript: TStrings; - FBox: TPaintBox; - FSortArray: PSortArray; - FSize: Integer; - FI, FJ: Integer; - fpyfuncname: string; - - procedure DoVisualSwap; - function getvalue(i: integer): integer; - protected - procedure ExecuteWithPython; override; - public - property value[i: integer]: integer read getvalue; default; - - constructor Create( AThreadExecMode: TThreadExecMode; script: TStrings; - module: TPythonModule; apyfuncname: string; - Box: TPaintBox; var SortArray: array of Integer); - - procedure VisualSwap(I, J: Integer); - end; - -procedure PaintLine(Canvas: TCanvas; I, Len: Integer); - -implementation - -procedure PaintLine(Canvas: TCanvas; I, Len: Integer); -begin - Canvas.PolyLine([Point(0, I * 2 + 1), Point(Len, I * 2 + 1)]); -end; - -{ TSortThread } - -constructor TSortThread.Create( AThreadExecMode: TThreadExecMode; script: TStrings; - module: TPythonModule; apyfuncname: string; - Box: TPaintBox; var SortArray: array of Integer); -begin - fpyfuncname := apyfuncname; - fScript := script; - FModule := module; - FBox := Box; - FSortArray := @SortArray; - FSize := High(SortArray) - Low(SortArray) + 1; - FreeOnTerminate := True; - ThreadExecMode := AThreadExecMode; - inherited Create(False); -end; - -{ Since DoVisualSwap uses a VCL component (i.e., the TPaintBox) it should never - be called directly by this thread. DoVisualSwap should be called by passing - it to the Synchronize method which causes DoVisualSwap to be executed by the - main VCL thread, avoiding multi-thread conflicts. See VisualSwap for an - example of calling Synchronize. } - -procedure TSortThread.DoVisualSwap; -type - pinteger = ^integer; -var t: integer; - pi,pj: pinteger; -begin - with FBox do - begin - Canvas.Pen.Color := clBtnFace; - pi := @(FSortArray^[FI]); - pj := @(FSortArray^[FJ]); - PaintLine(Canvas, FI, pi^); - PaintLine(Canvas, FJ, pj^); - Canvas.Pen.Color := clRed; - PaintLine(Canvas, FI, pj^); - PaintLine(Canvas, FJ, pi^); - - t := pi^; - pi^ := pj^; - pj^ := t; - end; -end; - -{ VisusalSwap is a wrapper on DoVisualSwap making it easier to use. The - parameters are copied to instance variables so they are accessable - by the main VCL thread when it executes DoVisualSwap } - -procedure TSortThread.VisualSwap(I, J: Integer); -begin - Py_BEGIN_ALLOW_THREADS; - if Terminated then - raise EPythonError.Create( 'Pythonthread terminated'); - FI := I; - FJ := J; - Synchronize(DoVisualSwap); - Py_END_ALLOW_THREADS; -end; - -{ The Execute method is called when the thread starts } - -procedure TSortThread.ExecuteWithPython; -var pyfunc: PPyObject; -begin - with GetPythonEngine do - begin - if Assigned(FModule) and (ThreadExecMode = emNewInterpreter) then - FModule.InitializeForNewInterpreter; - if Assigned(fScript) then - ExecStrings(fScript); - pyfunc := FindFunction( ExecModule, fpyfuncname); - if Assigned(pyfunc) then - try - EvalFunction(pyfunc,[NativeInt(self),0,FSize]); - finally - Py_DecRef(pyfunc); - end; - end; -end; - -function TSortThread.getvalue(i: integer): integer; -begin - if Terminated then - raise EPythonError.Create( 'Pythonthread terminated'); - Result := FSortArray^[i]; -end; - -end. diff --git a/demos_delphi/Demo11/ThSort.dfm b/demos_delphi/Demo11/ThSort.dfm deleted file mode 100644 index 19bcd53..0000000 Binary files a/demos_delphi/Demo11/ThSort.dfm and /dev/null differ diff --git a/demos_delphi/Demo11/ThSort.pas b/demos_delphi/Demo11/ThSort.pas deleted file mode 100644 index 28b3009..0000000 --- a/demos_delphi/Demo11/ThSort.pas +++ /dev/null @@ -1,230 +0,0 @@ -unit ThSort; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - ExtCtrls, StdCtrls, - PythonEngine; - -type - TThreadSortForm = class(TForm) - StartBtn: TButton; - BubbleSortBox: TPaintBox; - SelectionSortBox: TPaintBox; - QuickSortBox: TPaintBox; - Label1: TLabel; - Bevel1: TBevel; - Bevel2: TBevel; - Bevel3: TBevel; - Label2: TLabel; - Label3: TLabel; - PythonMemo: TMemo; - PythonEngine1: TPythonEngine; - Start2Btn: TButton; - LoadBtn: TButton; - PythonDialog: TOpenDialog; - SaveDialog: TSaveDialog; - SaveBtn: TButton; - SortModule: TPythonModule; - procedure BubbleSortBoxPaint(Sender: TObject); - procedure SelectionSortBoxPaint(Sender: TObject); - procedure QuickSortBoxPaint(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure StartBtnClick(Sender: TObject); - procedure Start2BtnClick(Sender: TObject); - procedure LoadBtnClick(Sender: TObject); - procedure SaveBtnClick(Sender: TObject); - procedure SortModuleInitialization(Sender: TObject); - procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); - private - OwnThreadState: PPyThreadState; - ThreadsRunning: Integer; - procedure RandomizeArrays; - procedure ThreadDone(Sender: TObject); - procedure InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings); - - function SortModule_GetValue( pself, args : PPyObject ) : PPyObject; cdecl; - function SortModule_Swap( pself, args : PPyObject ) : PPyObject; cdecl; - public - procedure PaintArray(Box: TPaintBox; const A: array of Integer); - end; - -var - ThreadSortForm: TThreadSortForm; - -implementation - -uses SortThds; - -{$R *.dfm} - -type - PSortArray = ^TSortArray; - TSortArray = array[0..176] of Integer; - -var - ArraysRandom: Boolean; - BubbleSortArray, SelectionSortArray, QuickSortArray: TSortArray; - -{ TThreadSortForm } - -procedure TThreadSortForm.PaintArray(Box: TPaintBox; const A: array of Integer); -var - I: Integer; -begin - with Box do - begin - Canvas.Pen.Color := clRed; - for I := Low(A) to High(A) do PaintLine(Canvas, I, A[I]); - end; -end; - -procedure TThreadSortForm.BubbleSortBoxPaint(Sender: TObject); -begin - PaintArray(BubbleSortBox, BubbleSortArray); -end; - -procedure TThreadSortForm.SelectionSortBoxPaint(Sender: TObject); -begin - PaintArray(SelectionSortBox, SelectionSortArray); -end; - -procedure TThreadSortForm.QuickSortBoxPaint(Sender: TObject); -begin - PaintArray(QuickSortBox, QuickSortArray); -end; - -procedure TThreadSortForm.FormCreate(Sender: TObject); -begin - RandomizeArrays; -end; - -procedure TThreadSortForm.InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings); -begin - RandomizeArrays; - ThreadsRunning := 3; - with GetPythonEngine do - begin - OwnThreadState := PyEval_SaveThread; - - with TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc1', - BubbleSortBox, BubbleSortArray) do - OnTerminate := ThreadDone; - with TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc2', - SelectionSortBox, SelectionSortArray) do - OnTerminate := ThreadDone; - with TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc3', - QuickSortBox, QuickSortArray) do - OnTerminate := ThreadDone; - end; - - StartBtn.Enabled := False; - Start2Btn.Enabled := False; -end; - -procedure TThreadSortForm.Start2BtnClick(Sender: TObject); -begin - with GetPythonEngine do - begin - ExecStrings(PythonMemo.Lines); - self.InitThreads(emNewState,nil); - end; -end; - -procedure TThreadSortForm.StartBtnClick(Sender: TObject); -begin - InitThreads(emNewInterpreter,PythonMemo.Lines); -//PythonEngine1.ExecStrings(PythonMemo.Lines); -end; - -procedure TThreadSortForm.LoadBtnClick(Sender: TObject); -begin - with PythonDialog do if Execute then - PythonMemo.Lines.LoadFromFile(FileName); -end; - -procedure TThreadSortForm.SaveBtnClick(Sender: TObject); -begin - with SaveDialog do if Execute then - PythonMemo.Lines.SaveToFile(FileName); -end; - -procedure TThreadSortForm.RandomizeArrays; -var - I: Integer; -begin - if not ArraysRandom then - begin - Randomize; - for I := Low(BubbleSortArray) to High(BubbleSortArray) do - BubbleSortArray[I] := Random(170); - SelectionSortArray := BubbleSortArray; - QuickSortArray := BubbleSortArray; - ArraysRandom := True; - Repaint; - end; -end; - -procedure TThreadSortForm.ThreadDone(Sender: TObject); -begin - Dec(ThreadsRunning); - if ThreadsRunning = 0 then - begin - GetPythonEngine.PyEval_RestoreThread(OwnThreadState); - StartBtn.Enabled := True; - Start2Btn.Enabled := True; - ArraysRandom := False; - end; -end; - -function TThreadSortForm.SortModule_GetValue( pself, args : PPyObject ) : PPyObject; cdecl; -var psort,index: integer; -begin - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'ii',@psort, @index) <> 0 then - begin - Result := PyInt_FromLong(TSortThread(psort)[index]); - end else - Result := nil; - end; -end; - -function TThreadSortForm.SortModule_Swap( pself, args : PPyObject ) : PPyObject; cdecl; -var psort,i,j: integer; -begin - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'iii',@psort, @i, @j) <> 0 then - begin - TSortThread(psort).VisualSwap(i,j); - Result := ReturnNone; - end else - Result := nil; - end; -end; - -procedure TThreadSortForm.SortModuleInitialization(Sender: TObject); -begin - with Sender as TPythonModule do - begin - AddDelphiMethod( 'getvalue', - SortModule_GetValue, - 'GetValue(handle,index)' ); - AddDelphiMethod( 'swap', - SortModule_Swap, - 'swap(handle,index1,index2)'); - end; -end; - -procedure TThreadSortForm.FormCloseQuery(Sender: TObject; - var CanClose: Boolean); -begin - CanClose := ThreadsRunning = 0; -end; - -end. diff --git a/demos_delphi/Demo11/ThrdDemo.dpr b/demos_delphi/Demo11/ThrdDemo.dpr deleted file mode 100644 index 6267980..0000000 --- a/demos_delphi/Demo11/ThrdDemo.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program ThrdDemo; - -{$I Definition.Inc} - -uses - Forms, - ThSort in 'ThSort.pas' {ThreadSortForm}, - SortThds in 'SortThds.pas'; - -{$R *.res} - -begin - Application.CreateForm(TThreadSortForm, ThreadSortForm); - Application.Run; -end. diff --git a/demos_delphi/Demo11/ThrdDemo.dproj b/demos_delphi/Demo11/ThrdDemo.dproj deleted file mode 100644 index 74c3d38..0000000 --- a/demos_delphi/Demo11/ThrdDemo.dproj +++ /dev/null @@ -1,102 +0,0 @@ - - - {FA5D85B3-B6D3-47F9-A4F9-482E5482F142} - ThrdDemo.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - ThrdDemo.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
ThreadSortForm
-
- - - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - ThrdDemo.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo11/ThrdDemo.res b/demos_delphi/Demo11/ThrdDemo.res deleted file mode 100644 index 8d706e2..0000000 Binary files a/demos_delphi/Demo11/ThrdDemo.res and /dev/null differ diff --git a/demos_delphi/Demo11/test.py b/demos_delphi/Demo11/test.py deleted file mode 100644 index a52c520..0000000 --- a/demos_delphi/Demo11/test.py +++ /dev/null @@ -1,33 +0,0 @@ -from SortModule import getvalue,swap - -def SortFunc1(handle, low, high): - for i in range(low, high): - for j in range(low+1,high): - if getvalue(handle,j-1) > getvalue(handle,j): - swap(handle,j-1,j) - -def SortFunc2(handle,low,high): - for i in range(low,high-1): - for j in range(i+1,high): - if getvalue(handle,i) > getvalue(handle,j): - swap(handle,i,j) - -def SortFunc3(handle,low,high): - Lo = low - Hi = high-1 - Mid = getvalue(handle,(Lo+Hi) / 2) - while 1: - while getvalue(handle,Lo) < Mid: - Lo = Lo + 1 - while getvalue(handle,Hi) > Mid: - Hi = Hi - 1 - if Lo <= Hi: - swap(handle,Lo,Hi) - Lo = Lo + 1 - Hi = Hi - 1 - if Lo > Hi: - break - if Hi > low: - SortFunc3(handle,low,Hi+1) - if Lo < high-1: - SortFunc3(handle,Lo,high) diff --git a/demos_delphi/Demo13/Demo13.dpr b/demos_delphi/Demo13/Demo13.dpr deleted file mode 100644 index f732346..0000000 --- a/demos_delphi/Demo13/Demo13.dpr +++ /dev/null @@ -1,16 +0,0 @@ -// JCL_DEBUG_EXPERT_GENERATEJDBG OFF -// JCL_DEBUG_EXPERT_INSERTJDBG OFF -// JCL_DEBUG_EXPERT_DELETEMAPFILE OFF -program Demo13; - -uses - Forms, - fmMain in 'fmMain.pas' {Main}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TMain, Main); - Application.Run; -end. diff --git a/demos_delphi/Demo13/Demo13.dproj b/demos_delphi/Demo13/Demo13.dproj deleted file mode 100644 index 935dabf..0000000 --- a/demos_delphi/Demo13/Demo13.dproj +++ /dev/null @@ -1,104 +0,0 @@ - - - {31F0DC69-484B-425F-A59F-C06840DF2EFC} - Demo13.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - Demo13.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Main
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Demo13.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1032 - 1253 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - 12 - -
diff --git a/demos_delphi/Demo13/Demo13.res b/demos_delphi/Demo13/Demo13.res deleted file mode 100644 index cfdbb79..0000000 Binary files a/demos_delphi/Demo13/Demo13.res and /dev/null differ diff --git a/demos_delphi/Demo13/Example1.py b/demos_delphi/Demo13/Example1.py deleted file mode 100644 index 8ead9bf..0000000 --- a/demos_delphi/Demo13/Example1.py +++ /dev/null @@ -1,67 +0,0 @@ -import DB -import DBTables -True = 1 -False = 0 - -# Create and open the table -T = DBTables.CreateTTable() -T.DatabaseName = "DBDemos" -T.TableName = "customer.db" -T.Active = True #or use T.Open() - -# Display columns -print "Columns: ", T.FieldNamesAsTuple() - -LastInvoiceDate = T.FieldByName("LastInvoiceDate") - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a list - A = [] - for i in xrange( T.FieldCount ): - A.append( T.Fields(i).Value ) - # Print the current record number and the list - print "Rec.", T.RecNo, ":", A - # Edit record - T.Edit() - T.FieldByName("TaxRate").Value = 2.5 - # Increments date by one day - D = LastInvoiceDate.Value - if D[2] < 28: - D2 = D[:2]+(D[2]+1,)+D[3:] # this is tuple arithmetic ! - else: - D2 = D[:2]+(1,)+D[3:] # this is tuple arithmetic ! - LastInvoiceDate.Value = D2 - T.Post() - # Get next record - T.Next() - -# Print some fields by their names -F = T.FieldByName("Company") -print F, F.FieldName, "=", F.Value - -# Use the TFields and print the list of companies -T.First() -while not T.EOF: - print F.AsString - T.Next() - -# Print the fields as a dictionary -D = T.FieldsAsDict() -print D -print D["Company"] - -T.Close() -T.TableName = "Dummy.db" -try: - T.Open() -except DB.DBError: - print "could not open table ", T.TableName - -#delete fields -del F -del LastInvoiceDate - -# delete the table -del T diff --git a/demos_delphi/Demo13/Example2.py b/demos_delphi/Demo13/Example2.py deleted file mode 100644 index b3caa1b..0000000 --- a/demos_delphi/Demo13/Example2.py +++ /dev/null @@ -1,89 +0,0 @@ -import DB -import DBTables -True = 1 -False = 0 - -# Get the TTable object associated to -# the delphi table displayed on right -# It is done when you click on Execute -T = DBTables.T - -# Display columns -print "Columns: " -for i in T.FieldNamesAsTuple(): - print " ", i - -T.CancelRange() -# For each record of the table -for i in T: - print "Rec.", T.RecNo, ":", i - -# Print some fields by their names -print T.FieldByName("Company") - -# check state -if not T.State in [DB.dsEdit, DB.dsInsert]: - print "Table is not edited" - -# access the table like an array -print T[10] # Row 11 -print T[10] [1] # second field of row 11 - -# locate a record -if T.Locate( "City;State", ["Largo","FL"], [] ): - print "Found rec:", T.RecNo -if T.Locate( "Company", "BLUE SPORTS", [DB.loCaseInsensitive] ): - print "Found rec:", T.RecNo -if T.Locate( "Company", "ISLAND", [DB.loCaseInsensitive, DB.loPartialKey] ): - print "Found rec:", T.RecNo - -# lookup a record -print T.Lookup( "City;State", ["Largo","FL"], "CustNo;Company" ) - -# define a range -print "-----------------------------------------------------------" -print "Indexes:", T.GetIndexNames() -T.IndexName = "ByCompany" -T.SetRange( ["Unisco"], ["Unisco"] ) -for i in T: - print "Rec.", T.RecNo, ":", i -T.CancelRange() - -print "-----------------------------------------------------------" -# Find a record -if T.FindKey( ['Unisco'] ): - print "Unisco found !" -else: - print "Could not find Unisco !" - -# Find the nearest record -T.FindNearest( ['Ocean'] ) -print "Find nearest Ocean :", T.FieldsAsTuple() - -# Print all doc strings of an instance's methods -def PrintDocOf( inst ): - print "--------------------- Type ", type(inst).__name__, "---------------------" - if type(inst).__doc__: - print type(inst).__doc__ - print "Methods:" - for i in dir(inst): - print inst - doc = getattr(inst, i).__doc__ - if doc: - print " ", doc - print - print "Properties:" - for i in inst.__properties__: - print " ", i -print "-----------------------------------------------------------" -print "Documentation:" -print -print "Module DBTables:" -print DBTables.__doc__ -PrintDocOf(T) -print "-----------------------------------------------------------" -print "Property values of", T -for i in T.__members__: # or T.__properties__ - print i, "=", getattr(T, i) - - diff --git a/demos_delphi/Demo13/Example3.py b/demos_delphi/Demo13/Example3.py deleted file mode 100644 index 55e48b5..0000000 --- a/demos_delphi/Demo13/Example3.py +++ /dev/null @@ -1,39 +0,0 @@ -import DB -import DBTables -True = 1 -False = 0 - -# Get the TTable object created by Delphi -# and connected to a Delphi Datasource -# It is done when you click on Execute -T = DBTables.T -# Select and open a table -T.DatabaseName = "DBDemos" -T.TableName = "customer.db" -T.Open() - -# Display columns -print "Columns: " -for i in T.FieldNamesAsTuple(): - print " ", i - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a tuple - A = T.FieldsAsTuple() - # Print the current record number and the tuple - print "Rec.", T.RecNo, ":", A - # Get next record - T.Next() - -# Print some fields by their names -print T.FieldByName("Company") - -# check state -if not T.State in [DB.dsEdit, DB.dsInsert]: - print "Table is not edited" - -# clean up -del T -del DBTables.T diff --git a/demos_delphi/Demo13/Example4.py b/demos_delphi/Demo13/Example4.py deleted file mode 100644 index 3030668..0000000 --- a/demos_delphi/Demo13/Example4.py +++ /dev/null @@ -1,40 +0,0 @@ -import DB -import DBTables -True = 1 -False = 0 - -# Create and open the table -T = DBTables.CreateTQuery() -T.DatabaseName = "DBDemos" -T.SQL = [ - "SELECT *", - " FROM customer.db" - ] -T.Open() - -# Display columns -print "Columns: ", T.FieldNamesAsTuple() - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a list - A = [] - for i in xrange( T.FieldCount ): - A.append( T.Fields(i).AsString ) - # Print the current record number and the list - print "Rec.", T.RecNo, ":", A - # Get next record - T.Next() - -# Print some fields by their names -print T.FieldByName("Company") - -# Print the fields as a dictionary -D = T.FieldsAsDict() -print D -print D["Company"] - -# delete the table -del T - diff --git a/demos_delphi/Demo13/Example5.py b/demos_delphi/Demo13/Example5.py deleted file mode 100644 index 0267567..0000000 --- a/demos_delphi/Demo13/Example5.py +++ /dev/null @@ -1,113 +0,0 @@ -import DB -import DBTables -import pyio - -True = 1 -False = 0 - -# Misc -def DisplayTypesStats(*args): - for i in apply(pyio.GetTypesStats, args): # Requested types - #for i in pyio.GetTypesStats('TTable', 'TField'): # Only the types TTable and TField - print "--------------------------------------------------------------------------------" - print "TYPE ", i[0] - print " Instance count :", i[1] - print " Create Hits :", i[2] - print " Delete Hits :", i[3] - print "--------------------------------------------------------------------------------" - -# Event functions - -def AfterScroll(Dataset): - print "---------> Scrolled to rec #"+str(Dataset.RecNo)+" <--------------" - -# Event methods - -# WARNING : -# --------- -# if you store the TTable in your C instance, and if you use events, -# you must be aware of the reference counting mechanism, and its -# failure on circular references: -# c = C(): c refcount = 1 -# c.T = CreateTTable(): c.T refcount = 1 -# c.T.OnAfterOpen = c.OnAfterOpen: c refcount = 2 -# del c: c refcount = 1 and you loose any reference on your c instance -# which still contains a TTable. -# so if you want to avoid the leaking, then you must clear the events -# before you delete the instance: -# c.T.OnAfterOpen = None: c refcount = 1 -# del c: c refcount = 0 -> c is deleted -# -# Try to use try..finally constructs, in order to avoid -# the leaking if an exception is raised before you can free the -# resources. -# -# Don't forget to close the TTable, if you want to get the Before/After -# close events, because when destroying a TTable, we first clear all -# events. But that's the case with the Delphi behaviour too. - -class C: - def __init__(Self): - # Create and open the table - Self.T = DBTables.CreateTTable() - Self.T.DatabaseName = "DBDemos" - Self.T.TableName = "customer.db" - Self.T.AfterScroll = AfterScroll # a global function - Self.T.BeforeOpen = Self.BeforeOpen # a method of the c instance of class C - Self.T.AfterOpen = Self.AfterOpen # a method of the c instance of class C - Self.T.BeforeClose = Self.BeforeClose # a method of the c instance of class C - Self.T.AfterClose = Self.AfterClose # a method of the c instance of class C - Self.T.OnFilterRecord = Self.OnFilterRecord # a method of the c instance of class C - Self.T.Filtered = True - Self.T.Open() - - def __del__(Self): - print "c instance deleted" - - def Free(Self): - Self.T.Close() - del Self.T - - def BeforeOpen(Self, Dataset): - Self.Name = Dataset.DatabaseName + ":" + Dataset.TableName - print "Before Open of ", Self.Name - - def AfterOpen(Self, Dataset): - print "After Open of ", Self.Name - - def BeforeClose(Self, Dataset): - print "Before close of ", Self.Name - - def AfterClose(Self, Dataset): - print "After Close of ", Self.Name - - def OnFilterRecord(Self, Dataset, Accept): - # Accept is var argument in Delphi, but in Python you can't - # change a function's argument. So we use a special object - # TVarArg which contains a single property : Value - Accept.Value = Dataset.FieldByName("Company").AsString > "E" - if not Accept.Value: - print "$$$$$ Rejected record:", Dataset.FieldsAsTuple() - -DisplayTypesStats() -c = C() -DisplayTypesStats() - -# don't use a "for i in c.T" expression with a filtered table, -# because the BDE will filter the whole table for each movement, -# in order to get the RecordCount. - -try: - c.T.First() - while not c.T.EOF: - print c.T.FieldsAsTuple() - c.T.Next() - -finally: - c.Free() - del c - -DisplayTypesStats() -#DisplayTypesStats('TField', 'TTable') - - diff --git a/demos_delphi/Demo13/Example6.py b/demos_delphi/Demo13/Example6.py deleted file mode 100644 index d7ca6db..0000000 --- a/demos_delphi/Demo13/Example6.py +++ /dev/null @@ -1,91 +0,0 @@ -import DB -import DBTables -True = 1 -False = 0 - -# Here's how you can use a Proxy class -# in order to inherit from any Python object -# like our TTable or TQuery ! - -class Proxy: - def __init__(Self, Object): - Self.__object__ = Object - - def __getattr__(Self, Key): - return getattr(Self.__dict__['__object__'], Key) - - def __setattr__(Self, Key, Value): - if Key == "__object__": - Self.__dict__[Key] = Value - elif hasattr(Self.__object__, Key): - return setattr(Self.__object__, Key, Value) - else: - Self.__dict__[Key] = Value - - def __len__(Self): - return len(Self.__object__) - - def __getitem__(Self, Item): - return Self.__object__[Item] - -class TMyQuery(Proxy): - def __init__(Self): - Proxy.__init__(Self, DBTables.CreateTQuery() ) - -class TMySubQuery(TMyQuery): - def First(Self): - print "First requested on Query" - Self.__object__.First() - - -# Create and open the table -T = TMySubQuery() -T.DatabaseName = "DBDemos" -T.SQL = [ - "SELECT *", - " FROM customer.db" - ] -T.Open() - -# Display columns -print "Columns: ", T.FieldNamesAsTuple() - -# Test of method override -T.Last() -print "RecNo =", T.RecNo -T.First() -print "RecNo =", T.RecNo - -# For each record of the table -T.First() -while not T.EOF: - # Get all the fields in a list - A = [] - for i in xrange( T.FieldCount ): - A.append( T.Fields(i).AsString ) - # Print the current record number and the list - print "Rec.", T.RecNo, ":", A - # Get next record - T.Next() - -# Print some fields by their names -print T.FieldByName("Company") - -# Print the fields as a dictionary -D = T.FieldsAsDict() -print D["Company"] - -# Iterate our class -print T -for i in T: - print i - -print T - -# Define new instance vars -T.Test1 = 3 -print T.Test1, T.DatabaseName - -# delete the table -del T - diff --git a/demos_delphi/Demo13/fmMain.dfm b/demos_delphi/Demo13/fmMain.dfm deleted file mode 100644 index ac23396..0000000 Binary files a/demos_delphi/Demo13/fmMain.dfm and /dev/null differ diff --git a/demos_delphi/Demo13/fmMain.pas b/demos_delphi/Demo13/fmMain.pas deleted file mode 100644 index ab798b5..0000000 --- a/demos_delphi/Demo13/fmMain.pas +++ /dev/null @@ -1,174 +0,0 @@ -unit fmMain; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - ComCtrls, ExtCtrls, StdCtrls, PythonEngine, PythonGUIInputOutput, Db, - DBTables, Grids, DBGrids, PythonDatabase; - -type - TMain = class(TForm) - RichEdit1: TRichEdit; - PageControl1: TPageControl; - Splitter1: TSplitter; - TabSheet1: TTabSheet; - TabSheet2: TTabSheet; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo1: TMemo; - Button1: TButton; - Table1: TTable; - Memo2: TMemo; - Panel1: TPanel; - DBGrid1: TDBGrid; - Button2: TButton; - DataSource1: TDataSource; - TabSheet3: TTabSheet; - Table1CustNo: TFloatField; - Table1Company: TStringField; - Table1Addr1: TStringField; - Table1Addr2: TStringField; - Table1City: TStringField; - Table1State: TStringField; - Table1Zip: TStringField; - Table1Country: TStringField; - Table1Phone: TStringField; - Table1FAX: TStringField; - Table1TaxRate: TFloatField; - Table1Contact: TStringField; - Table1LastInvoiceDate: TDateTimeField; - Table1Demo: TStringField; - Label1: TLabel; - TabSheet4: TTabSheet; - TabSheet5: TTabSheet; - Memo4: TMemo; - Splitter2: TSplitter; - Panel2: TPanel; - Button3: TButton; - Label2: TLabel; - Splitter3: TSplitter; - Memo3: TMemo; - Splitter4: TSplitter; - Panel3: TPanel; - Button4: TButton; - DBGrid2: TDBGrid; - DataSource2: TDataSource; - TreeView1: TTreeView; - TabSheet6: TTabSheet; - Label3: TLabel; - Memo5: TMemo; - Panel4: TPanel; - Button5: TButton; - Splitter5: TSplitter; - PythonDatabase1: TPythonDatabase; - TabSheet7: TTabSheet; - Memo6: TMemo; - Splitter6: TSplitter; - Panel5: TPanel; - Button6: TButton; - Label4: TLabel; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Table1CalcFields(DataSet: TDataSet); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure Button5Click(Sender: TObject); - procedure Button6Click(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - -var - Main: TMain; - -implementation -uses pyDB, pyDBTables; -{$R *.DFM} - -procedure TMain.Button1Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo1.Lines ); -end; - -procedure TMain.Button2Click(Sender: TObject); -var - tbl : TPyTable; - obj : PPyObject; -begin - // Instantiate a new Python object TPyTable - obj := gTableType.CreateInstance; - tbl := PythonToDelphi(obj) as TPyTable; - // Attach our Delphi table to the Python object - tbl.SetDataset( Table1, False ); - with GetPythonEngine do - begin - // Define a new variable "T" in the DB module - gDBTablesModule.SetVar( 'T', obj ); - Py_XDecRef(obj); - // Excecute the script - ExecStrings( memo2.Lines ); - end; -end; - -procedure TMain.Table1CalcFields(DataSet: TDataSet); -begin - Dataset.FieldByName('Demo').AsString := Dataset.FieldByName('State').AsString + ' - ' + - Dataset.FieldByName('Zip').AsString; -end; - -procedure TMain.Button3Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo4.Lines ); -end; - -procedure TMain.Button4Click(Sender: TObject); -var - tbl : TPyTable; - obj : PPyObject; -begin - // Instantiate a new Python object TPyTable - obj := gTableType.CreateInstance; - tbl := PythonToDelphi(obj) as TPyTable; - // connect the Datasource2 to the Python TTable - Datasource2.Dataset := tbl.Table; - with GetPythonEngine do - begin - // Define a new variable "T" in the DB module - gDBTablesModule.SetVar( 'T', obj ); - Py_XDecRef(obj); - // Excecute the script - ExecStrings( memo3.Lines ); - end; -end; - -procedure TMain.FormCreate(Sender: TObject); -begin - Memo1.Lines.LoadFromFile( 'Example1.py' ); - Memo2.Lines.LoadFromFile( 'Example2.py' ); - Memo3.Lines.LoadFromFile( 'Example3.py' ); - Memo4.Lines.LoadFromFile( 'Example4.py' ); - Memo5.Lines.LoadFromFile( 'Example5.py' ); - Memo6.Lines.LoadFromFile( 'Example6.py' ); - PageControl1.ActivePage := TabSheet1; -end; - -procedure TMain.Button5Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo5.Lines ); -end; - -procedure TMain.Button6Click(Sender: TObject); -begin - with PythonEngine1 do - ExecStrings( Memo6.Lines ); -end; - -end. - diff --git a/demos_delphi/Demo14/Project1.dpr b/demos_delphi/Demo14/Project1.dpr deleted file mode 100644 index 513a1dd..0000000 --- a/demos_delphi/Demo14/Project1.dpr +++ /dev/null @@ -1,13 +0,0 @@ -program Project1; - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo14/Project1.res b/demos_delphi/Demo14/Project1.res deleted file mode 100644 index 10ba0ac..0000000 Binary files a/demos_delphi/Demo14/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo14/Unit1.dfm b/demos_delphi/Demo14/Unit1.dfm deleted file mode 100644 index 4a3f8e6..0000000 Binary files a/demos_delphi/Demo14/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo14/Unit1.pas b/demos_delphi/Demo14/Unit1.pas deleted file mode 100644 index f1f1e8a..0000000 --- a/demos_delphi/Demo14/Unit1.pas +++ /dev/null @@ -1,38 +0,0 @@ -unit Unit1; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - PythonEngine, StdCtrls, ExtCtrls, ComCtrls, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - PythonEngine1: TPythonEngine; - Panel1: TPanel; - Button1: TButton; - RichEdit1: TRichEdit; - PythonGUIInputOutput1: TPythonGUIInputOutput; - procedure Button1Click(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - -var - Form1: TForm1; - -implementation - -{$R *.DFM} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( memo1.Lines ); -end; - - -end. diff --git a/demos_delphi/Demo14/database.dpr b/demos_delphi/Demo14/database.dpr deleted file mode 100644 index 3fe316f..0000000 --- a/demos_delphi/Demo14/database.dpr +++ /dev/null @@ -1,24 +0,0 @@ -library database; - -{ Remarque importante � propos de la gestion m�moire des DLL : ShareMem doit - �tre la premi�re unit� dans la clause USES de votre biblioth�que, - ET dans la clause USES de votre projet (s�lectionnez Voir-Source du projet) - si vos DLLs exportent des proc�dures ou des fonctions passant en param�tre - des cha�nes ou des r�sultats de fonction. - Ceci s'applique � toutes les cha�nes pass�es par ou � vos DLLs - m�mes celles - qui sont imbriqu�es dans des enregistrements ou des classes. ShareMem est - l'unit� d'interface au gestionnaire de m�moire partag�e DELPHIMM.DLL, qui - doit �tre d�ploy� avec vos propres DLLs. Pour �viter l'emploi de DELPHIMM.DLL, - passez vos cha�nes en utilisant des param�tres PAnsiChar ou ShortString. } - -uses - SysUtils, - Classes, - module in 'module.pas'; - -exports - initdatabase; -{$E pyd} - -begin -end. diff --git a/demos_delphi/Demo14/database.res b/demos_delphi/Demo14/database.res deleted file mode 100644 index d1f138d..0000000 Binary files a/demos_delphi/Demo14/database.res and /dev/null differ diff --git a/demos_delphi/Demo14/module.pas b/demos_delphi/Demo14/module.pas deleted file mode 100644 index 953d1fd..0000000 --- a/demos_delphi/Demo14/module.pas +++ /dev/null @@ -1,36 +0,0 @@ -unit module; - -interface -uses Windows,Dialogs,PythonEngine, PythonDatabase; - -procedure initdatabase; cdecl; - -var - gEngine : TPythonEngine; - gModule : TPythonModule; - gDB : TPythonDatabase; - -implementation - -procedure initdatabase; -begin - try - gEngine := TPythonEngine.Create(nil); - gEngine.AutoFinalize := False; - gDB := TPythonDatabase.Create(nil); - gDB.Engine := gEngine; - gModule := TPythonModule.Create(nil); - gModule.Engine := gEngine; - gModule.ModuleName := 'database'; - gEngine.LoadDll; - except - end; -end; - -initialization -finalization - gEngine.Free; - gModule.Free; -end. - - diff --git a/demos_delphi/Demo15/Project1.dpr b/demos_delphi/Demo15/Project1.dpr deleted file mode 100644 index 513a1dd..0000000 --- a/demos_delphi/Demo15/Project1.dpr +++ /dev/null @@ -1,13 +0,0 @@ -program Project1; - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo15/Project1.res b/demos_delphi/Demo15/Project1.res deleted file mode 100644 index 6008d58..0000000 Binary files a/demos_delphi/Demo15/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo15/Unit1.dfm b/demos_delphi/Demo15/Unit1.dfm deleted file mode 100644 index 29616f7..0000000 Binary files a/demos_delphi/Demo15/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo15/Unit1.pas b/demos_delphi/Demo15/Unit1.pas deleted file mode 100644 index 5d26c6e..0000000 --- a/demos_delphi/Demo15/Unit1.pas +++ /dev/null @@ -1,157 +0,0 @@ -unit Unit1; - -interface - -uses - Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - PythonEngine, StdCtrls, ComCtrls, ExtCtrls, PythonGUIInputOutput, Db, - DBTables, Grids, DBGrids; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Panel1: TPanel; - Button1: TButton; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Panel2: TPanel; - Panel3: TPanel; - RichEdit1: TRichEdit; - Splitter1: TSplitter; - Memo1: TMemo; - DBGrid1: TDBGrid; - Table1: TTable; - DataSource1: TDataSource; - PythonModule1: TPythonModule; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure PythonModule1AfterInitialization(Sender: TObject); - procedure PythonModule1Initialization(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - - function CreateTable( const DBName, TblName : String ) : TDataset; - function DoCreateTable( Self, Args : PPyObject ) : PPyObject; cdecl; // Don't forget the cdecl keyword !!! - - -var - Form1: TForm1; - -implementation -uses pyDB; -{$R *.DFM} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.PythonModule1AfterInitialization(Sender: TObject); -var - ds : TDataset; - obj : PPyObject; -begin - // The table is created while Python initializes our modules. - // But we could do it just before the ExecStrings method. - with Sender as TPythonModule do - begin - // Create our TDataset subclass - ds := CreateTable( 'DBDemos', 'Animals.dbf' ); - // Use it in the Datasource of the DBGrid - Datasource1.Dataset := ds; - // Create a Python object that will let your script access your table - obj := NewDataset(ds, True); - // Put the Python object in a module var called 'Dataset' - // To access this var in your script, import the module and prefix the var name with - // the module name: - // import MyModule - // print MyModule.Dataset.Active - PythonModule1.SetVar( 'Dataset', obj ); - // Don't forget to decrement the object, because SetVar has incremented it, - // in order to acquire property. - GetPythonEngine.Py_XDecRef(obj); - end; -end; - - - -procedure TForm1.PythonModule1Initialization(Sender: TObject); -begin - // Here we register our new module functions - with Sender as TPythonModule do - AddMethod( 'CreateTable', DoCreateTable, 'CreateTable( DBName, TbleName ) -> Dataset' ); -end; - -function CreateTable( const DBName, TblName : String ) : TDataset; -var - ds : TTable; -begin - // Note that here we use a simple TTable, but replace the TTable with anything that - // inherits from a TDataset. - ds := TTable.Create(nil); - ds.DatabaseName := DBName; - ds.TableName := TblName; - ds.Active := True; - Result := ds; -end; - -{ - This function will let your Python script create its own instances of your - TDataset subclass ! -} -function DoCreateTable( Self, Args : PPyObject ) : PPyObject; cdecl; -var - DBName, TblName : PAnsiChar; - ds : TDataset; -begin - with GetPythonEngine do - begin - // Extract our arguments - if PyArg_ParseTuple( args, 'ss:CreateTable',@DBName, @TblName ) <> 0 then - begin - try - // Try to create our dataset - ds := CreateTable( DBName, TblName ); - // Create our Python wrapper - Result := NewDataset( ds, True ); - except - on E : Exception do - begin - if Assigned(gDBModule) then - gDBModule.RaiseError( 'DBError', E.Message ); - Result := nil; - end; - end; - end - else // the arguments were not right - Result := nil; - end; -end; - -end. diff --git a/demos_delphi/Demo16/Example1/Project1.dpr b/demos_delphi/Demo16/Example1/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo16/Example1/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo16/Example1/Project1.dproj b/demos_delphi/Demo16/Example1/Project1.dproj deleted file mode 100644 index a621894..0000000 --- a/demos_delphi/Demo16/Example1/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {FEB76A6C-3FF0-423D-AA7F-BA28CE5A6B63} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo16/Example1/Project1.res b/demos_delphi/Demo16/Example1/Project1.res deleted file mode 100644 index d1f138d..0000000 Binary files a/demos_delphi/Demo16/Example1/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo16/Example1/Unit1.dfm b/demos_delphi/Demo16/Example1/Unit1.dfm deleted file mode 100644 index 04f92ed..0000000 Binary files a/demos_delphi/Demo16/Example1/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo16/Example1/Unit1.pas b/demos_delphi/Demo16/Example1/Unit1.pas deleted file mode 100644 index 7ff4225..0000000 --- a/demos_delphi/Demo16/Example1/Unit1.pas +++ /dev/null @@ -1,135 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Panel1: TPanel; - Splitter1: TSplitter; - Panel2: TPanel; - Splitter2: TSplitter; - Memo1: TMemo; - GroupBox1: TGroupBox; - Button1: TButton; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - PythonDelphiVar1: TPythonDelphiVar; - edName: TEdit; - cbInformatician: TCheckBox; - rgSex: TRadioGroup; - cbPythonUser: TCheckBox; - cbTitle: TComboBox; - Label1: TLabel; - Label2: TLabel; - edAge: TEdit; - Label3: TLabel; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure PythonDelphiVar1ExtGetData(Sender: TObject; - var Data: PPyObject); - procedure PythonDelphiVar1ExtSetData(Sender: TObject; Data: PPyObject); - procedure PythonDelphiVar1Change(Sender: TObject); - private - FProperties : PPyObject; - - function CreateProperties : PPyObject; - procedure UpdateProperties( props : PPyObject ); - public - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - with GetPythonEngine do - begin - // Detach from previous object - Py_XDecRef(FProperties); - // Create new object - FProperties := CreateProperties; - // Execute script - ExecStrings( Memo1.Lines ); - end; -end; - -procedure TForm1.PythonDelphiVar1ExtGetData(Sender: TObject; - var Data: PPyObject); -begin - with GetPythonEngine do - begin - // Return our object - Data := FProperties; - // Don't forget to increment it, otherwise we would loose property ! - Py_XIncRef(Data); - end; -end; - -procedure TForm1.PythonDelphiVar1ExtSetData(Sender: TObject; - Data: PPyObject); -begin - with GetPythonEngine do - begin - // Check if the transmitted object is a dictionary - if not PyDict_Check(Data) then - Exit; - // Acquire property to the transmitted object - Py_XIncRef(Data); - // Release property of our previous object - Py_XDecRef(FProperties); - // Assisgn transmitted object - FProperties := Data; - end; -end; - -function TForm1.CreateProperties : PPyObject; -begin - with GetPythonEngine do - begin - // Create new dictionary - Result := PyDict_New(); - // Assign key/values - PyDict_SetItemString( Result, 'Title', VariantAsPyObject(cbTitle.Text) ); - PyDict_SetItemString( Result, 'Name', VariantAsPyObject(edName.Text) ); - PyDict_SetItemString( Result, 'Informatician', VariantAsPyObject(cbInformatician.Checked) ); - PyDict_SetItemString( Result, 'PythonUser', VariantAsPyObject(cbPythonUser.Checked) ); - PyDict_SetItemString( Result, 'Age', VariantAsPyObject(StrToIntDef(edAge.Text, 0)) ); - PyDict_SetItemString( Result, 'Sex', VariantAsPyObject(rgSex.ItemIndex) ); - end; -end; - -procedure TForm1.UpdateProperties( props : PPyObject ); -begin - with GetPythonEngine do - begin - // Check if the transmitted object is a dictionary - if not PyDict_Check(props) then - Exit; - // Extract our key/values - cbTitle.Text := PyObjectAsVariant( PyDict_GetItemString(props, 'Title') ); - edName.Text := PyObjectAsVariant( PyDict_GetItemString(props, 'Name') ); - cbInformatician.Checked := PyObjectAsVariant( PyDict_GetItemString(props, 'Informatician') ); - cbPythonUser.Checked := PyObjectAsVariant( PyDict_GetItemString(props, 'PythonUser') ); - edAge.Text := PyObjectAsVariant( PyDict_GetItemString(props, 'Age') ); - rgSex.ItemIndex := PyObjectAsVariant( PyDict_GetItemString(props, 'Sex') ); - end; -end; - -procedure TForm1.PythonDelphiVar1Change(Sender: TObject); -begin - UpdateProperties( FProperties ); -end; - -end. diff --git a/demos_delphi/Demo16/Example2/Project1.dpr b/demos_delphi/Demo16/Example2/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo16/Example2/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo16/Example2/Project1.dproj b/demos_delphi/Demo16/Example2/Project1.dproj deleted file mode 100644 index e4ca94d..0000000 --- a/demos_delphi/Demo16/Example2/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {3B870EA7-EAEB-434F-8C0D-2800B09DC00C} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo16/Example2/Project1.res b/demos_delphi/Demo16/Example2/Project1.res deleted file mode 100644 index d1f138d..0000000 Binary files a/demos_delphi/Demo16/Example2/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo16/Example2/Unit1.dfm b/demos_delphi/Demo16/Example2/Unit1.dfm deleted file mode 100644 index 76671a7..0000000 Binary files a/demos_delphi/Demo16/Example2/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo16/Example2/Unit1.pas b/demos_delphi/Demo16/Example2/Unit1.pas deleted file mode 100644 index c8c630a..0000000 --- a/demos_delphi/Demo16/Example2/Unit1.pas +++ /dev/null @@ -1,161 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Panel1: TPanel; - Splitter1: TSplitter; - Panel2: TPanel; - Splitter2: TSplitter; - Memo1: TMemo; - GroupBox1: TGroupBox; - Button1: TButton; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - edName: TEdit; - cbInformatician: TCheckBox; - rgSex: TRadioGroup; - cbPythonUser: TCheckBox; - cbTitle: TComboBox; - Label1: TLabel; - Label2: TLabel; - edAge: TEdit; - Label3: TLabel; - PythonModule1: TPythonModule; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure PythonModule1Initialization(Sender: TObject); - private - function GetProperty(pSelf, Args : PPyObject) : PPyObject; cdecl; - function SetProperty(pSelf, Args : PPyObject) : PPyObject; cdecl; - function GetPropertyList(pSelf, Args : PPyObject) : PPyObject; cdecl; - public - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - with GetPythonEngine do - begin - // Execute script - ExecStrings( Memo1.Lines ); - end; -end; - -procedure TForm1.PythonModule1Initialization(Sender: TObject); -begin - with Sender as TPythonModule do - begin - AddDelphiMethod( 'GetProperty', GetProperty, 'GetProperty(PropName) -> PropValue' ); - AddDelphiMethod( 'SetProperty', SetProperty, 'SetProperty(PropName, PropValue) -> None' ); - AddDelphiMethod( 'GetPropertyList', GetPropertyList, 'GetPropertyList() -> List of property names' ); - end; -end; - -function TForm1.GetProperty(pSelf, Args : PPyObject) : PPyObject; cdecl; -var - key : PAnsiChar; -begin - with GetPythonEngine do - if PyArg_ParseTuple( args, 's:GetProperty',@key ) <> 0 then - begin - if key = 'Title' then - Result := VariantAsPyObject(cbTitle.Text) - else if key = 'Name' then - Result := VariantAsPyObject(edName.Text) - else if key = 'Informatician' then - Result := VariantAsPyObject(cbInformatician.Checked) - else if key = 'PythonUser' then - Result := VariantAsPyObject(cbPythonUser.Checked) - else if key = 'Age' then - Result := VariantAsPyObject(edAge.Text) - else if key = 'Sex' then - Result := VariantAsPyObject(rgSex.ItemIndex) - else - begin - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown property "%s"', [key]))); - Result := nil; - end; - end - else - Result := nil; -end; - -function TForm1.SetProperty(pSelf, Args : PPyObject) : PPyObject; cdecl; -var - key : PAnsiChar; - value : PPyObject; -begin - with GetPythonEngine do - if PyArg_ParseTuple( args, 'sO:SetProperty',@key, @value ) <> 0 then - begin - if key = 'Title' then - begin - cbTitle.Text := PyObjectAsVariant( value ); - Result := ReturnNone; - end - else if key = 'Name' then - begin - edName.Text := PyObjectAsVariant( value ); - Result := ReturnNone; - end - else if key = 'Informatician' then - begin - cbInformatician.Checked := PyObjectAsVariant( value ); - Result := ReturnNone; - end - else if key = 'PythonUser' then - begin - cbPythonUser.Checked := PyObjectAsVariant( value ); - Result := ReturnNone; - end - else if key = 'Age' then - begin - edAge.Text := PyObjectAsVariant( value ); - Result := ReturnNone; - end - else if key = 'Sex' then - begin - rgSex.ItemIndex := PyObjectAsVariant( value ); - Result := ReturnNone; - end - else - begin - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown property "%s"', [key]))); - Result := nil; - end; - end - else - Result := nil; -end; - -function TForm1.GetPropertyList(pSelf, Args : PPyObject) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - Result := PyList_New(6); - PyList_SetItem(Result, 0, PyString_FromString('Title')); - PyList_SetItem(Result, 1, PyString_FromString('Name')); - PyList_SetItem(Result, 2, PyString_FromString('Informatician')); - PyList_SetItem(Result, 3, PyString_FromString('PythonUser')); - PyList_SetItem(Result, 4, PyString_FromString('Age')); - PyList_SetItem(Result, 5, PyString_FromString('Sex')); - end; -end; - -end. diff --git a/demos_delphi/Demo17/Project1.dpr b/demos_delphi/Demo17/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo17/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo17/Project1.dproj b/demos_delphi/Demo17/Project1.dproj deleted file mode 100644 index 346ba85..0000000 --- a/demos_delphi/Demo17/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {45B70068-605E-4FFB-B78E-2045071FD5FA} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo17/Project1.res b/demos_delphi/Demo17/Project1.res deleted file mode 100644 index cfdbb79..0000000 Binary files a/demos_delphi/Demo17/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo17/Unit1.dfm b/demos_delphi/Demo17/Unit1.dfm deleted file mode 100644 index 7426472..0000000 Binary files a/demos_delphi/Demo17/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo17/Unit1.pas b/demos_delphi/Demo17/Unit1.pas deleted file mode 100644 index a70bac1..0000000 --- a/demos_delphi/Demo17/Unit1.pas +++ /dev/null @@ -1,102 +0,0 @@ -unit Unit1; - -interface - -{$I Definition.Inc} - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - Variants, PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - PythonModule1: TPythonModule; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - private - public - end; - - - -var - Form1: TForm1; - -implementation -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); - - procedure DisplayArrayVar( V : Variant ); - var - i, j : Integer; - item : Variant; - s : String; - begin - Memo2.Lines.Add('Displaying a variant array generated from a Python sequence:'); - for i := VarArrayLowBound( V, 1 ) to VarArrayHighBound( V, 1 ) do - begin - item := V[i]; - for j := VarArrayLowBound( item, 1 ) to VarArrayHighBound( item, 1 ) do - begin - s := item[j]; - Memo2.Lines.Add(Format('(%d, %d) = %s',[i, j, s])); - end; - end; - end; - -var - ComArray : Variant; -begin - ComArray := VarArrayCreate([0, 3, 0, 2], varVariant); - ComArray[0, 0] := 1; - ComArray[0, 1] := 1.1; - ComArray[0, 2] := 'a'; - ComArray[1, 0] := 2; - ComArray[1, 1] := 2.2; - ComArray[1, 2] := 'b'; - ComArray[2, 0] := 3; - ComArray[2, 1] := 3.3; - ComArray[2, 2] := 'c'; - ComArray[3, 0] := 4; - ComArray[3, 1] := 4.4; - ComArray[3, 2] := 'd'; - PythonModule1.SetVarFromVariant( 'L', ComArray ); - PythonEngine1.ExecStrings(Memo1.Lines); - DisplayArrayVar( PythonModule1.GetVarAsVariant( 'L' ) ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -end. diff --git a/demos_delphi/Demo18/Project1.bpr b/demos_delphi/Demo18/Project1.bpr deleted file mode 100644 index 9cef704..0000000 --- a/demos_delphi/Demo18/Project1.bpr +++ /dev/null @@ -1,172 +0,0 @@ -# --------------------------------------------------------------------------- -!if !$d(BCB) -BCB = $(MAKEDIR)\.. -!endif - -# --------------------------------------------------------------------------- -# SECTION EDI -# --------------------------------------------------------------------------- -# La section suivante du Makefile du projet est g�r�e par l'EDI de BCB. -# Il est recommand� d'utiliser l'EDI pour modifier les valeurs de cette -# section. -# --------------------------------------------------------------------------- - -VERSION = BCB.03 -# --------------------------------------------------------------------------- -PROJECT = Project1.exe -OBJFILES = Project1.obj -RESFILES = -RESDEPEN = $(RESFILES) -LIBFILES = ..\..\Components\py21.lib -LIBRARIES = -SPARELIBS = -PACKAGES = VCLX35.bpi VCL35.bpi -DEFFILE = -# --------------------------------------------------------------------------- -PATHCPP = .; -PATHASM = .; -PATHPAS = .; -PATHRC = .; -DEBUGLIBPATH = $(BCB)\lib\debug -RELEASELIBPATH = $(BCB)\lib\release -# --------------------------------------------------------------------------- -CFLAG1 = -Od -w -r- -k -y -v -vi- -c -tWC -CFLAG2 = -D_NO_VCL -I$(BCB)\include;..\..\Components\Include -CFLAG3 = -Tkh30000 -PFLAGS = -D_NO_VCL -U$(BCB)\lib;$(DEBUGLIBPATH) \ - -I$(BCB)\include;..\..\Components\Include -$Y -$W -$O- -v -JPHN -M -RFLAGS = -D_NO_VCL -i$(BCB)\include;..\..\Components\Include -AFLAGS = /i$(BCB)\include /i..\..\Components\Include /d_NO_VCL /mx /w2 /zd -LFLAGS = -L$(BCB)\lib;$(DEBUGLIBPATH) -ap -Tpe -x -Gn -v -IFLAGS = -# --------------------------------------------------------------------------- -ALLOBJ = c0x32.obj $(OBJFILES) -ALLRES = $(RESFILES) -ALLLIB = $(LIBFILES) import32.lib cw32mt.lib -# --------------------------------------------------------------------------- -!ifdef IDEOPTIONS - -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1036 -CodePage=1252 - -[Version Info Keys] -CompanyName= -FileDescription=Executable (Console) -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 -Comments= - -[HistoryLists\hlIncludePath] -Count=3 -Item0=$(BCB)\include;..\..\Components\Include -Item1=$(BCB)\include;..\..\Include -Item2=$(BCB)\include;d:\Python-1.5.2\Include;d:\Python-1.5.2\Pc - -[HistoryLists\hlLibraryPath] -Count=1 -Item0=$(BCB)\lib - -[HistoryLists\hlConditionals] -Count=1 -Item0=_NO_VCL - -[Debugging] -DebugSourceDirs= - -[Parameters] -RunParams= -HostApplication= - -!endif - -# --------------------------------------------------------------------------- -# SECTION MAKE -# --------------------------------------------------------------------------- -# Cette section du fichier projet n'est pas utilis�e par l'EDI de BCB. Elle est destin�e -# � la construction � partir de la ligne de commande en utilisant l'utilitaire MAKE. -# --------------------------------------------------------------------------- - -.autodepend -# --------------------------------------------------------------------------- -!if !$d(BCC32) -BCC32 = bcc32 -!endif - -!if !$d(DCC32) -DCC32 = dcc32 -!endif - -!if !$d(TASM32) -TASM32 = tasm32 -!endif - -!if !$d(LINKER) -LINKER = ilink32 -!endif - -!if !$d(BRCC32) -BRCC32 = brcc32 -!endif -# --------------------------------------------------------------------------- -!if $d(PATHCPP) -.PATH.CPP = $(PATHCPP) -.PATH.C = $(PATHCPP) -!endif - -!if $d(PATHPAS) -.PATH.PAS = $(PATHPAS) -!endif - -!if $d(PATHASM) -.PATH.ASM = $(PATHASM) -!endif - -!if $d(PATHRC) -.PATH.RC = $(PATHRC) -!endif -# --------------------------------------------------------------------------- -$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) - $(BCB)\BIN\$(LINKER) @&&! - $(LFLAGS) + - $(ALLOBJ), + - $(PROJECT),, + - $(ALLLIB), + - $(DEFFILE), + - $(ALLRES) -! -# --------------------------------------------------------------------------- -.pas.hpp: - $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } - -.pas.obj: - $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } - -.cpp.obj: - $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } - -.c.obj: - $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } - -.asm.obj: - $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ - -.rc.res: - $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< -# --------------------------------------------------------------------------- diff --git a/demos_delphi/Demo18/Project1.cpp b/demos_delphi/Demo18/Project1.cpp deleted file mode 100644 index 12893ec..0000000 --- a/demos_delphi/Demo18/Project1.cpp +++ /dev/null @@ -1,47 +0,0 @@ - -#pragma hdrstop -#include -#include -USELIB("..\..\Components\py21.lib"); -//--------------------------------------------------------------------------- -using namespace Py; - -//--------------------------------------------------------------------------- -#pragma argsused - -int ExecString( char * str ) -{ - PyObject *m, *d; - m = PyImport_AddModule("__main__"); - if ( ! m ) - return -1; - d = PyModule_GetDict(m); - PyObject * Result = PyRun_String(str, Py_file_input, d, d); - Py_DECREF(Result); - Py_FlushLine(); - if ( PyErr_Occurred() ) - PyErr_Print(); - if ( Result ) - return 0; - else - return -1; -} - - -int main(int argc, char **argv) -{ - Py_SetProgramName(argv[0]); - // Init Python - Py_Initialize(); - // Execute a script from a string - //if ( ExecString("for i in range(100):\n print 'Line #',i\n") ) - if ( PyRun_SimpleString("for i in range(100):\n print 'Line #',i\n") ) - fprintf(stderr, "Could not execute script !\n"); - // Print some Python informations - fprintf(stderr, "Python %s on %s\n%s\n", - Py_GetVersion(), Py_GetPlatform(), Py_GetCopyright()); - // Finalize Python - Py_Finalize(); - // Terminate - return 0; -} diff --git a/demos_delphi/Demo18/Project1.res b/demos_delphi/Demo18/Project1.res deleted file mode 100644 index 7a54c4c..0000000 Binary files a/demos_delphi/Demo18/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo19/Project1.bpr b/demos_delphi/Demo19/Project1.bpr deleted file mode 100644 index 5f77506..0000000 --- a/demos_delphi/Demo19/Project1.bpr +++ /dev/null @@ -1,186 +0,0 @@ -# --------------------------------------------------------------------------- -!if !$d(BCB) -BCB = $(MAKEDIR)\.. -!endif - -# --------------------------------------------------------------------------- -# SECTION EDI -# --------------------------------------------------------------------------- -# La section suivante du Makefile du projet est g�r�e par l'EDI de BCB. -# Il est recommand� d'utiliser l'EDI pour modifier les valeurs de cette -# section. -# --------------------------------------------------------------------------- - -VERSION = BCB.03 -# --------------------------------------------------------------------------- -PROJECT = Project1.exe -OBJFILES = Project1.obj Unit1.obj -RESFILES = Project1.res -DEFFILE = -RESDEPEN = $(RESFILES) Unit1.dfm -LIBFILES = -LIBRARIES = -SPARELIBS = VCL35.lib -PACKAGES = VCLX35.bpi VCL35.bpi -# --------------------------------------------------------------------------- -PATHCPP = .; -PATHASM = .; -PATHPAS = .; -PATHRC = .; -DEBUGLIBPATH = $(BCB)\lib\debug -RELEASELIBPATH = $(BCB)\lib\release -# --------------------------------------------------------------------------- -CFLAG1 = -Od -Hc -w -Ve -r- -k -y -v -vi- -c -b- -w-par -w-inl -Vx -tW -CFLAG2 = -D_RTLDLL \ - -I$(BCB)\include;$(BCB)\include\vcl;..\..\Components\Sources\Core;..\..\Components\Sources\Vcl \ - -H=$(BCB)\lib\vcl35.csm -CFLAG3 = -Tkh30000 -PFLAGS = -D_RTLDLL \ - -U$(BCB)\lib\obj;$(BCB)\lib;..\..\Components;..\..\Components\Sources\Core;"e:\program files\PythonForDelphi\Components\Sources\Vcl";$(RELEASELIBPATH) \ - -I$(BCB)\include;$(BCB)\include\vcl;..\..\Components\Sources\Core;..\..\Components\Sources\Vcl \ - -$Y -$W -$O- -v -JPHN -M -RFLAGS = -D_RTLDLL \ - -i$(BCB)\include;$(BCB)\include\vcl;..\..\Components\Sources\Core;..\..\Components\Sources\Vcl -AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /i..\..\Components\Sources\Core \ - /i..\..\Components\Sources\Vcl /d_RTLDLL /mx /w2 /zd -LFLAGS = -L$(BCB)\lib\obj;$(BCB)\lib;..\..\Components;..\..\Components\Sources\Core;"e:\program files\PythonForDelphi\Components\Sources\Vcl";$(RELEASELIBPATH) \ - -aa -Tpe -x -Gn -v -IFLAGS = -# --------------------------------------------------------------------------- -ALLOBJ = c0w32.obj sysinit.obj $(OBJFILES) -ALLRES = $(RESFILES) -ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib -# --------------------------------------------------------------------------- -!ifdef IDEOPTIONS - -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1036 -CodePage=1252 - -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 -Comments= - -[HistoryLists\hlIncludePath] -Count=2 -Item0=$(BCB)\include;$(BCB)\include\vcl;..\..\Components\Sources\Core;..\..\Components\Sources\Vcl -Item1=$(BCB)\include;$(BCB)\include\vcl;e:\program files\PythonForDelphi\Components\Sources\Core;e:\program files\PythonForDelphi\Components\Sources\Vcl - -[HistoryLists\hlLibraryPath] -Count=4 -Item0=$(BCB)\lib\obj;$(BCB)\lib;..\..\Components;..\..\Components\Sources\Core;e:\program files\PythonForDelphi\Components\Sources\Vcl -Item1=$(BCB)\lib\obj;$(BCB)\lib;e:\program files\PythonForDelphi\Components;e:\program files\PythonForDelphi\Components\Sources\Core;e:\program files\PythonForDelphi\Components\Sources\Vcl -Item2=$(BCB)\lib\obj;$(BCB)\lib;e:\program files\PythonForDelphi\Components;;e:\program files\PythonForDelphi\Components\Sources\Core;e:\program files\PythonForDelphi\Components\Sources\Vcl -Item3=$(BCB)\lib\obj;$(BCB)\lib;e:\program files\PythonForDelphi\Components - -[HistoryLists\hlDebugSourcePath] -Count=1 -Item0=$(BCB)\source\vcl - -[HistoryLists\hlConditionals] -Count=2 -Item0=_RTLDLL -Item1=_RTLDLL;USEPACKAGES - -[Debugging] -DebugSourceDirs=$(BCB)\source\vcl - -[Parameters] -RunParams= -HostApplication= - -!endif - -# --------------------------------------------------------------------------- -# SECTION MAKE -# --------------------------------------------------------------------------- -# Cette section du fichier projet n'est pas utilis�e par l'EDI de BCB. Elle est destin�e -# � la construction � partir de la ligne de commande en utilisant l'utilitaire MAKE. -# --------------------------------------------------------------------------- - -.autodepend -# --------------------------------------------------------------------------- -!if !$d(BCC32) -BCC32 = bcc32 -!endif - -!if !$d(DCC32) -DCC32 = dcc32 -!endif - -!if !$d(TASM32) -TASM32 = tasm32 -!endif - -!if !$d(LINKER) -LINKER = ilink32 -!endif - -!if !$d(BRCC32) -BRCC32 = brcc32 -!endif -# --------------------------------------------------------------------------- -!if $d(PATHCPP) -.PATH.CPP = $(PATHCPP) -.PATH.C = $(PATHCPP) -!endif - -!if $d(PATHPAS) -.PATH.PAS = $(PATHPAS) -!endif - -!if $d(PATHASM) -.PATH.ASM = $(PATHASM) -!endif - -!if $d(PATHRC) -.PATH.RC = $(PATHRC) -!endif -# --------------------------------------------------------------------------- -$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) - $(BCB)\BIN\$(LINKER) @&&! - $(LFLAGS) + - $(ALLOBJ), + - $(PROJECT),, + - $(ALLLIB), + - $(DEFFILE), + - $(ALLRES) -! -# --------------------------------------------------------------------------- -.pas.hpp: - $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } - -.pas.obj: - $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } - -.cpp.obj: - $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } - -.c.obj: - $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } - -.asm.obj: - $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ - -.rc.res: - $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< -# --------------------------------------------------------------------------- diff --git a/demos_delphi/Demo19/Project1.cpp b/demos_delphi/Demo19/Project1.cpp deleted file mode 100644 index ee17a36..0000000 --- a/demos_delphi/Demo19/Project1.cpp +++ /dev/null @@ -1,21 +0,0 @@ -//--------------------------------------------------------------------------- -#include -#pragma hdrstop -USERES("Project1.res"); -USEFORM("Unit1.cpp", Form1); -//--------------------------------------------------------------------------- -WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->CreateForm(__classid(TForm1), &Form1); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - return 0; -} -//--------------------------------------------------------------------------- diff --git a/demos_delphi/Demo19/Project1.res b/demos_delphi/Demo19/Project1.res deleted file mode 100644 index 5245a96..0000000 Binary files a/demos_delphi/Demo19/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo19/Unit1.cpp b/demos_delphi/Demo19/Unit1.cpp deleted file mode 100644 index da8c9ab..0000000 --- a/demos_delphi/Demo19/Unit1.cpp +++ /dev/null @@ -1,51 +0,0 @@ -//--------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Unit1.h" -//--------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma link "PythonEngine" -#pragma link "PythonGUIInputOutput" -#pragma resource "*.dfm" -TForm1 *Form1; -//--------------------------------------------------------------------------- -__fastcall TForm1::TForm1(TComponent* Owner) - : TForm(Owner) -{ -} -//--------------------------------------------------------------------------- - -void __fastcall TForm1::Button1Click(TObject *Sender) -{ - PythonEngine1->ExecStrings( Memo1->Lines ); -} -//--------------------------------------------------------------------------- - -void __fastcall TForm1::Button2Click(TObject *Sender) -{ - if ( OpenDialog1->Execute() ) - Memo1->Lines->LoadFromFile( OpenDialog1->FileName ); -} -//--------------------------------------------------------------------------- - -void __fastcall TForm1::Button3Click(TObject *Sender) -{ - if ( SaveDialog1->Execute() ) - Memo1->Lines->SaveToFile( SaveDialog1->FileName ); -} -//--------------------------------------------------------------------------- -PPyObject spam_foo( PPyObject self, PPyObject args ) -{ - // normally, you would use the function PyArg_ParseTuple for - // parsing the given arguments. - TPythonEngine * eng = GetPythonEngine(); - ShowMessage( "args of foo: "+eng->PyObjectAsString(args) ); - return eng->ReturnNone(); -} - -void __fastcall TForm1::PythonModule1Initialization(TObject *Sender) -{ - PythonModule1->AddMethod( "foo", spam_foo, "foo" ); -} -//--------------------------------------------------------------------------- diff --git a/demos_delphi/Demo19/Unit1.dfm b/demos_delphi/Demo19/Unit1.dfm deleted file mode 100644 index 2c4cd6f..0000000 Binary files a/demos_delphi/Demo19/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo19/Unit1.h b/demos_delphi/Demo19/Unit1.h deleted file mode 100644 index 6cd774b..0000000 --- a/demos_delphi/Demo19/Unit1.h +++ /dev/null @@ -1,40 +0,0 @@ -//--------------------------------------------------------------------------- -#ifndef Unit1H -#define Unit1H -//--------------------------------------------------------------------------- -#include -#include -#include -#include -#include "PythonEngine.hpp" -#include "PythonGUIInputOutput.hpp" -#include -#include -//--------------------------------------------------------------------------- -class TForm1 : public TForm -{ -__published: // Composants g�r�s par l'EDI - TMemo *Memo1; - TPanel *Panel1; - TButton *Button1; - TButton *Button2; - TButton *Button3; - TPythonEngine *PythonEngine1; - TPythonModule *PythonModule1; - TOpenDialog *OpenDialog1; - TSaveDialog *SaveDialog1; - TPythonGUIInputOutput *PythonGUIInputOutput1; - TMemo *Memo2; - TSplitter *Splitter1; - void __fastcall Button1Click(TObject *Sender); - void __fastcall Button2Click(TObject *Sender); - void __fastcall Button3Click(TObject *Sender); - void __fastcall PythonModule1Initialization(TObject *Sender); -private: // D�clarations de l'utilisateur -public: // D�clarations de l'utilisateur - __fastcall TForm1(TComponent* Owner); -}; -//--------------------------------------------------------------------------- -extern PACKAGE TForm1 *Form1; -//--------------------------------------------------------------------------- -#endif diff --git a/demos_delphi/Demo20/Project1.bpr b/demos_delphi/Demo20/Project1.bpr deleted file mode 100644 index 322c44c..0000000 --- a/demos_delphi/Demo20/Project1.bpr +++ /dev/null @@ -1,188 +0,0 @@ -# --------------------------------------------------------------------------- -!if !$d(BCB) -BCB = $(MAKEDIR)\.. -!endif - -# --------------------------------------------------------------------------- -# SECTION EDI -# --------------------------------------------------------------------------- -# La section suivante du Makefile du projet est g�r�e par l'EDI de BCB. -# Il est recommand� d'utiliser l'EDI pour modifier les valeurs de cette -# section. -# --------------------------------------------------------------------------- - -VERSION = BCB.03 -# --------------------------------------------------------------------------- -PROJECT = Project1.exe -OBJFILES = Project1.obj Unit1.obj -RESFILES = Project1.res -DEFFILE = -RESDEPEN = $(RESFILES) Unit1.dfm -LIBFILES = py21.lib -LIBRARIES = -SPARELIBS = VCL35.lib -PACKAGES = VCLX35.bpi VCL35.bpi -# --------------------------------------------------------------------------- -PATHCPP = .; -PATHASM = .; -PATHPAS = .; -PATHRC = .; -DEBUGLIBPATH = $(BCB)\lib\debug -RELEASELIBPATH = $(BCB)\lib\release -# --------------------------------------------------------------------------- -CFLAG1 = -Od -Hc -w -Ve -r- -k -y -v -vi- -c -b- -w-par -w-inl -Vx -tW -CFLAG2 = -D_RTLDLL;USEPACKAGES \ - -I$(BCB)\include;$(BCB)\include\vcl;..\..\components\sources\core;..\..\components\sources\vcl;..\..\Components\Include \ - -H=$(BCB)\lib\vcl35.csm -CFLAG3 = -Tkh30000 -PFLAGS = -D_RTLDLL;USEPACKAGES \ - -U$(BCB)\lib\obj;$(BCB)\lib;..\..\components\sources\core;..\..\components\sources\vcl;$(RELEASELIBPATH) \ - -I$(BCB)\include;$(BCB)\include\vcl;..\..\components\sources\core;..\..\components\sources\vcl;..\..\Components\Include \ - -$Y -$W -$O- -v -JPHN -M -RFLAGS = -D_RTLDLL;USEPACKAGES \ - -i$(BCB)\include;$(BCB)\include\vcl;..\..\components\sources\core;..\..\components\sources\vcl;..\..\Components\Include -AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /i..\..\components\sources\core \ - /i..\..\components\sources\vcl /i..\..\Components\Include /d_RTLDLL \ - /dUSEPACKAGES /mx /w2 /zd -LFLAGS = -L$(BCB)\lib\obj;$(BCB)\lib;..\..\components\sources\core;..\..\components\sources\vcl;$(RELEASELIBPATH) \ - -aa -Tpe -x -Gn -v -IFLAGS = -# --------------------------------------------------------------------------- -ALLOBJ = c0w32.obj $(PACKAGES) sysinit.obj $(OBJFILES) -ALLRES = $(RESFILES) -ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib -# --------------------------------------------------------------------------- -!ifdef IDEOPTIONS - -[Version Info] -IncludeVerInfo=0 -AutoIncBuild=0 -MajorVer=1 -MinorVer=0 -Release=0 -Build=0 -Debug=0 -PreRelease=0 -Special=0 -Private=0 -DLL=0 -Locale=1036 -CodePage=1252 - -[Version Info Keys] -CompanyName= -FileDescription= -FileVersion=1.0.0.0 -InternalName= -LegalCopyright= -LegalTrademarks= -OriginalFilename= -ProductName= -ProductVersion=1.0.0.0 -Comments= - -[HistoryLists\hlIncludePath] -Count=3 -Item0=$(BCB)\include;$(BCB)\include\vcl;..\..\components\sources\core;..\..\components\sources\vcl;..\..\Components\Include -Item1=$(BCB)\include;$(BCB)\include\vcl;e:\program files\pythonfordelphi\components\sources\core;e:\program files\pythonfordelphi\components\sources\vcl;D:\Python-1.5.2\Include;D:\Python-1.5.2\PC -Item2=$(BCB)\include;$(BCB)\include\vcl;e:\program files\pythonfordelphi\components\sources\core;e:\program files\pythonfordelphi\components\sources\vcl - -[HistoryLists\hlLibraryPath] -Count=3 -Item0=$(BCB)\lib\obj;$(BCB)\lib;..\..\components\sources\core;..\..\components\sources\vcl -Item1=e:\program files\pythonfordelphi\components\sources\core;$(BCB)\lib\obj;$(BCB)\lib;e:\program files\pythonfordelphi\components\sources\vcl -Item2=$(BCB)\lib\obj;$(BCB)\lib;e:\program files\pythonfordelphi\components\sources\core;e:\program files\pythonfordelphi\components\sources\vcl - -[HistoryLists\hlDebugSourcePath] -Count=1 -Item0=$(BCB)\source\vcl - -[HistoryLists\hlConditionals] -Count=3 -Item0=_RTLDLL;USEPACKAGES -Item1=_RTLDLL -Item2=_RTLDLL;NO_IMPLICIT_NAMESPACE_USE - -[Debugging] -DebugSourceDirs=$(BCB)\source\vcl - -[Parameters] -RunParams= -HostApplication= - -!endif - -# --------------------------------------------------------------------------- -# SECTION MAKE -# --------------------------------------------------------------------------- -# Cette section du fichier projet n'est pas utilis�e par l'EDI de BCB. Elle est destin�e -# � la construction � partir de la ligne de commande en utilisant l'utilitaire MAKE. -# --------------------------------------------------------------------------- - -.autodepend -# --------------------------------------------------------------------------- -!if !$d(BCC32) -BCC32 = bcc32 -!endif - -!if !$d(DCC32) -DCC32 = dcc32 -!endif - -!if !$d(TASM32) -TASM32 = tasm32 -!endif - -!if !$d(LINKER) -LINKER = ilink32 -!endif - -!if !$d(BRCC32) -BRCC32 = brcc32 -!endif -# --------------------------------------------------------------------------- -!if $d(PATHCPP) -.PATH.CPP = $(PATHCPP) -.PATH.C = $(PATHCPP) -!endif - -!if $d(PATHPAS) -.PATH.PAS = $(PATHPAS) -!endif - -!if $d(PATHASM) -.PATH.ASM = $(PATHASM) -!endif - -!if $d(PATHRC) -.PATH.RC = $(PATHRC) -!endif -# --------------------------------------------------------------------------- -$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) - $(BCB)\BIN\$(LINKER) @&&! - $(LFLAGS) + - $(ALLOBJ), + - $(PROJECT),, + - $(ALLLIB), + - $(DEFFILE), + - $(ALLRES) -! -# --------------------------------------------------------------------------- -.pas.hpp: - $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } - -.pas.obj: - $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } - -.cpp.obj: - $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } - -.c.obj: - $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } - -.asm.obj: - $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ - -.rc.res: - $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< -# --------------------------------------------------------------------------- diff --git a/demos_delphi/Demo20/Project1.cpp b/demos_delphi/Demo20/Project1.cpp deleted file mode 100644 index c090264..0000000 --- a/demos_delphi/Demo20/Project1.cpp +++ /dev/null @@ -1,22 +0,0 @@ -//--------------------------------------------------------------------------- -#include -#pragma hdrstop -USERES("Project1.res"); -USEFORM("Unit1.cpp", Form1); -USELIB("py21.lib"); -//--------------------------------------------------------------------------- -WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -{ - try - { - Application->Initialize(); - Application->CreateForm(__classid(TForm1), &Form1); - Application->Run(); - } - catch (Exception &exception) - { - Application->ShowException(&exception); - } - return 0; -} -//--------------------------------------------------------------------------- diff --git a/demos_delphi/Demo20/Project1.res b/demos_delphi/Demo20/Project1.res deleted file mode 100644 index 5245a96..0000000 Binary files a/demos_delphi/Demo20/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo20/Unit1.cpp b/demos_delphi/Demo20/Unit1.cpp deleted file mode 100644 index 37d9157..0000000 --- a/demos_delphi/Demo20/Unit1.cpp +++ /dev/null @@ -1,154 +0,0 @@ -//--------------------------------------------------------------------------- -#include -#pragma hdrstop - -#include "Unit1.h" -#include -//--------------------------------------------------------------------------- -#pragma package(smart_init) -#pragma link "PythonEngine" -#pragma link "PythonGUIInputOutput" -#pragma resource "*.dfm" -TForm1 *Form1; - -//--------------------------------------------------------------------------- -// New Python type Point -// -// Constructors & Destructors - -// We override the constructors -__fastcall TPyPoint::TPyPoint( TPythonType* APythonType ) - : TPyObject(APythonType) -{ - x = 0; - y = 0; -} - -// Don't call the Create constructor of TPyPoint, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyPoint.Create will be automatically be called. -__fastcall TPyPoint::TPyPoint( TPythonType* APythonType, PPyObject args ) - : TPyObject(APythonType, args) -{ - if (! Py::PyArg_ParseTuple( (Py::PyObject *)args, "ii:CreatePoint", &x, &y )) - return; -} - -// Type services -//////////////// - -// Basic services -PPyObject __fastcall TPyPoint::GetAttr(char * key) -{ - TPythonEngine* eng = GetPythonEngine(); - if ( strcmp(key, "x") == 0 ) - return eng->VariantAsPyObject( x ); - // Or return eng->PyInt_FromLong( x ); - else if ( strcmp(key, "y" ) == 0 ) - return eng->VariantAsPyObject( y ); - // or return PyInt_FromLong( y ); - else - return inherited::GetAttr(key); -} - -int __fastcall TPyPoint::SetAttr(char * key, PPyObject value) -{ - Py::PyObject * val = (Py::PyObject *)value; - if ( strcmp(key, "x") == 0 ) { - if ( Py::PyArg_Parse( val, "i:Point.SetAttr", &x ) ) - return 0; - else - return -1; - } else if ( strcmp(key, "y") == 0 ) { - if ( Py::PyArg_Parse( val, "i:Point.SetAttr", &y ) ) - return 0; - else - return -1; - } else - return inherited::SetAttr(key, value); -} - -PPyObject __fastcall TPyPoint::Repr(void) -{ - TPythonEngine* eng = GetPythonEngine(); - return eng->VariantAsPyObject(Format("(%d, %d)",ARRAYOFCONST((x, y)))); - // or return eng->PyString_FromString( (char *)Format("(%d, %d)", ARRAYOFCONST((x, y))) ); -} - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -PPyObject __cdecl DoOffsetBy( PPyObject self, PPyObject args ) -{ - TPyPoint * p = (TPyPoint *)PythonToDelphi(self); - int dx, dy; - if (! Py::PyArg_ParseTuple( (Py::PyObject *)args, "ii:OffsetBy", &dx, &dy )) - return NULL; - p->OffsetBy(dx, dy); - TPythonEngine* eng = GetPythonEngine(); - return eng->ReturnNone(); -} - -PPyObject __cdecl DoRaiseError( PPyObject self, PPyObject args ) -{ - TPyPoint * p = (TPyPoint *)PythonToDelphi(self); - p->RaiseError(); - return NULL; // we return NULL because RaiseError raised a Python error. -} - -// Class method for registering the type interface methods -void __fastcall TPyPoint::RegisterMethods(TPythonType* PythonType) -{ - inherited::RegisterMethods(PythonType); - PythonType->AddMethod( "OffsetBy", DoOffsetBy, "Point.OffsetBy( dx, dy )" ); - PythonType->AddMethod( "RaiseError", DoRaiseError, "Point.RaiseError()" ); -} - -// Methods of TPyPoint -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -void TPyPoint::OffsetBy( int dx, int dy ) -{ - x += dx; - y += dy; -} - -// Here's an example of how you can raise errors defined -// in the module linked to our type. -void TPyPoint::RaiseError(void) -{ - TPythonEngine* eng = GetPythonEngine(); - // This is a simple call: - // GetModule->RaiseError( "PointError", "this is an example of raising an error !" ); - // This is an advanced call: - // We provide the instance vars as a dictionary, so that we can intercept the - // error with "except" and extract informations from the error object. - // ArrayToPyDict needs a list of pairs: varName (string), varValue (anything) - GetModule()->RaiseErrorObj( "EBadPoint", "this is an example of raising an error !", - eng->ArrayToPyDict( ARRAYOFCONST(("a", 1, "b", 2, "c", 3)) ) ); -} - -//--------------------------------------------------------------------------- -__fastcall TForm1::TForm1(TComponent* Owner) - : TForm(Owner) -{ -} -//--------------------------------------------------------------------------- -void __fastcall TForm1::Button1Click(TObject *Sender) -{ - PythonEngine1->ExecStrings( Memo2->Lines ); -} -//--------------------------------------------------------------------------- -// We need to initialize the property PyObjectClass with -// the class of our Type object -void __fastcall TForm1::PythonType1Initialization(TObject *Sender) -{ - PythonType1->PyObjectClass = __classid(TPyPoint); -} -//--------------------------------------------------------------------------- diff --git a/demos_delphi/Demo20/Unit1.dfm b/demos_delphi/Demo20/Unit1.dfm deleted file mode 100644 index c6a7a20..0000000 Binary files a/demos_delphi/Demo20/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo20/Unit1.h b/demos_delphi/Demo20/Unit1.h deleted file mode 100644 index ad34ca9..0000000 --- a/demos_delphi/Demo20/Unit1.h +++ /dev/null @@ -1,62 +0,0 @@ -//--------------------------------------------------------------------------- -#ifndef Unit1H -#define Unit1H -//--------------------------------------------------------------------------- -#include -#include -#include -#include -#include "PythonEngine.hpp" -#include "PythonGUIInputOutput.hpp" -#include -//--------------------------------------------------------------------------- -// New Python type Point -class TPyPoint : public TPyObject -{ -public: - typedef TPyObject inherited; - - int x, y; - - // Constructors & Destructors - __fastcall TPyPoint( TPythonType* APythonType ); - __fastcall TPyPoint( TPythonType* APythonType, PPyObject args ); - - // Type services - //////////////// - - // Basic services - virtual PPyObject __fastcall GetAttr(char * key); - virtual int __fastcall SetAttr(char * key, PPyObject value); - virtual PPyObject __fastcall Repr(void); - - /* virtual class method */ virtual void __fastcall RegisterMethods(TPythonType* PythonType); - - // Methods of TPyPoint - void OffsetBy( int dx, int dy ); - void RaiseError(void); - -}; -//--------------------------------------------------------------------------- -class TForm1 : public TForm -{ -__published: // Composants g�r�s par l'EDI - TPythonEngine *PythonEngine1; - TPythonGUIInputOutput *PythonGUIInputOutput1; - TMemo *Memo1; - TSplitter *Splitter1; - TMemo *Memo2; - TPanel *Panel1; - TButton *Button1; - TPythonModule *PythonModule1; - TPythonType *PythonType1; - void __fastcall Button1Click(TObject *Sender); - void __fastcall PythonType1Initialization(TObject *Sender); -private: // D�clarations de l'utilisateur -public: // D�clarations de l'utilisateur - __fastcall TForm1(TComponent* Owner); -}; -//--------------------------------------------------------------------------- -extern PACKAGE TForm1 *Form1; -//--------------------------------------------------------------------------- -#endif diff --git a/demos_delphi/Demo21/Project1.dpr b/demos_delphi/Demo21/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo21/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo21/Project1.dproj b/demos_delphi/Demo21/Project1.dproj deleted file mode 100644 index 14f1c23..0000000 --- a/demos_delphi/Demo21/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {8A0913B4-35C9-4DDA-A98A-02C28A91C049} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo21/Project1.res b/demos_delphi/Demo21/Project1.res deleted file mode 100644 index cfdbb79..0000000 Binary files a/demos_delphi/Demo21/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo21/Unit1.dfm b/demos_delphi/Demo21/Unit1.dfm deleted file mode 100644 index 33ffc7e..0000000 Binary files a/demos_delphi/Demo21/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo21/Unit1.pas b/demos_delphi/Demo21/Unit1.pas deleted file mode 100644 index 82c3b5e..0000000 --- a/demos_delphi/Demo21/Unit1.pas +++ /dev/null @@ -1,214 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - PythonModule1: TPythonModule; - PythonType1: TPythonType; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure PythonModule1Events0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); - procedure PythonType1Initialization(Sender: TObject); - procedure PythonType1Events0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); - private - public - end; - - // This is a Delphi class implementing a new Python type - // it must derive from TPyObject or one of its descendants. - // Then it must override some methods, like the constructors, - // the RegisterMethods and the type services' virtual methods. - TPyPoint = class(TPyObject) - x, y : Integer; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; - function Repr : PPyObject; override; - - // Methods of TPyPoint - procedure OffsetBy( dx, dy : Integer ); - end; - - -var - Form1: TForm1; - -implementation -{$R *.dfm} - -// We override the constructors - -constructor TPyPoint.Create( APythonType : TPythonType ); -begin - inherited; - x := 0; - y := 0; -end; - -// Don't call the Create constructor of TPyPoint, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyPoint.Create will be automatically be called. - -constructor TPyPoint.CreateWith( PythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'ii:CreatePoint',@x, @y ) = 0 then - exit; - end; -end; - -// Then we override the needed services - -function TPyPoint.GetAttr(key : PAnsiChar) : PPyObject; -begin - with GetPythonEngine do - begin - if key = 'x' then - Result := VariantAsPyObject( x ) - // Or Result := PyInt_FromLong( x ) - else if key = 'y' then - Result := PyInt_FromLong( y ) - // or Result := PyInt_FromLong( y ) - else - Result := inherited GetAttr(key); - end; -end; - -function TPyPoint.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; -begin - Result := 0; - with GetPythonEngine do - begin - if key = 'x' then - begin - if PyArg_Parse( value, 'i:Point.SetAttr', @x ) = 0 then - Result := -1; - end - else if key = 'y' then - begin - if PyArg_Parse( value, 'i:Point.SetAttr', @y ) = 0 then - Result := -1; - end - else - Result := inherited SetAttr(key, value); - end; -end; - -function TPyPoint.Repr : PPyObject; -begin - with GetPythonEngine do - Result := VariantAsPyObject(Format('(%d, %d)',[x, y])); - // or Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[x, y])) ); -end; - -// Methods of TPyPoint -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -procedure TPyPoint.OffsetBy( dx, dy : Integer ); -begin - Inc( x, dx ); - Inc( y, dy ); -end; - -///////////////////////////////////////////////// - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.PythonModule1Events0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); -begin - with GetPythonEngine do - begin - Result := PyString_FromString('Hello world !'); - end; -end; - -procedure TForm1.PythonType1Initialization(Sender: TObject); -begin - PythonType1.PyObjectClass := TPyPoint; -end; - -procedure TForm1.PythonType1Events0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); -var - dx, dy : Integer; - Instance : TPyPoint; -begin - with GetPythonEngine do - begin - // Convert the PSelf Python object to a Delphi instance pointer. - Instance := TPyPoint(PythonToDelphi(PSelf)); - // first we extract the arguments - if PyArg_ParseTuple( args, 'ii:Point.Offset',@dx, @dy ) <> 0 then - begin - // if it's ok, then we call the method that does the job - // with the correct arguments - Instance.OffsetBy( dx, dy ); - // Finally, we return nothing - Result := ReturnNone; - end - else // the arguments were not right - Result := nil; - end; -end; - -end. diff --git a/demos_delphi/Demo22/Project1.dpr b/demos_delphi/Demo22/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo22/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo22/Project1.dproj b/demos_delphi/Demo22/Project1.dproj deleted file mode 100644 index 5014433..0000000 --- a/demos_delphi/Demo22/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {17D5A3A6-4820-4D9C-BD8A-71D8B83709A0} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo22/Project1.res b/demos_delphi/Demo22/Project1.res deleted file mode 100644 index cfdbb79..0000000 Binary files a/demos_delphi/Demo22/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo22/Unit1.dfm b/demos_delphi/Demo22/Unit1.dfm deleted file mode 100644 index 7019efe..0000000 Binary files a/demos_delphi/Demo22/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo22/Unit1.pas b/demos_delphi/Demo22/Unit1.pas deleted file mode 100644 index 873e629..0000000 --- a/demos_delphi/Demo22/Unit1.pas +++ /dev/null @@ -1,68 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure FormClose(Sender: TObject; var Action: TCloseAction); - private - public - end; - - - -var - Form1: TForm1; - -implementation -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); -begin - PythonEngine1.Finalize; -end; - -end. diff --git a/demos_delphi/Demo23/Project1.dpr b/demos_delphi/Demo23/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo23/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo23/Project1.dproj b/demos_delphi/Demo23/Project1.dproj deleted file mode 100644 index 071d003..0000000 --- a/demos_delphi/Demo23/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {C077A77D-C4BE-486B-A654-6605F805E4FE} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo23/Project1.res b/demos_delphi/Demo23/Project1.res deleted file mode 100644 index cfdbb79..0000000 Binary files a/demos_delphi/Demo23/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo23/Unit1.dfm b/demos_delphi/Demo23/Unit1.dfm deleted file mode 100644 index ef8929f..0000000 Binary files a/demos_delphi/Demo23/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo23/Unit1.pas b/demos_delphi/Demo23/Unit1.pas deleted file mode 100644 index c91329d..0000000 --- a/demos_delphi/Demo23/Unit1.pas +++ /dev/null @@ -1,82 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonInputOutput1: TPythonInputOutput; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure FormClose(Sender: TObject; var Action: TCloseAction); - procedure PythonInputOutput1SendData(Sender: TObject; - const Data: String); - private - public - end; - - - -var - Form1: TForm1; - -implementation -{$R *.dfm} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); -begin - PythonEngine1.Finalize; -end; - -procedure TForm1.PythonInputOutput1SendData(Sender: TObject; - const Data: String); -begin -{$IFDEF MSWINDOWS} - OutputDebugString( PAnsiChar(Data) ); -{$ENDIF} -{$IFDEF LINUX} - WriteLn( ErrOutput, Data ); -{$ENDIF} -end; - -end. diff --git a/demos_delphi/Demo25/MyModule.py b/demos_delphi/Demo25/MyModule.py deleted file mode 100644 index 9d69bb3..0000000 --- a/demos_delphi/Demo25/MyModule.py +++ /dev/null @@ -1,2 +0,0 @@ -def Add(a, b): - return a + b diff --git a/demos_delphi/Demo25/VarPythUnitTest.bdsproj b/demos_delphi/Demo25/VarPythUnitTest.bdsproj deleted file mode 100644 index 8a06609..0000000 --- a/demos_delphi/Demo25/VarPythUnitTest.bdsproj +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - VarPythUnitTest.dpr - - - 7.0 - - - 8 - 0 - 1 - 1 - 0 - 0 - 1 - 1 - 1 - 0 - 0 - 1 - 0 - 1 - 0 - 1 - 0 - 0 - 0 - 0 - 0 - 1 - 0 - 1 - 1 - 1 - True - True - WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; - - False - - True - False - False - True - False - False - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - True - False - False - False - True - True - True - True - True - True - - - - 0 - 0 - False - 1 - False - False - False - 16384 - 1048576 - 4194304 - - - - - - - - $(DELPHI)\Lib\Debug - vcl;rtl;dbrtl;adortl;vcldb;vclx;bdertl;vcldbx;ibxpress;dsnap;cds;bdecds;qrpt;teeui;teedb;tee;dss;teeqr;visualclx;visualdbclx;dsnapcrba;dsnapcon;VclSmp;vclshlctrls;vclie;xmlrtl;inet;inetdbbde;inetdbxpress;inetdb;nmfast;webdsnap;websnap;dbexpress;dbxcds;indy;dclOffice2k;dxcomnd6;EQTLD6;dxEdtrD6;ECQDBCD6;EQDBTLD6;EQGridD6;dxGrEdD6;dxExELD6;dxELibD6;dxBarD6;dxBarDBNavD6;dxBarExtItemsD6;dxBarExtDBItemsD6;dxsbD6;dxDBEdD6;dxInsD6;dxExRwD6;dxmdsd6;dxorgcD6;dxdborD6;dxPageControlD6;Python_d6;PythonVCL_d6 - - - False - - - - - - False - - - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - diff --git a/demos_delphi/Demo25/VarPythUnitTest.conf b/demos_delphi/Demo25/VarPythUnitTest.conf deleted file mode 100644 index 84e6d10..0000000 --- a/demos_delphi/Demo25/VarPythUnitTest.conf +++ /dev/null @@ -1,32 +0,0 @@ --$A8 --$B- --$C+ --$D+ --$E- --$F- --$G+ --$H+ --$I+ --$J- --$K- --$L+ --$M- --$N+ --$O+ --$P+ --$Q- --$R- --$S- --$T- --$U- --$V+ --$W- --$X+ --$YD --$Z1 --cg --H+ --W+ --M --$M16384,1048576 --K$00400000 diff --git a/demos_delphi/Demo25/VarPythUnitTest.dpr b/demos_delphi/Demo25/VarPythUnitTest.dpr deleted file mode 100644 index 223289b..0000000 --- a/demos_delphi/Demo25/VarPythUnitTest.dpr +++ /dev/null @@ -1,14 +0,0 @@ -program VarPythUnitTest; - -uses - Forms, - fmMain in 'fmMain.pas' {TMain}; - -{$R *.res} - -begin - ReportMemoryLeaksOnShutdown := True; - Application.Initialize; - Application.CreateForm(TMain, Main); - Application.Run; -end. diff --git a/demos_delphi/Demo25/VarPythUnitTest.dproj b/demos_delphi/Demo25/VarPythUnitTest.dproj deleted file mode 100644 index 35e03e5..0000000 --- a/demos_delphi/Demo25/VarPythUnitTest.dproj +++ /dev/null @@ -1,136 +0,0 @@ - - - {F6960501-E313-4232-96B9-EA62FB351D5E} - VarPythUnitTest.dpr - Debug - DCC32 - 13.4 - VCL - True - Win64 - 3 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;System.Win;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - 1033 - VarPythUnitTest.exe - 00400000 - x86 - - - Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - true - $(BDS)\bin\default_app.manifest - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - None - - - - MainSource - - -
TMain
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - VarPythUnitTest.dpr - - - False - True - False - - - True - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - 12 - - -
diff --git a/demos_delphi/Demo25/VarPythUnitTest.res b/demos_delphi/Demo25/VarPythUnitTest.res deleted file mode 100644 index 15f1ffe..0000000 Binary files a/demos_delphi/Demo25/VarPythUnitTest.res and /dev/null differ diff --git a/demos_delphi/Demo25/fmMain.dfm b/demos_delphi/Demo25/fmMain.dfm deleted file mode 100644 index 969796b..0000000 --- a/demos_delphi/Demo25/fmMain.dfm +++ /dev/null @@ -1,290 +0,0 @@ -object Main: TMain - Left = 153 - Top = 148 - Width = 769 - Height = 561 - VertScrollBar.Range = 356 - ActiveControl = Memo1 - Caption = 'VarPyth unit tests' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = 11 - Font.Name = 'MS Sans Serif' - Font.Pitch = fpVariable - Font.Style = [] - OldCreateOrder = True - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object Splitter1: TSplitter - Left = 0 - Top = 249 - Width = 753 - Height = 5 - Cursor = crVSplit - Align = alTop - ExplicitWidth = 761 - end - object Memo1: TMemo - Left = 0 - Top = 0 - Width = 753 - Height = 249 - Align = alTop - ScrollBars = ssVertical - TabOrder = 0 - end - object Panel1: TPanel - Left = 0 - Top = 421 - Width = 753 - Height = 102 - Align = alBottom - BevelOuter = bvNone - TabOrder = 1 - object Label1: TLabel - Left = 616 - Top = 59 - Width = 24 - Height = 13 - Caption = 'times' - end - object ProgressBar1: TProgressBar - Left = 0 - Top = 86 - Width = 753 - Height = 16 - Align = alBottom - TabOrder = 15 - Visible = False - end - object btnExecuteScript: TButton - Left = 8 - Top = 8 - Width = 89 - Height = 25 - Caption = 'E&xecute Script' - TabOrder = 0 - OnClick = btnExecuteScriptClick - end - object btnTestIntegers: TButton - Left = 128 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Test Integers' - TabOrder = 1 - OnClick = btnTestIntegersClick - end - object btnTestFloats: TButton - Left = 216 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Test Floats' - TabOrder = 2 - OnClick = btnTestFloatsClick - end - object btnTestSequences: TButton - Left = 392 - Top = 8 - Width = 89 - Height = 25 - Caption = 'Test Sequences' - TabOrder = 3 - OnClick = btnTestSequencesClick - end - object btnTestMappings: TButton - Left = 488 - Top = 8 - Width = 89 - Height = 25 - Caption = 'Test Mappings' - TabOrder = 4 - OnClick = btnTestMappingsClick - end - object btnTestObjects: TButton - Left = 664 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Test Objects' - TabOrder = 5 - OnClick = btnTestObjectsClick - end - object btnTestStrings: TButton - Left = 304 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Test Strings' - TabOrder = 6 - OnClick = btnTestStringsClick - end - object cbIntegers: TCheckBox - Left = 128 - Top = 33 - Width = 73 - Height = 17 - Caption = 'Included' - Checked = True - State = cbChecked - TabOrder = 7 - end - object cbFloats: TCheckBox - Left = 216 - Top = 33 - Width = 73 - Height = 17 - Caption = 'Included' - Checked = True - State = cbChecked - TabOrder = 8 - end - object cbStrings: TCheckBox - Left = 304 - Top = 33 - Width = 73 - Height = 17 - Caption = 'Included' - Checked = True - State = cbChecked - TabOrder = 9 - end - object cbSequences: TCheckBox - Left = 392 - Top = 33 - Width = 73 - Height = 17 - Caption = 'Included' - Checked = True - State = cbChecked - TabOrder = 10 - end - object cbMappings: TCheckBox - Left = 488 - Top = 33 - Width = 73 - Height = 17 - Caption = 'Included' - Checked = True - State = cbChecked - TabOrder = 11 - end - object cbObjects: TCheckBox - Left = 664 - Top = 33 - Width = 73 - Height = 17 - Caption = 'Included' - Checked = True - State = cbChecked - TabOrder = 12 - end - object btnRunSelectedTests: TButton - Left = 128 - Top = 56 - Width = 121 - Height = 25 - Caption = 'Run selected tests once' - TabOrder = 13 - OnClick = btnRunSelectedTestsClick - end - object edtTestCount: TEdit - Left = 568 - Top = 56 - Width = 41 - Height = 21 - TabOrder = 14 - Text = '1000' - end - object btnRunNTimes: TButton - Left = 400 - Top = 56 - Width = 163 - Height = 25 - Caption = 'Run selected tests n times' - TabOrder = 16 - OnClick = btnRunNTimesClick - end - object btnTestDates: TButton - Left = 584 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Test Dates' - TabOrder = 18 - OnClick = btnTestDatesClick - end - object cbDates: TCheckBox - Left = 584 - Top = 33 - Width = 77 - Height = 17 - Caption = 'Included' - Checked = True - State = cbChecked - TabOrder = 17 - end - end - object Memo2: TMemo - Left = 0 - Top = 254 - Width = 753 - Height = 167 - Align = alClient - Lines.Strings = ( - 'class XYZ(object):' - ' pass' - '' - 'class Foo:' - ' def __init__(Self, Value=0):' - ' Self.Value = Value' - ' def __del__(Self):' - ' print "delete", Self' - ' def __add__(self, other):' - ' return Foo(self.Value + other.Value)' - ' def Inc(Self, AValue = 1):' - ' Self.Value = Self.Value + AValue' - ' def GetSelf(Self):' - ' return Self' - ' def GetValue(Self):' - ' return Self.Value' - ' def SetABC(Self, A, B, C):' - ' Self.A = A' - ' Self.B = B' - ' Self.C = C' - ' def Add(Self, AFooInst):' - ' Self.Value = Self.Value + AFooInst.Value' - 'class Bar(Foo):' - ' def Inc(Self, AValue = 1):' - ' Self.Value = Self.Value - AValue' - 'def Add(a, b):' - ' return a + b' - 'def MakeList(a, b, c, d):' - ' return [a, b, c, d]' - '' - 'f = Foo()' - 'print "Created", f' - 'f.Inc()' - 'f.Inc(2)' - 'b = Bar()' - 'b.Inc()' - 'b.Inc(2)') - ScrollBars = ssVertical - TabOrder = 2 - end - object PythonEngine1: TPythonEngine - IO = PythonGUIInputOutput1 - Left = 192 - Top = 48 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = False - RawOutput = False - Output = Memo1 - Left = 232 - Top = 48 - end -end diff --git a/demos_delphi/Demo25/fmMain.pas b/demos_delphi/Demo25/fmMain.pas deleted file mode 100644 index 3558e76..0000000 --- a/demos_delphi/Demo25/fmMain.pas +++ /dev/null @@ -1,1207 +0,0 @@ -unit fmMain; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, Variants, - Windows, Messages, Graphics, Controls, Forms, - Dialogs, ExtCtrls, StdCtrls, ComCtrls, - PythonEngine, PythonGUIInputOutput, Contnrs; - -type - TMain = class(TForm) - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo1: TMemo; - Splitter1: TSplitter; - Panel1: TPanel; - Memo2: TMemo; - btnExecuteScript: TButton; - btnTestIntegers: TButton; - btnTestFloats: TButton; - btnTestSequences: TButton; - btnTestMappings: TButton; - btnTestObjects: TButton; - btnTestStrings: TButton; - cbIntegers: TCheckBox; - cbFloats: TCheckBox; - cbStrings: TCheckBox; - cbSequences: TCheckBox; - cbMappings: TCheckBox; - cbObjects: TCheckBox; - btnRunSelectedTests: TButton; - edtTestCount: TEdit; - btnRunNTimes: TButton; - Label1: TLabel; - ProgressBar1: TProgressBar; - btnTestDates: TButton; - cbDates: TCheckBox; - procedure btnExecuteScriptClick(Sender: TObject); - procedure btnTestIntegersClick(Sender: TObject); - procedure btnTestFloatsClick(Sender: TObject); - procedure btnTestStringsClick(Sender: TObject); - procedure btnTestSequencesClick(Sender: TObject); - procedure btnTestMappingsClick(Sender: TObject); - procedure btnTestObjectsClick(Sender: TObject); - procedure btnRunSelectedTestsClick(Sender: TObject); - procedure btnRunNTimesClick(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure btnTestDatesClick(Sender: TObject); - private - fVerbose : Boolean; - procedure Log( const AText : String ); - procedure RunSelectedTests; - public - { Public declarations } - end; - -var - Main: TMain; - -implementation - -uses VarPyth; - -{$R *.dfm} - -procedure TMain.Log( const AText : String ); -begin - if fVerbose then - Memo1.Lines.Add(AText); -end; - -procedure TMain.btnExecuteScriptClick(Sender: TObject); -begin - PythonEngine1.ExecStrings(Memo2.Lines); -end; - -procedure TMain.btnTestIntegersClick(Sender: TObject); -var - a, b, c : Variant; - big : Int64; -begin - // initialize the operands - a := VarPythonCreate(2); - Assert(VarIsPython(a)); - Assert(VarIsPythonNumber(a)); - Assert(VarIsPythonInteger(a)); - Assert(Integer(a) = 2); - - b := VarPythonCreate(3); - Assert(VarIsPython(b)); - Assert(VarIsPythonNumber(b)); - Assert(VarIsPythonInteger(b)); - Assert(Integer(b) = 3); - - // arithmetic operations - //---------------------- - - // addition - c := a + b; - // check result of operation - Assert( Integer(c) = 5 ); - // check that operation did not change the content of operands. - Assert(Integer(a) = 2); - Assert(Integer(b) = 3); - // now with a litteral - c := a + b + 1; - Assert( Integer(c) = 6 ); - c := a + 1 + b; - Assert( Integer(c) = 6 ); - c := 1 + a + b; - Assert( Integer(c) = 6 ); - - // substraction - c := b - a; - Assert( Integer(c) = 1 ); - // now with a litteral - c := b - a - 1; - Assert( Integer(c) = 0 ); - c := b - 1 - a; - Assert( Integer(c) = 0 ); - c := 1 - b - a; - Assert( Integer(c) = -4 ); - - // multiplication - c := a * b; - Assert( Integer(c) = 6 ); - // now with a litteral - c := a * b * 2; - Assert( Integer(c) = 12 ); - c := a * 2 * b; - Assert( Integer(c) = 12 ); - c := 2 * a * b; - Assert( Integer(c) = 12 ); - - // integer division - c := b div a; - Assert( Integer(c) = 1 ); - - // division: in Python a division between 2 integers is the same as the integer division - c := b / a; - Assert( c = 1.5 ); - Assert( Integer(c) = 2 ); - - // modulus - c := b mod a; - Assert( Integer(c) = 1 ); - c := BuiltinModule.divmod(b, a); // this returns a tuple whose first item is the result of the division, - // and second item the modulo. - if VarIsPythonSequence(c) and (c.Length = 2) then - begin - Assert(Integer(c.GetItem(0)) = 1); // division - Assert(Integer(c.GetItem(1)) = 1); // modulo - end; - - // power - c := BuiltinModule.pow(a, b); - Assert(c = 8); - - // negation - c := -a; - Assert( Integer(c) = -2 ); - - // logical operations - //------------------ - - // inverse - c := not a; // in python it would be: c = ~2 - Assert( Integer(c) = -3 ); - - // shift left (<<) - c := a shl b; - Assert( Integer(c) = 16 ); - c := a shl 1; - Assert( Integer(c) = 4 ); - - // shift right (>>) - c := a shl b; - c := c shr b; - Assert( Integer(c) = Integer(a) ); - c := b shr 1; - Assert( Integer(c) = 1 ); - - // and - c := a and (a*5); - Assert( Integer(c) = Integer(a) ); - c := a and 6; - Assert( Integer(c) = Integer(a) ); - - // or - c := a or b; - Assert( Integer(c) = 3 ); - c := a or 3; - Assert( Integer(c) = 3 ); - - // xor - c := a xor b; - Assert( Integer(c) = 1 ); - c := a xor 3; - Assert( Integer(c) = 1 ); - - // comparisons - //------------ - - // equal - c := a = b; - Assert(c = False); - c := a = a; - Assert(c = True); - Assert( a = 2); - - // not equal - c := a <> b; - Assert(c = True); - Assert( not (c = b) ); - c := a <> a; - Assert(c = False); - Assert( a = 2); - - // greater than - c := a > b; Assert(c = False); - c := b > a; Assert(c = True); - Assert( a > 1); - - // greater or equal than - c := a >= b; Assert(c = False); - c := b >= a; Assert(c = True); - c := a >= a; Assert(c = True); - Assert( a >= 2 ); - - // less than - c := a < b; Assert(c = True); - c := b < a; Assert(c = False); - Assert( a < 6); - - // less or equal than - c := a <= b; Assert(c = True); - c := b <= a; Assert(c = False); - c := a <= a; Assert(c = True); - Assert( a <= 2); - - // parenthesis - c := a * ((a * b) div b); - Assert( c = a*2 ); - - // copy - c := a; - Assert( c = a); - Assert( VarIsSame(c, a) ); // checks if 2 variants share the same Python object. - - // test long long (Int64) - big := Int64(MaxInt)*4; - b := VarPythonCreate(big); - Assert( b = big ); - Assert( b <> big+1 ); - Assert( b > MaxInt ); - Assert( MaxInt < b ); - Assert( b+1 = big+1 ); - Assert( b*2 = big*2 ); - Assert( b div 2 = big div 2 ); - c := VarPythonCreate(True); - Assert(VarIsBool(c)); - Assert(VarIsTrue(c)); - c := VarPythonCreate(False); - Assert(VarIsBool(c)); - Assert(not VarIsTrue(c)); - - // Done! - Log('Integer test was Ok.'); -end; - -procedure TMain.btnTestFloatsClick(Sender: TObject); -var - a, b, c : Variant; - dbl_a, dbl_b, dbl_c : Double; - int : Integer; -begin - // initialize the operands - dbl_a := 2.5; - a := VarPythonCreate(dbl_a); - Assert(VarIsPython(a)); - Assert(VarIsPythonNumber(a)); - Assert(VarIsPythonFloat(a)); - Assert(Double(a) = 2.5); - - dbl_b := 3.2; - b := VarPythonCreate(dbl_b); - Assert(VarIsPython(b)); - Assert(VarIsPythonNumber(b)); - Assert(VarIsPythonFloat(b)); - Assert(Double(b) = dbl_b); // note that Assert(Double(b) = 3.2) fails. - - // arithmetic operations - //---------------------- - - // addition - c := a + b; - // check result of operation - Assert( Double(c) = (dbl_a + dbl_b) ); - // check that operation did not change the content of operands. - Assert(Double(a) = dbl_a); - Assert(Double(b) = dbl_b); - // now with a litteral - c := a + b + 1; - Assert( Double(c) = (dbl_a+dbl_b+1) ); - c := a + 1 + b; - Assert( Double(c) = (dbl_a+1+dbl_b) ); - c := 1 + a + b; - Assert( Double(c) = (1+dbl_a+dbl_b) ); - - // substraction - c := b - a; - Assert( Double(c) = (dbl_b - dbl_a) ); - // now with a litteral - c := b - a - 1; - Assert( Double(c) = (dbl_b-dbl_a-1) ); - c := b - 1 - a; - Assert( Double(c) = (dbl_b-1-dbl_a) ); - c := 1 - b - a; - Assert( Double(c) = (1-dbl_b-dbl_a) ); - - // multiplication - c := a * b; - dbl_c := dbl_a * dbl_b; - Assert( Double(c) = dbl_c ); - // now with a litteral - c := a * b * 2; - dbl_c := dbl_a * dbl_b * 2; - Assert( Double(c) = dbl_c ); - c := a * 2 * b; - dbl_c := dbl_a * 2 * dbl_b; - Assert( Double(c) = dbl_c ); - c := 2 * a * b; - dbl_c := 2 * dbl_a * dbl_b; - Assert( Double(c) = dbl_c ); - - // division: in Python a division between 2 integers is the same as the integer division - c := b / a; - dbl_c := dbl_b / dbl_a; - Assert( Double(c) = dbl_c ); - - // negation - c := -a; - Assert( Double(c) = -dbl_a ); - - // comparisons - //------------ - - // equal - c := a = b; - Assert(c = False); - c := a = a; - Assert(c = True); - Assert( a = dbl_a); - - // not equal - c := a <> b; - Assert(c = True); - Assert( not (c = b) ); - c := a <> a; - Assert(c = False); - Assert( a = dbl_a); - - // greater than - c := a > b; Assert(c = False); - c := b > a; Assert(c = True); - Assert( a > (dbl_a-1)); - - // greater or equal than - c := a >= b; Assert(c = False); - c := b >= a; Assert(c = True); - c := a >= a; Assert(c = True); - Assert( a >= dbl_a ); - - // less than - c := a < b; Assert(c = True); - c := b < a; Assert(c = False); - Assert( a < dbl_b); - - // less or equal than - c := a <= b; Assert(c = True); - c := b <= a; Assert(c = False); - c := a <= a; Assert(c = True); - Assert( a <= dbl_a); - - // parenthesis - c := a * ((a * b) / b); - dbl_c := dbl_a * ((dbl_a * dbl_b) / dbl_b); - Assert( c = dbl_c ); - - // copy - c := a; - Assert( c = a); - Assert( VarIsSame(c, a) ); // checks if 2 variants share the same Python object. - - // casts - int := a; - Assert(int = 2); - - // Done! - Log('Float test was Ok.'); -end; - -procedure TMain.btnTestStringsClick(Sender: TObject); -var - a, b, c : Variant; - w : WideString; - _obj : PPyObject; -begin - // initialize the operands - a := VarPythonCreate('abc'); - Assert(VarIsPython(a)); - Assert(VarIsPythonString(a)); - Assert(String(a) = 'abc'); - - b := VarPythonCreate('def'); - Assert(VarIsPython(b)); - Assert(VarIsPythonString(b)); - Assert(String(b) = 'def'); - - // concatenation - c := a + b; - // check result of operation - Assert( String(c) = 'abcdef' ); - // check that operation did not change the content of operands. - Assert(String(a) = 'abc'); - Assert(String(b) = 'def'); - // now with a litteral - c := a + b + '!'; - Assert( String(c) = 'abcdef!' ); - c := a + '!' + b; - Assert( String(c) = 'abc!def' ); - c := '!' + a + b; - Assert( String(c) = '!abcdef' ); - - // multiplication - c := a * 3; // in Python the multiplication of string concatenates n times the string - Assert( String(c) = 'abcabcabc' ); - - // comparisons - //------------ - - // equal - c := a = b; - Assert(c = False); - c := a = a; - Assert(c = True); - Assert( a = 'abc'); - - // not equal - c := a <> b; - Assert(c = True); - Assert( not (c = b) ); - c := a <> a; - Assert(c = False); - Assert( a = 'abc'); - - // greater than - c := a > b; Assert(c = False); - c := b > a; Assert(c = True); - Assert( a > 'aaa'); - - // greater or equal than - c := a >= b; Assert(c = False); - c := b >= a; Assert(c = True); - c := a >= a; Assert(c = True); - Assert( a >= 'abc' ); - - // less than - c := a < b; Assert(c = True); - c := b < a; Assert(c = False); - Assert( a < 'bbb'); - - // less or equal than - c := a <= b; Assert(c = True); - c := b <= a; Assert(c = False); - c := a <= a; Assert(c = True); - Assert( a <= 'abc'); - - // copy - c := a; - Assert( c = a); - Assert( VarIsSame(c, a) ); // checks if 2 variants share the same Python object. - - // empty strings - a := VarPythonCreate(''); - Assert(a.length = 0); - Assert(a = ''); - Assert(String(a) = ''); - - // Unicode strings - b := VarPythonEval( 'u"Hello world!"' ); - Assert( VarIsPythonUnicode(b) ); - w := PythonEngine1.PyUnicode_AsWideString(ExtractPythonObjectFrom(b)); - Assert( w = 'Hello world!'); - Assert( b = 'Hello world!'); - Assert( b <> a ); - _obj := PythonEngine1.PyUnicode_FromWideString(w); - try - c := VarPythonCreate( _obj ); - finally - PythonEngine1.Py_XDecRef(_obj); - end; - Assert(b = c); - Assert(c = w); - Assert( c = 'Hello world!'); - w := b; - Assert( b = w); - Assert( w = 'Hello world!'); - Assert( Length(w) = 12 ); - Assert( Length(w) = b.Length() ); - c := PythonEngine1.PyObjectAsVariant(ExtractPythonObjectFrom(b)); - Assert( c = b ); - Assert( c = w ); - Assert( c = 'Hello world!'); - {$IFDEF UNICODE} - Assert( VarType(c) and VarTypeMask = varUString ); - {$ELSE} - Assert( VarType(c) and VarTypeMask = varOleStr ); - {$ENDIF} - c := VarPythonCreate(w); - Assert( c = 'Hello world!'); - Assert( c = w ); - c := VarPythonCreate([w]); - Assert( VarIsPythonUnicode(c.GetItem(0)) ); - Assert( c.GetItem(0) = 'Hello world!'); - Assert( c.GetItem(0) = w ); - {$IFDEF PREFER_UNICODE} - c := w; - b := VarPythonCreate(c); - Assert( VarIsPythonUnicode(b) ); - Assert( b = c ); - Assert( b = w ); - {$ENDIF} - // empty strings - a := VarPythonEval( 'u""' ); - Assert(a.length = 0); - Assert(a = ''); - Assert(String(a) = ''); - Assert(WideString(a) = ''); - - // Done! - Log('String test was Ok.'); -end; - -procedure TMain.btnTestSequencesClick(Sender: TObject); -var - a, b, c : Variant; - iter : Variant; - cpt : Integer; -begin - // initialize the operands - // you can either use the overloaded function with an array of const - // or use the VarArrayOf function that returns an array of variants that will - // be casted to a Python list. - a := VarPythonCreate([1, 2, 3]); - Assert(VarIsPython(a)); - Assert(VarIsPythonSequence(a)); - Assert(VarIsPythonList(a)); - Assert(a.Length = 3); // this is a special property that does the same as: len(a) in Python - Assert(a.Length() = 3); // this is a special method that does the same as the special property - Assert(len(a) = 3); - Assert(a.GetItem(0) = 1); // this is a special method that lets you do the same as: a[0] in Python - Assert(a.GetItem(1) = 2); - Assert(a.GetItem(2) = 3); - Assert(String(a) = '[1, 2, 3]'); - // indexed access using brackets when the sequence is a property of an object (module, instance...) - MainModule.a := VarPythonCreate([1, 2, 3]); - Assert(MainModule.a[1] = 2); - - b := VarPythonCreate(VarArrayOf([4, 5, 6])); - Assert(VarIsPython(b)); - Assert(VarIsPythonSequence(b)); - Assert(VarIsPythonList(b)); - Assert(b.Length = 3); - Assert(b.Length() = 3); - Assert(len(b) = 3); - Assert(b.GetItem(0) = 4); - Assert(b.GetItem(1) = 5); - Assert(b.GetItem(2) = 6); - Assert(String(b) = '[4, 5, 6]'); - - // concatenation - c := a + b; - // check result of operation - Assert(String(c) = '[1, 2, 3, 4, 5, 6]'); - // check that operation did not change the content of operands. - Assert(String(a) = '[1, 2, 3]'); - Assert(String(b) = '[4, 5, 6]'); - // now with a litteral: note that with D6 SP1, we can't concatenate a custom variant with an var array of variants - c := a + b + VarPythonCreate(['Hello', 'World!', 3.14]); - {$IFDEF UNICODE} - Assert( String(c) = '[1, 2, 3, 4, 5, 6, u''Hello'', u''World!'', 3.1400000000000001]' ); - {$ELSE} - Assert( String(c) = '[1, 2, 3, 4, 5, 6, ''Hello'', ''World!'', 3.1400000000000001]' ); - {$ENDIF} - c := a + VarPythonCreate(['Hello', 'World!', 3.14]) + b; - {$IFDEF UNICODE} - Assert( String(c) = '[1, 2, 3, u''Hello'', u''World!'', 3.1400000000000001, 4, 5, 6]' ); - {$ELSE} - Assert( String(c) = '[1, 2, 3, ''Hello'', ''World!'', 3.1400000000000001, 4, 5, 6]' ); - {$ENDIF} - c := VarPythonCreate(['Hello', 'World!', 3.14]) + a + b; - {$IFDEF UNICODE} - Assert( String(c) = '[u''Hello'', u''World!'', 3.1400000000000001, 1, 2, 3, 4, 5, 6]' ); - {$ELSE} - Assert( String(c) = '[''Hello'', ''World!'', 3.1400000000000001, 1, 2, 3, 4, 5, 6]' ); - {$ENDIF} - - // multiplication - c := a * 3; // in Python the multiplication of sequence concatenates n times the sequence - Assert( String(c) = '[1, 2, 3, 1, 2, 3, 1, 2, 3]' ); - - // comparisons - //------------ - - // equal - c := a = b; - Assert(c = False); - c := a = a; - Assert(c = True); - Assert( String(a) = '[1, 2, 3]'); - - // not equal - c := a <> b; - Assert(c = True); - Assert( not (c = b) ); - c := a <> a; - Assert(c = False); - Assert( String(a) = '[1, 2, 3]'); - - // greater than - c := a > b; Assert(c = False); - c := b > a; Assert(c = True); - Assert( String(a) > '[1, 1, 1]'); - - // greater or equal than - c := a >= b; Assert(c = False); - c := b >= a; Assert(c = True); - c := a >= a; Assert(c = True); - Assert( String(a) >= '[1, 2, 3]' ); - - // less than - c := a < b; Assert(c = True); - c := b < a; Assert(c = False); - Assert( String(a) < '[4, 4, 4]'); - - // less or equal than - c := a <= b; Assert(c = True); - c := b <= a; Assert(c = False); - c := a <= a; Assert(c = True); - Assert( String(a) <= '[1, 2, 3]'); - - // copy - c := a; - Assert( c = a); - Assert( VarIsSame(c, a) ); // checks if 2 variants share the same Python object. - - // sequence methods: - c := b + a; - c.sort(); // note that you must you the parenthesis to distinguish the call between a method or a property. - Assert( c = (a+b) ); - - c := NewPythonList; // facility for building sequences - Assert( not VarIsTrue(c) ); // c is false because it's an empty collection - c.append(1); - c.append(2); - c.append(3); - Assert( VarIsTrue(c) ); // c is true because it's not an empty collection - Assert(c = a); - Assert( c.pop() = 3 ); - Assert( String(c) = '[1, 2]'); - - c := NewPythonList(3); // facility for building sequences - c.SetItem(0, 1); - c.SetItem(1, 2); - c.SetItem(2, 3); - Assert(c = a); - c.DeleteItem(1); - Assert(c = VarPythonCreate([1,3])); - - Assert(VarPythonCreate([1,2,3,4]).GetSlice(1, 3) = VarPythonCreate([2,3])); // same as x = [1,2,3,4]; x[1:3] - Assert(VarPythonCreate([1,2,3,4]).GetSlice(1, Ellipsis) = VarPythonCreate([2,3,4])); // same as x = [1,2,3,4]; x[1:] - Assert(VarPythonCreate([1,2,3,4]).GetSlice(1, -1) = VarPythonCreate([2,3])); // same as x = [1,2,3,4]; x[1:-1] - c := VarPythonCreate([1,2,3,4]); - c.SetSlice(1, 3, VarPythonCreate([7, 8, 9])); - Assert( c = VarPythonCreate([1, 7, 8, 9, 4]) ); - Assert( Boolean(c.Contains( 7 )) ); // same as 7 in c - Assert( not Boolean(c.Contains( 77 )) ); - c.DelSlice(1,3); - Assert( c = VarPythonCreate([1,9,4]) ); - - c := VarPythonCreate([1, 2, 3, 4], stTuple); // test a tuple - Assert( VarIsPythonTuple(c) ); - Assert( VarIsPythonSequence(c) ); - Assert( c.GetItem(1) = 2 ); - Assert( c.Length = 4 ); - c := NewPythonTuple(3); - c.SetItem(0, 1); - c.SetItem(1, 2); - c.SetItem(2, 3); - Assert( VarIsPythonTuple(c) ); - Assert( VarIsPythonSequence(c) ); - Assert( c.GetItem(1) = 2 ); - Assert( c.Length = 3 ); - Assert(not VarIsPythonIterator(c)); - - // test iterator - iter := BuiltinModule.iter(VarPythonCreate([1, 2, 3, 4], stTuple)); - Assert(VarIsPythonIterator(iter)); - Assert(iter.next() = 1); - Assert(iter.next() = 2); - Assert(iter.next() = 3); - Assert(iter.next() = 4); - try - iter.next(); - except - on E: EPyStopIteration do - begin - Assert(True); //Ok. - end - else - Assert(False, 'expected stop exception'); - end; - cpt := 0; - iter := VarPyth.iter(VarPythonCreate([1, 2, 3, 4], stTuple)); - Assert(VarIsPythonIterator(iter)); - try - while True do - begin - a := iter.next(); - Inc(cpt); - Assert(a = cpt); - end; - except - on E: EPyStopIteration do - begin - Assert(True); //Ok. - end - else - Assert(False, 'expected stop exception'); - end; - Assert(cpt = 4); - // Done! - Log('Sequence test was Ok.'); -end; - -procedure TMain.btnTestMappingsClick(Sender: TObject); -var - a, b, c, keys, values : Variant; -begin - // initialize the operands - a := NewPythonDict; - Assert(VarIsPython(a)); - Assert(VarIsPythonMapping(a)); - Assert(VarIsPythonDict(a)); - // There is a bug in D2010 in which Char('a') gets translated to integer parameter - a.SetItem( string('a'), 1 ); - a.SetItem( string('b'), 2 ); - a.SetItem( string('c'), 3 ); - Assert(a.Length = 3); // this is a special property that does the same as: len(a) in Python - Assert(a.Length() = 3); // this is a special method that does the same as the special property - Assert(len(a) = 3); - Assert(a.GetItem(string('a')) = 1); // this is a special method that lets you do the same as: a[0] in Python - Assert(a.GetItem(string('b')) = 2); - Assert(a.GetItem(string('c')) = 3); - - - b := NewPythonDict; - Assert(VarIsPython(b)); - Assert(VarIsPythonMapping(b)); - Assert(VarIsPythonDict(b)); - b.SetItem( string('d'), 4 ); - b.SetItem( string('e'), 5 ); - b.SetItem( string('f'), 6 ); - Assert(b.Length = 3); - Assert(b.Length() = 3); - Assert(len(b) = 3); - Assert(b.GetItem(string('d')) = 4); - Assert(b.GetItem(string('e')) = 5); - Assert(b.GetItem(string('f')) = 6); - - // copy - c := a; - Assert( c = a); - Assert( VarIsSame(c, a) ); // checks if 2 variants share the same Python object. - - // dict methods - Assert( Boolean(a.has_key(string('a'))) ); - Assert( not Boolean(a.has_key('abc')) ); - keys := a.keys(); - keys.sort(); - Assert( keys = VarPythonCreate(VarArrayOf(['a', 'b', 'c']))); - values := a.values(); - values.sort(); - Assert( values = VarPythonCreate(VarArrayOf([1, 2, 3]))); - c := a; - c.DeleteItem(string('a')); - Assert( not Boolean(c.has_key(string('a'))) ); - - // test string values - a := NewPythonDict; - a.SetItem( string('a'), 'Hello'); - a.SetItem( string('b'), 'World!'); - a.SetItem( string('c'), ''); - Assert(a.GetItem(string('a')) = 'Hello'); - Assert(a.GetItem(string('b')) = 'World!'); - Assert(a.GetItem(string('c')) = ''); - - // Done! - Log('Mapping test was Ok.'); -end; - -procedure TMain.btnTestDatesClick(Sender: TObject); -var - a, b, _timeMod : Variant; - c : Variant; - _date, _date2 : TDateTime; - _year, _month, _day : Word; - _year2, _month2, _day2 : Word; - _hour, _min, _sec, _msec : Word; - _hour2, _min2, _sec2, _msec2 : Word; -begin - _timeMod := Import('time'); // get the time module of Python - - _date := Now; - DecodeDate( _date, _year, _month, _day ); - DecodeTime( _date, _hour, _min, _sec, _msec ); - - b := _timeMod.localtime(_timeMod.time()); // same as Now in Delphi - - a := VarPythonCreate(_date); - Assert( a.Length = 9 ); - Assert( a.GetItem(0) = _year ); - Assert( a.GetItem(1) = _month ); - Assert( a.GetItem(2) = _day ); - Assert( a.GetItem(3) = _hour ); - Assert( a.GetItem(4) = _min ); - Assert( a.GetItem(5) = _sec ); - Assert( b.Length = 9 ); - Assert( b.GetItem(0) = a.GetItem(0) ); - Assert( b.GetItem(1) = a.GetItem(1) ); - Assert( b.GetItem(2) = a.GetItem(2) ); - Assert( b.GetItem(3) = a.GetItem(3) ); - Assert( b.GetItem(4) = a.GetItem(4) ); - Assert( b.GetItem(5) = a.GetItem(5) ); - Assert( b.GetItem(6) = a.GetItem(6) ); - Assert( b.GetItem(7) = a.GetItem(7) ); - // don't test the 9th item of the tuple, because it's the daylight saving, - // and it's not computed by the Python for Delphi. - //Assert( b.GetItem(8) = a.GetItem(8) ); - - _date2 := b; - DecodeDate( _date2, _year2, _month2, _day2 ); - DecodeTime( _date2, _hour2, _min2, _sec2, _msec2 ); - Assert( _year2 = _year ); - Assert( _month2 = _month ); - Assert( _day2 = _day ); - Assert( _hour2 = _hour ); - Assert( _min2 = _min ); - Assert( _sec2 = _sec ); - - // test new datetime module - _timeMod := Import('datetime'); // get the datetime module of Python - //or _timeMod := DatetimeModule; // get the datetime module of Python - - a := _timeMod.datetime(2002, 12, 30, 22, 15, 38, 827738); - Assert(VarIsPythonDateTime(a)); - Assert(VarIsPythonDate(a)); - Assert(not VarIsPythonTime(a)); - Assert(not VarIsPythonDateTimeDelta(a)); - Assert(a.year = 2002); - Assert(a.month = 12); - Assert(a.day = 30); - Assert(a.hour = 22); - Assert(a.minute = 15); - Assert(a.second = 38); - Assert(a.microsecond = 827738); - - _date := a; - DecodeDate( _date, _year, _month, _day ); - DecodeTime( _date, _hour, _min, _sec, _msec ); - Assert(_year = 2002); - Assert(_month = 12); - Assert(_day = 30); - Assert(_hour = 22); - Assert(_min = 15); - Assert(_sec = 38); - Assert(_msec = 827738 div 1000); - - a := _timeMod.date(2002, 12, 30); - Assert(not VarIsPythonDateTime(a)); - Assert(VarIsPythonDate(a)); - Assert(not VarIsPythonTime(a)); - Assert(not VarIsPythonDateTimeDelta(a)); - _date := a; - DecodeDate( _date, _year, _month, _day ); - DecodeTime( _date, _hour, _min, _sec, _msec ); - Assert(_year = 2002); - Assert(_month = 12); - Assert(_day = 30); - Assert(_hour = 0); - Assert(_min = 0); - Assert(_sec = 0); - Assert(_msec = 0); - Assert(a.year = 2002); - Assert(a.month = 12); - Assert(a.day = 30); - - a := _timeMod.time(22, 15, 38, 827738); - Assert(not VarIsPythonDateTime(a)); - Assert(not VarIsPythonDate(a)); - Assert(VarIsPythonTime(a)); - Assert(not VarIsPythonDateTimeDelta(a)); - Assert(a.hour = 22); - Assert(a.minute = 15); - Assert(a.second = 38); - Assert(a.microsecond = 827738); - _date := a; - DecodeTime( _date, _hour, _min, _sec, _msec ); - Assert(_hour = 22); - Assert(_min = 15); - Assert(_sec = 38); - Assert(_msec = 827738 div 1000); - - a := DatetimeModule.datetime(2002, 12, 30, 22, 15, 38, 827738); - b := _timeMod.datetime(2002, 12, 30, 22, 16, 38, 827738); - c := b - a; - Assert(VarIsPythonDateTimeDelta(c)); - Assert(c.days = 0); - Assert(c.seconds = 60); - Assert(c.microseconds = 0); - _date := c; - Assert(Trunc(_date)=0); - DecodeTime( _date, _hour, _min, _sec, _msec ); - Assert(_hour = 0); - Assert(_min = 1); - Assert(_sec = 0); - Assert(_msec = 0); - - c := a - b; - Assert(VarIsPythonDateTimeDelta(c)); - Assert(c.days = -1); - Assert(c.seconds = 86340); - Assert(c.microseconds = 0); - _date := c; - Assert(Trunc(_date)=0); - Assert(_date<0); - DecodeTime( _date, _hour, _min, _sec, _msec ); - Assert(_hour = 0); - Assert(_min = 1); - Assert(_sec = 0); - Assert(_msec = 0); - - c := a + (b-a); - Assert(VarIsPythonDateTime(c)); - Assert(c = b); - Assert(c <> a); - Assert(a < b); - Assert(b > a); - - GetPythonEngine.DatetimeConversionMode := dcmToDatetime; - try - _date := EncodeDate(2003, 01, 28) + EncodeTime(12, 22, 33, 450); - a := VarPythonCreate(_date); - Assert(VarIsPythonDateTime(c)); - _date2 := a; - DecodeDate( _date, _year, _month, _day ); - DecodeTime( _date, _hour, _min, _sec, _msec ); - DecodeDate( _date2, _year2, _month2, _day2 ); - DecodeTime( _date2, _hour2, _min2, _sec2, _msec2 ); - Assert( _year2 = _year ); - Assert( _month2 = _month ); - Assert( _day2 = _day ); - Assert( _hour2 = _hour ); - Assert( _min2 = _min ); - Assert( _sec2 = _sec ); - Assert( _msec2 = _msec ); - Assert(a.year = 2003); - Assert(a.month = 01); - Assert(a.day = 28); - Assert(a.hour = 12); - Assert(a.minute = 22); - Assert(a.second = 33); - Assert(a.microsecond = 450000); - finally - GetPythonEngine.DatetimeConversionMode := dcmToTuple; - end; - // Done! - Log('Dates test was Ok.'); -end; - -procedure TMain.btnTestObjectsClick(Sender: TObject); -var - _main, f, a, b, c : Variant; - val : Integer; - _folder, _str : String; - _myModule : Variant; -begin - PythonEngine1.ExecStrings(Memo2.Lines); - _main := MainModule; - Assert( VarIsPythonModule(_main) ); - Assert( VarIsPythonModule(SysModule) ); - Assert( Import('sys').version = SysModule.version ); - Assert( Boolean(SysModule.modules.has_key(GetPythonEngine.ExecModule)) ); // if __main__ in sys.modules - Assert( VarIsSameType(_main, SysModule) ); - Assert( _type(_main).__name__ = 'module'); - Assert( BuiltinModule.type(_main).__name__ = 'module'); - - Assert( VarIsPythonClass(_main.Foo) ); - Assert( VarIsPythonClass(_main.Bar) ); - Assert( VarIsPythonClass(_main.XYZ) ); - Assert( not VarIsPythonClass(_main.Foo.__add__) ); - Assert( not VarIsPythonClass(_main.f) ); - Assert( VarIsPythonCallable(_main.Foo) ); - Assert( VarIsPythonCallable(_main.Foo) ); - Assert( VarIsTrue(BuiltinModule.callable(_main.Foo)) ); - Assert( VarIsPythonInstance(_main.f) ); - Assert( VarIsSame(_main.f.__class__, _main.Foo) ); - Assert( VarIsPythonMethod(_main.f.Inc) ); - Assert( VarIsPythonCallable(_main.f.Inc) ); - Assert( VarIsTrue(BuiltinModule.callable(_main.f.Inc)) ); - Assert( VarIsPythonFunction(_main.Add) ); - Assert( VarIsPythonCallable(_main.Add) ); - Assert( VarIsInstanceOf(_main.f, _main.Foo) ); - Assert( VarIsTrue(BuiltinModule.isinstance(_main.f, _main.Foo)) ); - Assert( VarIsSubclassOf(_main.Bar, _main.Foo) ); - Assert( VarIsTrue(BuiltinModule.issubclass(_main.Bar, _main.Foo)) ); - Assert( not VarIsSubclassOf(_main.Foo, _main.Bar) ); - Assert( VarIsInstanceOf(_main.b, _main.Foo) ); - Assert( not VarIsInstanceOf(_main.f, _main.Bar) ); - Assert( VarIsTrue( BuiltinModule.vars(_main).has_key(string('f')) ) ); - Assert( VarIsTrue( BuiltinModule.dir(_main).Contains(string('f')) ) ); - - f := _main.Foo(); // new instance of class Foo - Log('Instanciate class Foo: ' + f); - f.Inc(); // call a method without any arg, because there's a default arg. - f.Inc(2); // call a method with one arg, overriding the default arg. - Assert( VarIsPythonNumber(f.Value) ); - Assert( VarIsPythonInteger(f.Value) ); - Assert( f.Value = _main.f.Value ); // compare the result with what we did in the script - Assert( f.GetValue() = _main.f.GetValue() ); // compare the result with what we did in the script - Assert( VarIsPython( f.GetSelf() ) ); - Assert( VarIsSame( f.GetSelf(), f ) ); - Assert( BuiltinModule.getattr(f, 'Value') = f.Value ); - // python (+) operator overloading - a := _main.Foo(10); - b := _main.Foo(5); - c := a + b; - Assert(a.Value = 10); - Assert(b.Value = 5); - Assert(c.Value = 15); - Log('Test -> a, b, c : ' + a.Value + ', ' + b.Value + ', ' + c.Value); - // cascading calls - Assert( f.GetSelf().GetSelf().GetSelf().GetSelf().GetValue() = _main.f.GetValue() ); - Assert( Boolean(f.__dict__.has_key('Value')) ); - Assert( VarIsTrue( BuiltinModule.hasattr(f, 'Value') ) ); - _str := 'Value'; - Assert( Boolean(f.__dict__.has_key(_str)) ); // check with a string var - Assert( Boolean( BuiltinModule.hasattr(f, _str) ) ); - val := f.Value; - f.Add(f); // passing itself as an argument - Assert( f.Value = val*2 ); - // check param order - f.SetABC(1, 2, 3); - Assert(f.A = 1); - Assert(f.B = 2); - Assert(f.C = 3); - // add a property to an instance - f.Z := 99; - Assert(f.Z = 99); - // add a var to a module - _main.Z := 99; - Assert(_main.Z = 99); - // check none - Assert( VarIsNone(None) ); - Assert( VarIsNone(VarPythonCreate([1, Null, 3]).GetItem(1)) ); // Null is casted to None - Assert( VarIsNone(VarPythonCreate([1, None, 3]).GetItem(1)) ); - Assert( VarIsNone(f.Inc()) ); - Assert( f.Inc() = None ); - Assert( not Boolean(None) ); // if not None: - Assert( not VarIsTrue(None) ); // if not None: - Assert( Boolean(f) ); // if f: - Assert( VarIsTrue(f) ); // if f: - - // call a function - Assert( _main.Add(2, 2) = 4 ); - // call a function with a mix of regular parameters and named parameters - f := _main.MakeList(1, 2, 3, 4); - Assert(VarIsPythonList(f)); - Assert(f.Length = 4); - Assert(f.GetItem(0) = 1); - Assert(f.GetItem(1) = 2); - Assert(f.GetItem(2) = 3); - Assert(f.GetItem(3) = 4); - f := _main.MakeList(1, d:=3, c:=4, b:=2); - Assert(VarIsPythonList(f)); - Assert(f.Length = 4); - Assert(f.GetItem(0) = 1); - Assert(f.GetItem(1) = 2); - Assert(f.GetItem(2) = 4); - Assert(f.GetItem(3) = 3); - f := _main.MakeList(1, 2, d:= 3, c:=4); - Assert(VarIsPythonList(f)); - Assert(f.Length = 4); - Assert(f.GetItem(0) = 1); - Assert(f.GetItem(1) = 2); - Assert(f.GetItem(2) = 4); - Assert(f.GetItem(3) = 3); - f := _main.MakeList(1, 2, 3, d:=4); - Assert(VarIsPythonList(f)); - Assert(f.Length = 4); - Assert(f.GetItem(0) = 1); - Assert(f.GetItem(1) = 2); - Assert(f.GetItem(2) = 3); - Assert(f.GetItem(3) = 4); - f := _main.MakeList(b:=1, a:=2, d:= 3, c:=4); - Assert(VarIsPythonList(f)); - Assert(f.Length = 4); - Assert(f.GetItem(0) = 2); - Assert(f.GetItem(1) = 1); - Assert(f.GetItem(2) = 4); - Assert(f.GetItem(3) = 3); - - // importing an external module and using it - // first, extend the path with our current folder - _folder := ExtractFilePath(Application.ExeName); - if (Length(_folder) > 0) and (_folder[Length(_folder)] = '\') then - Delete(_folder, Length(_folder), 1); - if not Boolean(SysModule.path.Contains(_folder)) then - SysModule.path.insert(0, _folder); - // import the module - _myModule := Import('MyModule'); - // call one of his functions - Assert( _myModule.Add(2, 2) = 4 ); - // delete module var f - _main.__dict__.DeleteItem(string('f')); - Assert( _main.__dict__.has_key(string('f')) = False ); - // open a file using Python - if FileExists('MyModule.py') then - begin - f := BuiltinModule.open('MyModule.py', string('r')).readlines(); - with TStringList.Create do - try - LoadFromFile('MyModule.py'); - Assert( len(f) = Count); - finally - Free; // TStringList - end; // of try - end; // of if - // Done! - Log('Objects test was Ok.'); -end; - -procedure TMain.RunSelectedTests; -begin - if cbIntegers.Checked then - btnTestIntegersClick(nil); - if cbFloats.Checked then - btnTestFloatsClick(nil); - if cbStrings.Checked then - btnTestStringsClick(nil); - if cbSequences.Checked then - btnTestSequencesClick(nil); - if cbMappings.Checked then - btnTestMappingsClick(nil); - if cbDates.Checked then - btnTestDatesClick(nil); - if cbObjects.Checked then - btnTestObjectsClick(nil); -end; - -procedure TMain.btnRunSelectedTestsClick(Sender: TObject); -begin - RunSelectedTests; -end; - -procedure TMain.btnRunNTimesClick(Sender: TObject); -var - i, _count : Integer; -begin - _count := StrToInt(edtTestCount.Text)-1; - fVerbose := False; - PythonEngine1.RedirectIO := False; - ProgressBar1.Visible := True; - try - for i := 0 to _count do - begin - ProgressBar1.Position := i * 100 div _count; - ProgressBar1.Update; - RunSelectedTests; - end; - finally - fVerbose := True; - PythonEngine1.RedirectIO := True; - ProgressBar1.Visible := False; - end; -end; - -procedure TMain.FormCreate(Sender: TObject); -begin - fVerbose := True; -end; - -end. diff --git a/demos_delphi/Demo26/Project1.dpr b/demos_delphi/Demo26/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo26/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo26/Project1.dproj b/demos_delphi/Demo26/Project1.dproj deleted file mode 100644 index c8ea281..0000000 --- a/demos_delphi/Demo26/Project1.dproj +++ /dev/null @@ -1,100 +0,0 @@ - - - {910E2A03-F875-4153-9E58-3434C6D9AB6F} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo26/Project1.res b/demos_delphi/Demo26/Project1.res deleted file mode 100644 index f928fd9..0000000 Binary files a/demos_delphi/Demo26/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo26/Unit1.dfm b/demos_delphi/Demo26/Unit1.dfm deleted file mode 100644 index cf78062..0000000 Binary files a/demos_delphi/Demo26/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo26/Unit1.pas b/demos_delphi/Demo26/Unit1.pas deleted file mode 100644 index 2543760..0000000 --- a/demos_delphi/Demo26/Unit1.pas +++ /dev/null @@ -1,274 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - PythonEngine1: TPythonEngine; - PythonModule1: TPythonModule; - PythonType1: TPythonType; - Panel1: TPanel; - Button1: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure PythonType1Initialization(Sender: TObject); - private - { D�clarations priv�es } - public - { D�clarations publiques } - end; - - // This is a Delphi class implementing a new Python type - // it must derive from TPyObject or one of its descendants. - // Then it must override some methods, like the constructors, - // the RegisterMethods and the type services' virtual methods. - TPyPoint = class(TPyObject) - x, y : Integer; - Name : String; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - - // Type services - //////////////// - - // Basic services - function Repr : PPyObject; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - class procedure RegisterMembers( PythonType : TPythonType ); override; - class procedure RegisterGetSets( PythonType : TPythonType ); override; - - // Methods of TPyPoint - procedure OffsetBy( dx, dy : Integer ); - - // Interface methods - function DoOffsetBy( args : PPyObject ) : PPyObject; cdecl; - function DoRaiseError( args : PPyObject ) : PPyObject; cdecl; - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -// First, we need to initialize the property PyObjectClass with -// the class of our Type object -procedure TForm1.PythonType1Initialization(Sender: TObject); -begin - PythonType1.PyObjectClass := TPyPoint; -end; - -// We override the constructors - -constructor TPyPoint.Create( APythonType : TPythonType ); -begin - inherited; - x := 0; - y := 0; -end; - -// Don't call the Create constructor of TPyPoint, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyPoint.Create will be automatically be called. - -constructor TPyPoint.CreateWith( PythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'ii:CreatePoint',@x, @y ) = 0 then - exit; - end; -end; - -// Then we override the needed services - -function TPyPoint.Repr : PPyObject; -begin - with GetPythonEngine do - Result := VariantAsPyObject(Format('(%d, %d)',[x, y])); - // or Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[x, y])) ); -end; - -// get/set functions -function TPyPoint_GetName( obj : PPyObject; context : Pointer) : PPyObject; cdecl; -begin - with GetPythonEngine do - Result := PyString_FromString(PAnsiChar(AnsiString(TPyPoint(PythonToDelphi(obj)).Name))); -end; - -function TPyPoint_SetName( obj, value : PPyObject; context : Pointer) : integer; cdecl; -begin - with GetPythonEngine do - begin - if PyString_Check(value) then - begin - TPyPoint(PythonToDelphi(obj)).Name := PyObjectAsVariant(value); - Result := 0; - end - else - begin - Result := -1; - PyErr_SetString(PyExc_AttributeError^, 'attribute Name expected a string value'); - end; - end; -end; - -// Class methods -// We register the methods of our type - -class procedure TPyPoint.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - AddMethod( 'OffsetBy', @TPyPoint.DoOffsetBy, 'Point.OffsetBy( dx, dy )' ); - AddMethod( 'RaiseError', @TPyPoint.DoRaiseError, 'Point.RaiseError()' ); - end; -end; - -class procedure TPyPoint.RegisterMembers( PythonType : TPythonType ); -begin - with PythonType do - begin - AddMember( 'x', mtInt, NativeInt(@TPyPoint(nil).x), mfDefault, 'x coordinate'); - AddMember( 'y', mtInt, NativeInt(@TPyPoint(nil).y), mfDefault, 'y coordinate'); - end; -end; - -class procedure TPyPoint.RegisterGetSets( PythonType : TPythonType ); -begin - with PythonType do - begin - AddGetSet('Name', TPyPoint_GetName, TPyPoint_SetName, 'Name of a point', nil); - end; -end; - -// Methods of TPyPoint -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -procedure TPyPoint.OffsetBy( dx, dy : Integer ); -begin - Inc( x, dx ); - Inc( y, dy ); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -function TPyPoint.DoOffsetBy( args : PPyObject ) : PPyObject; -var - dx, dy : Integer; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // first we extract the arguments - if PyArg_ParseTuple( args, 'ii:Point.Offset',@dx, @dy ) <> 0 then - begin - // if it's ok, then we call the method that does the job - // with the correct arguments - OffsetBy( dx, dy ); - // Finally, we return nothing - Result := ReturnNone; - end - else // the arguments were not right - Result := nil; - end; -end; - -// Here's an example of how you can raise errors defined -// in the module linked to our type. -function TPyPoint.DoRaiseError( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // This is a simple call: - //GetModule.RaiseError( 'PointError', 'this is an example of raising an error !' ); - // This is an advanced call: - // We provide the instance vars as a dictionary, so that we can intercept the - // error with "except" and extract informations from the error object. - // ArrayToPyDict needs a list of pairs: varName (string), varValue (anything) - GetModule.RaiseErrorObj( 'EBadPoint', 'this is an example of raising an error !', - ArrayToPyDict( ['a', 1, 'b', 2, 'c', 3] ) ); - Result := nil; - end; -end; - -///////////////////////////////////////////////// - - -procedure TForm1.Button1Click(Sender: TObject); -var - DelphiPoint : TPyPoint; - p : PPyObject; -begin - // Here's how you can create/read Python vars from Delphi with - // Delphi/Python objects. - - // You should ask to the TPythonType to create an instance of its type - // because it will do some initialization. You can use CreateInstanceWith - // if you want to transmit some Python arguments. - // We receive a Python object pointer - p := PythonType1.CreateInstance; - PythonEngine1.CheckError; - // Then we cast the python object to the right delphi type - DelphiPoint := TPyPoint( PythonToDelphi(p) ); - // We do some changes on the delphi object - DelphiPoint.X:=10; - DelphiPoint.Y:=20; - // Add variable "myPoint" in the module "spam". - // So you'll access to the var in the module called spam with: - // import spam - // print spam.myPoint - PythonModule1.SetVar( 'myPoint', p ); - PythonEngine1.Py_DecRef(p); - { - Of course, if you want to retrieve a Python var from a module, - just use the PythonModule1.GetVar or PythonModule1.GetVarAsVariant - Example: - p := PythonModule1.GetVar('myPoint'); - if Assigned(p) then - begin - DelphiPoint := PythonToDelphi(p) as TPyPoint; - ... - Py_XDecRef(p); - end; - - end; } - // Excecute the script - PythonEngine1.ExecStrings( memo1.Lines ); - // Add the following line at the end of the script: - // print spam.myPoint - - // Note, that you must not free the delphi point yourself. - // Instead use the GetPythonEngine.Py_XDECREF(obj) method, - // because the object may be used by another Python object. -end; - -end. diff --git a/demos_delphi/Demo27/Project1.dpr b/demos_delphi/Demo27/Project1.dpr deleted file mode 100644 index 513a1dd..0000000 --- a/demos_delphi/Demo27/Project1.dpr +++ /dev/null @@ -1,13 +0,0 @@ -program Project1; - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo27/Project1.dproj b/demos_delphi/Demo27/Project1.dproj deleted file mode 100644 index dd952b9..0000000 --- a/demos_delphi/Demo27/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {5A404EF7-3EA9-4DDC-AF3D-D6434CB20EEA} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 4105 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo27/Project1.res b/demos_delphi/Demo27/Project1.res deleted file mode 100644 index 9bf42ad..0000000 Binary files a/demos_delphi/Demo27/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo27/Unit1.dfm b/demos_delphi/Demo27/Unit1.dfm deleted file mode 100644 index 4113d5f..0000000 --- a/demos_delphi/Demo27/Unit1.dfm +++ /dev/null @@ -1,81 +0,0 @@ -object Form1: TForm1 - Left = 192 - Top = 114 - Width = 870 - Height = 640 - Caption = 'Form1' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - OldCreateOrder = False - PixelsPerInch = 96 - TextHeight = 13 - object Memo1: TMemo - Left = 56 - Top = 24 - Width = 745 - Height = 281 - TabOrder = 0 - end - object Memo2: TMemo - Left = 56 - Top = 320 - Width = 745 - Height = 217 - Lines.Strings = ( - 'import test' - 'S=test.CreateMySeq()' - 'print S' - 'print len(S)' - 'print S[1]' - 'print S[1,2]' - 'print S[1:2]' - 'print S[1:20:2]' - 'print S[...]' - 'print S[1,4,5:8, 10:20:2, ...]') - TabOrder = 1 - end - object Button1: TButton - Left = 56 - Top = 560 - Width = 201 - Height = 25 - Caption = 'Execute' - TabOrder = 2 - OnClick = Button1Click - end - object PythonEngine1: TPythonEngine - IO = PythonGUIInputOutput1 - Left = 40 - Top = 144 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - Output = Memo1 - Left = 40 - Top = 176 - end - object PythonModule1: TPythonModule - Engine = PythonEngine1 - ModuleName = 'test' - Errors = <> - Left = 40 - Top = 216 - end - object PythonType1: TPythonType - Engine = PythonEngine1 - OnInitialization = PythonType1Initialization - TypeName = 'MySeq' - Prefix = 'Create' - Module = PythonModule1 - Services.Basic = [bsGetAttr, bsSetAttr, bsRepr, bsStr] - Services.InplaceNumber = [] - Services.Number = [] - Services.Sequence = [] - Services.Mapping = [msLength, msSubscript] - Left = 40 - Top = 248 - end -end diff --git a/demos_delphi/Demo27/Unit1.pas b/demos_delphi/Demo27/Unit1.pas deleted file mode 100644 index ca8c30c..0000000 --- a/demos_delphi/Demo27/Unit1.pas +++ /dev/null @@ -1,67 +0,0 @@ -unit Unit1; - -interface - -uses - Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, PythonEngine, PythonGUIInputOutput, StdCtrls; - -type - TMySeq = class(TPyObject) - public - // Mapping services - function MpLength : Integer; override; - function MpSubscript( obj : PPyObject) : PPyObject; override; - //function MpAssSubscript( obj1, obj2 : PPyObject) : Integer; override; - end; - - TForm1 = class(TForm) - Memo1: TMemo; - Memo2: TMemo; - Button1: TButton; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - PythonModule1: TPythonModule; - PythonType1: TPythonType; - procedure Button1Click(Sender: TObject); - procedure PythonType1Initialization(Sender: TObject); - private - { Private declarations } - public - { Public declarations } - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -{ TMySeq } - -function TMySeq.MpLength: Integer; -begin - Result := 10; -end; - -function TMySeq.MpSubscript(obj: PPyObject): PPyObject; -begin - Result := obj; - GetPythonEngine.Py_XINCREF(obj); -end; - -{ TForm1 } - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings(Memo2.Lines); -end; - -procedure TForm1.PythonType1Initialization(Sender: TObject); -begin - with Sender as TPythonType do - PyObjectClass := TMySeq; -end; - -end. diff --git a/demos_delphi/Demo28/Project1.dpr b/demos_delphi/Demo28/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo28/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo28/Project1.dproj b/demos_delphi/Demo28/Project1.dproj deleted file mode 100644 index 917689c..0000000 --- a/demos_delphi/Demo28/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {8B96EA5E-DEEA-4208-93B8-31AC94C87BCE} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo28/Project1.res b/demos_delphi/Demo28/Project1.res deleted file mode 100644 index f928fd9..0000000 Binary files a/demos_delphi/Demo28/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo28/Unit1.dfm b/demos_delphi/Demo28/Unit1.dfm deleted file mode 100644 index 1eb278e..0000000 Binary files a/demos_delphi/Demo28/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo28/Unit1.pas b/demos_delphi/Demo28/Unit1.pas deleted file mode 100644 index 9cba4f7..0000000 --- a/demos_delphi/Demo28/Unit1.pas +++ /dev/null @@ -1,335 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TPyStringList = class(TPyObject) - private - fStrings: TStringList; - procedure SetStrings(const Value: TStringList); - public - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - destructor Destroy; override; - - // Basic services - function Iter : PPyObject; override; - - // Sequence services - function SqLength : Integer; override; - function SqItem( idx : Integer ) : PPyObject; override; - function SqAssItem( idx : integer; obj : PPyObject) : Integer; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Exposed methods - function add(args : PPyObject) : PPyObject; cdecl; - - // properties - property Strings : TStringList read fStrings write SetStrings; - end; - - TPyStringListIterator = class(TPyObject) - private - fStringList: TPyStringList; - fCurrentIndex: Integer; - procedure SetStringList(const Value: TPyStringList); - public - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - destructor Destroy; override; - - // Basic services - function Iter : PPyObject; override; - function IterNext : PPyObject; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Exposed methods - function next(args : PPyObject) : PPyObject; cdecl; - - // properties - property StringList : TPyStringList read fStringList write SetStringList; - end; - - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - ptStringList: TPythonType; - pmP4D: TPythonModule; - ptStringListIterator: TPythonType; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure ptStringListCreate(Sender: TObject); - procedure ptStringListIteratorCreate(Sender: TObject); - private - public - end; - - - -var - Form1: TForm1; - -implementation - -{$R *.DFM} - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -{ TPyStringList } - -function TPyStringList.add(args: PPyObject): PPyObject; -var - _obj : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - if PyArg_ParseTuple( args, 'O:add',@_obj ) <> 0 then - begin - Result := PyInt_FromLong(Strings.Add(PyObjectAsString(_obj))); - end - else - Result := nil; - end; -end; - -constructor TPyStringList.Create(APythonType: TPythonType); -begin - inherited; - Assert(not Assigned(fStrings)); - fStrings := TStringList.Create; -end; - -constructor TPyStringList.CreateWith(PythonType: TPythonType; - args: PPyObject); -var - i : Integer; -begin - inherited; - with GetPythonEngine do - begin - for i := 0 to PyTuple_Size(args)-1 do - begin - Strings.Add(PyObjectAsString(PyTuple_GetItem(args, i))); - end; - end; -end; - -destructor TPyStringList.Destroy; -begin - fStrings.Free; - inherited; -end; - -function TPyStringList.Iter: PPyObject; -var -// _iter : TPyStringListIterator; - _args : PPyObject; -begin - _args := GetPythonEngine.MakePyTuple([Self.GetSelf]); - try - Result := Form1.ptStringListIterator.CreateInstanceWith(_args); - finally - GetPythonEngine.Py_DECREF(_args); - end; - {_iter := Form1.ptStringListIterator.CreateInstance as TPyStringListIterator; - _iter.StringList := Self; - Result := _iter.GetSelf;} -end; - -class procedure TPyStringList.RegisterMethods(PythonType: TPythonType); -begin - inherited; - with PythonType do - begin - AddMethod( 'add', @TPyStringList.add, 'add a new item to the list and returns the index position' ); - end; -end; - -procedure TPyStringList.SetStrings(const Value: TStringList); -begin - fStrings.Assign(Value); -end; - -function TPyStringList.SqAssItem(idx: integer; obj: PPyObject): Integer; -begin - with GetPythonEngine do - begin - if idx < Strings.Count then - begin - Strings[idx] := PyObjectAsString(obj); - Result := 0; - end - else - begin - PyErr_SetString(PyExc_IndexError^, 'list index out of range'); - Result := -1; - end; - end; -end; - -function TPyStringList.SqItem(idx: Integer): PPyObject; -begin - with GetPythonEngine do - begin - if idx < Strings.Count then - Result := PyString_FromString(PAnsiChar(AnsiString(Strings[idx]))) - else - begin - PyErr_SetString(PyExc_IndexError^, 'list index out of range'); - Result := nil; - end; - end; -end; - -function TPyStringList.SqLength: Integer; -begin - Result := Strings.Count; -end; - -{ TPyStringListIterator } - -constructor TPyStringListIterator.Create(APythonType: TPythonType); -begin - inherited; -end; - -constructor TPyStringListIterator.CreateWith(PythonType: TPythonType; - args: PPyObject); -var - _obj : PPyObject; - _stringList : TPyStringList; -begin - inherited; - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'O:TPyStringListIterator constructor',@_obj ) <> 0 then - begin - _stringList := PythonToDelphi(_obj) as TPyStringList; - StringList := _stringList; - end; - end; -end; - -destructor TPyStringListIterator.Destroy; -begin - StringList := nil; - inherited; -end; - -function TPyStringListIterator.Iter: PPyObject; -begin - Result := Self.GetSelf; - GetPythonEngine.Py_INCREF(Result); -end; - -function TPyStringListIterator.IterNext: PPyObject; -begin - Inc(fCurrentIndex); - with GetPythonEngine do - begin - if fCurrentIndex >= StringList.Strings.Count then - begin - //PyErr_SetString(PyExc_StopIteration^, 'Stop iteration'); - Result := nil; - end - else - begin - Result := PyString_FromString(PAnsiChar(AnsiString(StringList.Strings[fCurrentIndex]))); - end; - end; -end; - -function TPyStringListIterator.next(args: PPyObject): PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - Result := Self.IterNext; - if not Assigned(Result) and (PyErr_Occurred = nil) then - PyErr_SetString(PyExc_StopIteration^, 'Stop iteration'); - end; -end; - -class procedure TPyStringListIterator.RegisterMethods( - PythonType: TPythonType); -begin - inherited; - with PythonType do - begin - AddMethod( 'next', @TPyStringListIterator.next, 'Returns the next value from the iterable container' ); - end; -end; - -procedure TPyStringListIterator.SetStringList(const Value: TPyStringList); -begin - if fStringList <> Value then - begin - if Assigned(fStringList) then - GetPythonEngine.Py_DECREF(fStringList.GetSelf); - fStringList := Value; - if Assigned(fStringList) then - GetPythonEngine.Py_INCREF(fStringList.GetSelf); - fCurrentIndex := -1; - end; -end; - -procedure TForm1.ptStringListCreate(Sender: TObject); -begin - with Sender as TPythonType do - PyObjectClass := TPyStringList; -end; - -procedure TForm1.ptStringListIteratorCreate(Sender: TObject); -begin - with Sender as TPythonType do - PyObjectClass := TPyStringListIterator; -end; - -end. diff --git a/demos_delphi/Demo29/Project1.dpr b/demos_delphi/Demo29/Project1.dpr deleted file mode 100644 index a5d8aee..0000000 --- a/demos_delphi/Demo29/Project1.dpr +++ /dev/null @@ -1,13 +0,0 @@ -program Project1; - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} -{$R XP_UAC.RES} -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo29/Project1.dproj b/demos_delphi/Demo29/Project1.dproj deleted file mode 100644 index c1c1a71..0000000 --- a/demos_delphi/Demo29/Project1.dproj +++ /dev/null @@ -1,156 +0,0 @@ - - - {2F621E09-DAC5-4AB2-83F7-BD019D49AAF2} - Project1.dpr - Debug - DCC32 - 18.7 - VCL - True - Win32 - 1 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - 4105 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - Project1.exe - 00400000 - x86 - Project1 - - - $(BDS)\bin\default_app.manifest - 1033 - true - Project1_Icon.ico - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - Project1_Icon.ico - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - - - Debug - true - 1033 - $(BDS)\bin\delphi_PROJECTICON.ico - true - - - - MainSource - - -
Form1
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 4105 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - False - - - 12 - - -
diff --git a/demos_delphi/Demo29/Project1.res b/demos_delphi/Demo29/Project1.res deleted file mode 100644 index aff75ae..0000000 Binary files a/demos_delphi/Demo29/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo29/Unit1.dfm b/demos_delphi/Demo29/Unit1.dfm deleted file mode 100644 index ccdcdd3..0000000 --- a/demos_delphi/Demo29/Unit1.dfm +++ /dev/null @@ -1,111 +0,0 @@ -object Form1: TForm1 - Left = 218 - Top = 18 - Caption = 'Form1' - ClientHeight = 743 - ClientWidth = 668 - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - Font.Style = [] - OldCreateOrder = False - PixelsPerInch = 96 - TextHeight = 13 - object Image1: TImage - Left = 8 - Top = 8 - Width = 657 - Height = 289 - AutoSize = True - end - object Button1: TButton - Left = 8 - Top = 312 - Width = 97 - Height = 25 - Caption = 'Open Picture...' - TabOrder = 0 - OnClick = Button1Click - end - object Button2: TButton - Left = 196 - Top = 312 - Width = 105 - Height = 25 - Caption = 'Execute' - TabOrder = 1 - OnClick = Button2Click - end - object Memo1: TMemo - Left = 8 - Top = 471 - Width = 657 - Height = 330 - Lines.Strings = ( - '# This demo requires the module pillow (PIL)' - - '# You can use "pip install Pillow" from a command prompt to ins' + - 'tall Pillow' - '' - 'from io import BytesIO' - 'from PIL import Image' - 'import sys' - '' - 'def ProcessImage(data):' - ' print(sys.version)' - ' stream = BytesIO(data)' - ' im = Image.open(stream)' - - ' print ("Processing image %s of %d bytes" % (im.format, len(dat' + - 'a)))' - ' new_im = im.rotate(90, expand=True)' - ' new_im.format = im.format' - ' return new_im' - ' ' - 'def ImageToString(image):' - ' stream = BytesIO()' - ' image.save(stream, image.format)' - ' return stream.getvalue()') - ScrollBars = ssBoth - TabOrder = 2 - end - object Memo2: TMemo - Left = 8 - Top = 352 - Width = 657 - Height = 113 - ScrollBars = ssBoth - TabOrder = 3 - end - object chkUseDC: TCheckBox - Left = 336 - Top = 316 - Width = 193 - Height = 17 - Caption = 'Use Device Context' - TabOrder = 4 - end - object OpenPictureDialog1: TOpenPictureDialog - Left = 104 - Top = 336 - end - object PythonEngine1: TPythonEngine - AutoUnload = False - DllName = 'python36.dll' - APIVersion = 1013 - RegVersion = '3.6' - UseLastKnownVersion = False - IO = PythonGUIInputOutput1 - Left = 168 - Top = 624 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = True - RawOutput = False - Output = Memo2 - Left = 208 - Top = 624 - end -end diff --git a/demos_delphi/Demo29/Unit1.pas b/demos_delphi/Demo29/Unit1.pas deleted file mode 100644 index 80cb54b..0000000 --- a/demos_delphi/Demo29/Unit1.pas +++ /dev/null @@ -1,145 +0,0 @@ -unit Unit1; -{ - Demonstrates the manipulation of images on the Delphi side using python. - Requires the Pillow python module. - Istall using pip (pip install Pillow). - Currently the code is setup for Python 3.x, but Python 2 can be supported - with minor changes. (io.Bytes should be replaced with StringIO.StringIO) -} -interface - -uses - Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, - Dialogs, ExtDlgs, StdCtrls, ExtCtrls, PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Image1: TImage; - Button1: TButton; - Button2: TButton; - OpenPictureDialog1: TOpenPictureDialog; - Memo1: TMemo; - Memo2: TMemo; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - chkUseDC: TCheckBox; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - private - { Private declarations } - public - { Public declarations } - end; - -var - Form1: TForm1; - -implementation - -uses - VarPyth, - Math, - jpeg; - -{$R *.dfm} - -// Old code not compatible with Unicode -// -//function ImageToString(AGraphic : TGraphic) : String; -//var -// _stream : TStringStream; -//begin -// _stream := TStringStream.Create(''); -// try -// AGraphic.SaveToStream(_stream); -// Result := _stream.DataString; -// finally -// _stream.Free; -// end; -//end; -// -//function BinStrToPyStr(const AString : String) : Variant; -//var -// _str : PPyObject; -//begin -// _str := GetPythonEngine.PyString_FromStringAndSize(PAnsiChar(AString), Length(AString)*SizeOf(Char)); -// Result := VarPythonCreate(_str); -// GetPythonEngine.Py_DECREF(_str); -//end; - -function ImageToPyStr(AGraphic : TGraphic) : Variant; -var - _stream : TMemoryStream; - _str : PPyObject; -begin - _stream := TMemoryStream.Create(); - try - AGraphic.SaveToStream(_stream); - _str := GetPythonEngine.PyString_FromStringAndSize(_stream.Memory, _stream.Size); - Result := VarPythonCreate(_str); - GetPythonEngine.Py_DECREF(_str); - finally - _stream.Free; - end; -end; - -procedure TForm1.Button1Click(Sender: TObject); -begin - if OpenPictureDialog1.Execute then - Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName); -end; - -procedure TForm1.Button2Click(Sender: TObject); -var - _im : Variant; - _stream : TMemoryStream; - _dib : Variant; - pargs: PPyObject; - presult :PPyObject; - P : PAnsiChar; - Len : NativeInt; -begin - if (Image1.Picture.Graphic = nil) or Image1.Picture.Graphic.Empty then - raise Exception.Create('You must first select an image'); - PythonEngine1.ExecStrings(Memo1.Lines); - _im := MainModule.ProcessImage(ImageToPyStr(Image1.Picture.Graphic)); - if not chkUseDC.Checked then - begin - // We have to call PyString_AsStringAndSize because the image may contain zeros - with GetPythonEngine do begin - pargs := MakePyTuple([ExtractPythonObjectFrom(_im)]); - try - try - presult := PyEval_CallObjectWithKeywords( - ExtractPythonObjectFrom(MainModule.ImageToString), pargs, nil); - if (PyString_AsStringAndSize(presult, P, Len) < 0) or (P = nil) then begin - ShowMessage('This does not work and needs fixing'); - Abort; - end; - finally - Py_XDECREF(pResult); - end; - finally - Py_DECREF(pargs); - end; - end; - - _stream := TMemoryStream.Create(); - try - _stream.Write(P^, Len); - _stream.Position := 0; - Image1.Picture.Graphic.LoadFromStream(_stream); - finally - _stream.Free; - end; - end - else - begin - Image1.Picture.Bitmap.SetSize(Image1.Width, Image1.Height); - _dib := Import('PIL.ImageWin').Dib(_im); - Image1.Picture.Bitmap.SetSize(Image1.Height, Image1.Width); - _dib.expose(NativeInt(Image1.Picture.Bitmap.Canvas.Handle)); - end; -end; - -end. diff --git a/demos_delphi/Demo29/XP_UAC.manifest b/demos_delphi/Demo29/XP_UAC.manifest deleted file mode 100644 index 3bcf619..0000000 --- a/demos_delphi/Demo29/XP_UAC.manifest +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - true - - - \ No newline at end of file diff --git a/demos_delphi/Demo29/XP_UAC.rc b/demos_delphi/Demo29/XP_UAC.rc deleted file mode 100644 index a0b6bf9..0000000 --- a/demos_delphi/Demo29/XP_UAC.rc +++ /dev/null @@ -1 +0,0 @@ -1 24 ".\XP_UAC.manifest" diff --git a/demos_delphi/Demo29/XP_UAC.res b/demos_delphi/Demo29/XP_UAC.res deleted file mode 100644 index 3bd5273..0000000 Binary files a/demos_delphi/Demo29/XP_UAC.res and /dev/null differ diff --git a/demos_delphi/Demo30/Project1.dpr b/demos_delphi/Demo30/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo30/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo30/Project1.dproj b/demos_delphi/Demo30/Project1.dproj deleted file mode 100644 index 7aa53f9..0000000 --- a/demos_delphi/Demo30/Project1.dproj +++ /dev/null @@ -1,101 +0,0 @@ - - - {E779713C-E867-4111-98ED-796E46162694} - Project1.dpr - Debug - DCC32 - 12.0 - - - true - - - true - Base - true - - - true - Base - true - - - WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias) - Project1.exe - 00400000 - x86 - - - false - RELEASE;$(DCC_Define) - 0 - false - - - DEBUG;$(DCC_Define) - - - - MainSource - - -
Form1
-
- - Base - - - Cfg_2 - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - - 12 - -
diff --git a/demos_delphi/Demo30/Project1.res b/demos_delphi/Demo30/Project1.res deleted file mode 100644 index f928fd9..0000000 Binary files a/demos_delphi/Demo30/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo30/Unit1.dfm b/demos_delphi/Demo30/Unit1.dfm deleted file mode 100644 index a55ced6..0000000 Binary files a/demos_delphi/Demo30/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo30/Unit1.pas b/demos_delphi/Demo30/Unit1.pas deleted file mode 100644 index ffe5b2f..0000000 --- a/demos_delphi/Demo30/Unit1.pas +++ /dev/null @@ -1,107 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - Classes, SysUtils, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ComCtrls, ExtCtrls, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - Splitter1: TSplitter; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - private - public - end; - - - -var - Form1: TForm1; - -implementation - -uses - VarPyth; - -{$R *.DFM} - -procedure TForm1.Button1Click(Sender: TObject); -var - P : Variant; -begin - PythonEngine1.ExecStrings( Memo1.Lines ); - P := MainModule.Person('John', 'Doe'); - Assert(P.first_name = 'John'); - Assert(P.last_name = 'Doe'); - Assert(VarIsNone(P.weight)); - Assert(VarIsNone(P.height)); - Assert(VarIsNone(P.age)); - P := MainModule.Person('John', 'Doe', weight := 70); - Assert(P.first_name = 'John'); - Assert(P.last_name = 'Doe'); - Assert(P.weight = 70); - Assert(VarIsNone(P.height)); - Assert(VarIsNone(P.age)); - P := MainModule.Person('John', 'Doe', weight := 70, height := 172); - Assert(P.first_name = 'John'); - Assert(P.last_name = 'Doe'); - Assert(P.weight = 70); - Assert(P.height = 172); - Assert(VarIsNone(P.age)); - P := MainModule.Person('John', 'Doe', weight := 70, height := 172, age := 35); - Assert(P.first_name = 'John'); - Assert(P.last_name = 'Doe'); - Assert(P.weight = 70); - Assert(P.height = 172); - Assert(P.age = 35); - P := MainModule.Person(last_name := 'Doe', first_name := 'John', weight := 70, height := 172, age := 35); - Assert(P.first_name = 'John'); - Assert(P.last_name = 'Doe'); - Assert(P.weight = 70); - Assert(P.height = 172); - Assert(P.age = 35); - P := MainModule.Person('John', 'Doe', 35, 172, 70); - Assert(P.first_name = 'John'); - Assert(P.last_name = 'Doe'); - Assert(P.weight = 70); - Assert(P.height = 172); - Assert(P.age = 35); - Memo2.Lines.Add('Success') -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -end. diff --git a/demos_delphi/Demo31/Project1.dpr b/demos_delphi/Demo31/Project1.dpr deleted file mode 100644 index 30d0679..0000000 --- a/demos_delphi/Demo31/Project1.dpr +++ /dev/null @@ -1,25 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}, - Unit2 in 'Unit2.pas' {TestForm}, - WrapDelphiExtCtrls, - WrapDelphiTypes, - WrapDelphiWindows, - WrapDelphiComCtrls, - WrapDelphiGrids, - WrapDelphiGraphics, - WrapDelphiButtons, - WrapDelphiDialogs; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.CreateForm(TTestForm, TestForm); - Application.Run; -end. diff --git a/demos_delphi/Demo31/Project1.dproj b/demos_delphi/Demo31/Project1.dproj deleted file mode 100644 index 568230f..0000000 --- a/demos_delphi/Demo31/Project1.dproj +++ /dev/null @@ -1,809 +0,0 @@ - - - {13782AFF-38C4-49AC-BA0A-8FAFC09245D8} - Project1.dpr - Debug - DCC32 - 18.7 - VCL - True - Win32 - 3 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - Project1 - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - 4105 - Project1.exe - 00400000 - x86 - - - true - Project1_Icon.ico - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - $(BDS)\bin\default_app.manifest - true - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - true - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - 1033 - $(BDS)\bin\default_app.manifest - Project1_Icon.ico - true - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - - - Debug - true - 1033 - $(BDS)\bin\delphi_PROJECTICON.ico - true - true - - - Debug - true - 1033 - $(BDS)\bin\delphi_PROJECTICON.ico - true - true - - - - MainSource - - -
Form1
-
- -
TestForm
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 4105 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - - - Project1.exe - true - - - - - 1 - - - 0 - - - - - classes - 1 - - - - - res\xml - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - - - res\values - 1 - - - - - res\values-v21 - 1 - - - - - res\values - 1 - - - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-xxxhdpi - 1 - - - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - - - res\values - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - 1 - - - 1 - - - 1 - - - - - - - - Contents\Resources - 1 - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - - 12 - - - -
diff --git a/demos_delphi/Demo31/Project1.res b/demos_delphi/Demo31/Project1.res deleted file mode 100644 index a04757b..0000000 Binary files a/demos_delphi/Demo31/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo31/Unit1.dfm b/demos_delphi/Demo31/Unit1.dfm deleted file mode 100644 index 111daab..0000000 --- a/demos_delphi/Demo31/Unit1.dfm +++ /dev/null @@ -1,565 +0,0 @@ -object Form1: TForm1 - Left = 246 - Top = 10 - Width = 737 - Height = 647 - VertScrollBar.Range = 210 - ActiveControl = Memo1 - Caption = 'Form1' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = 11 - Font.Name = 'MS Sans Serif' - Font.Pitch = fpVariable - Font.Style = [] - OldCreateOrder = True - Visible = True - OnCreate = FormCreate - PixelsPerInch = 96 - TextHeight = 13 - object Splitter1: TSplitter - Left = 0 - Top = 169 - Width = 721 - Height = 3 - Cursor = crVSplit - Align = alTop - ExplicitWidth = 677 - end - object Memo1: TMemo - Left = 0 - Top = 172 - Width = 721 - Height = 395 - Align = alClient - Lines.Strings = ( - - 'from spam import DelphiVersion, MainForm, DVar, CreateComponent,' + - ' Application, Screen, mrOk, Form, Button, CheckBox, OpenDialog, ' + - 'caFree' - - 'from spam import Point, Monitor, DrawGrid, gdSelected, clBlue, s' + - 'sCtrl, PageControl, TabSheet' - 'if DelphiVersion >= 6:' - ' from spam import mdNearest' - 'if DelphiVersion >= 15: ' - ' from spam import rtti_var' - '' - 'import unittest' - 'import sys' - 'py_major, py_minor = sys.version_info[:2]' - '' - 'class MyForm(Form):' - ' def __init__(self, Owner):' - ' self.Caption = '#39'Subclassed form'#39 - ' self.btnClose = Button(self)' - ' self.btnClose.Parent = self' - ' self.btnClose.Caption = '#39'Close'#39 - ' self.btnClose.SetBounds(10, 10, 120, 30)' - ' self.btnClose.OnClick = self.btnCloseClick' - '' - ' self.chkCanClose = CheckBox(self)' - ' self.chkCanClose.Parent = self' - ' self.chkCanClose.Caption = '#39'Can close?'#39 - ' self.chkCanClose.SetBounds(10, 50, 120, 30)' - '' - ' self.grdTest = DrawGrid(self)' - ' self.grdTest.Parent = self' - ' self.grdTest.SetBounds(10, 100, 300, 250)' - ' self.grdTest.OnDrawCell = self.grdTestDrawCell' - ' self.grdTest.OnSelectCell = self.grdTestSelectCell' - '' - ' self.OnCloseQuery = self.MyFormCloseQuery' - ' self.OnClose = self.MyFormClose' - ' self.Width = 400' - ' self.Height = 400' - '' - ' def btnCloseClick(self, Sender):' - ' print("Close!")' - ' self.Close()' - '' - ' def MyFormCloseQuery(self, Sender, CanClose):' - ' CanClose.Value = self.chkCanClose.Checked' - '' - ' def MyFormClose(self, Sender, Action):' - ' Action.Value = caFree' - '' - ' def grdTestDrawCell(self, Sender, Col, Row, Rect, State):' - ' if gdSelected in State:' - ' Sender.Canvas.Brush.Color = clBlue # 0x00ff0000 # blue' - - ' print("Cell[%d, %d] is selected, Rect=%s, State=%s" % (Col' + - ', Row, Rect, State))' - - ' Sender.Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2, "%d @ ' + - '%d" % (Col, Row))' - '' - ' def grdTestSelectCell(self, Sender, Col, Row, CanSelect):' - ' if Col == 2 and Row == 2:' - ' CanSelect.Value = False' - '' - 'class TTestForm(Form):' - ' def __init__(self, Owner):' - - ' self.Caption = self.Caption + '#39' - changed by Python subclass' + - #39 - ' self.BindMethodsToEvents()' - '' - ' def handle_btnAdd_OnClick(self, Sender):' - ' self.ListBox1.Items.Add(self.Edit1.Text)' - '' - 'class TestDelphiWrapper(unittest.TestCase):' - '' - ' def testReadWriteProperties(self):' - ' DVar.SValue = '#39'Weight'#39 - ' self.assertEqual(DVar.SValue, '#39'Weight'#39')' - ' DVar.IValue = 70' - ' self.assertEqual(DVar.IValue, 70)' - - ' MainForm.Caption = '#39'PyDelphi rocks!'#39' #setting propertie' + - 's' - ' self.assertEqual(MainForm.Caption, '#39'PyDelphi rocks!'#39')' - ' print()' - - ' print('#39'MainForm.ActiveControl='#39', MainForm.ActiveControl' + - ') # class properties' - - ' MainForm.BorderStyle = '#39'bsSizeable'#39' #enumeration propert' + - 'y' - ' MainForm.Anchors = ['#39'akLeft'#39', '#39'akTop'#39'] #set property' - ' self.assertEqual(MainForm.Anchors, ['#39'akLeft'#39', '#39'akTop'#39'])' - '' - ' def testTObject(self):' - ' self.assertEqual(MainForm.ClassName, '#39'TForm1'#39')' - ' self.assertTrue(MainForm.InheritsFrom('#39'TObject'#39'))' - '' - ' def testMethodCall(self):' - ' if DelphiVersion >= 7:' - ' DVar.SetMeUp('#39'Age'#39', 25)' - ' self.assertEqual(DVar.SValue, '#39'Age'#39')' - ' self.assertEqual(DVar.IValue, 25)' - ' print()' - ' print(DVar.DescribeMe()) #method calls' - '' - ' def testRepr(self):' - ' print()' - ' print('#39'Representation of Delphi objects'#39')' - ' print(DVar)' - ' print(MainForm)' - ' if DelphiVersion >= 7:' - ' print(DVar.DescribeMe) # method object' - ' print(DVar.SL) # TStrings' - '' - ' def testTStrings(self):' - ' SL = DVar.SL' - ' self.assertEqual(len(SL), 2)' - ' print()' - ' for i in DVar.SL: print(i, '#39' contains '#39', DVar.SL[i])' - ' SL.Add('#39'New String'#39')' - ' self.assertEqual(len(SL), 3)' - ' self.assertEqual(SL.IndexOf('#39'New String'#39'), 2)' - ' self.assertEqual(SL[0], '#39'Form1'#39')' - ' self.assertEqual(SL.Objects[0], MainForm)' - ' self.assertEqual(MainForm in SL.Objects, True)' - ' SL[2] = '#39'Changed'#39 - ' self.assertEqual(SL[2], '#39'Changed'#39')' - ' self.assertEqual(SL.Objects[2], None)' - ' SL.Objects[2] = MainForm' - ' self.assertEqual(SL.Objects[2], MainForm)' - ' self.assertEqual(MainForm in SL.Objects, True)' - ' SL.Delete(2)' - ' self.assertEqual(len(SL), 2)' - ' print("str(SL) =", str(SL))' - ' SL.Assign([1, 2, 3])' - ' self.assertEqual(len(SL), 3)' - ' self.assertEqual('#39'2'#39' in SL, True)' - ' self.assertEqual(SL[1], '#39'2'#39')' - ' tmp = ['#39'a'#39', '#39'b'#39', '#39'c'#39']' - ' SL.Assign(tmp)' - ' self.assertEqual(SL.ToList(), tmp)' - ' tmp = ('#39'a'#39', '#39'b'#39', '#39'c'#39')' - ' SL.Assign(tmp)' - ' self.assertEqual(SL.ToTuple(), tmp)' - '' - ' def testTComponent(self):' - ' self.assertEqual(MainForm.Name, '#39'Form1'#39')' - ' count = MainForm.ComponentCount' - ' def SetComponentCount():' - ' MainForm.ComponentCount = 3' - ' if py_major == 2 and py_minor < 5:' - ' self.assertRaises(TypeError, SetComponentCount)' - ' else:' - ' self.assertRaises(AttributeError, SetComponentCount)' - ' self.assertEqual(MainForm.__owned__, False)' - '' - ' def testSubComponents(self):' - ' MainForm.Button1.Caption = '#39'Click me!!'#39 - ' self.assertEqual(MainForm.Button1.Caption, '#39'Click me!!'#39')' - ' # test alternate mapping notation' - ' MainForm['#39'Button1'#39'].Caption = '#39'Click me!!!!'#39 - - ' self.assertEqual(MainForm['#39'Button1'#39'].Caption, '#39'Click me!' + - '!!!'#39')' - - ' self.assertEqual(MainForm.Button1.Caption, '#39'Click me!!!!' + - #39')' - ' # Test Owner property and DelphiObject comparison' - ' self.assertTrue(MainForm.Button1.Owner == MainForm)' - ' print([i.Name for i in MainForm.Components])' - '' - ' def testCreateComponent(self):' - ' NewButton = CreateComponent('#39'TButton'#39', None)' - ' self.assertEqual(NewButton.__bound__, True)' - ' self.assertEqual(NewButton.__owned__, True)' - ' NewButton.Free()' - ' self.assertEqual(NewButton.__bound__, False)' - '' - ' def testWinControls(self):' - ' self.assertEqual(MainForm.Panel1.Parent, MainForm)' - ' print()' - - ' print('#39'MainForm contains '#39', MainForm.ControlCount, '#39' con' + - 'trols'#39')' - ' print([i.Name for i in MainForm.Controls])' - '' - ' def testForm(self):' - ' MyForm = CreateComponent('#39'TForm'#39', None)' - ' MyForm.Name = '#39'MyForm'#39 - ' MyForm.Caption = '#39'Python Generated Form'#39 - ' MyForm.Height = 300' - ' MyForm.Width = 310' - ' MyForm.Position = '#39'poDefaultPosOnly'#39 - ' PC = PageControl(MyForm)' - ' PC.Name = "MyPageControl"' - ' PC.Parent = MyForm' - ' PC.Align = "alClient"' - ' P1 = TabSheet(MyForm)' - ' P1.PageControl = PC' - ' P1.Caption = "Page 1"' - ' LB = CreateComponent('#39'TListBox'#39', MyForm)' - ' B1 = CreateComponent('#39'TButton'#39', MyForm)' - ' B2 = CreateComponent('#39'TButton'#39', MyForm)' - ' Edit = CreateComponent('#39'TEdit'#39', MyForm)' - ' LB.Name = '#39'ListBox1'#39 - ' LB.Parent = P1' - ' LB.Left = 20' - ' LB.Top = 14' - ' LB.Width = 121' - ' LB.Height = 97' - ' LB.TabOrder = 0' - ' B1.Name = '#39'Button1'#39 - ' B1.Parent = P1' - ' B1.Left = 185' - ' B1.Top = 60' - ' B1.Width = 75' - ' B1.Height = 25' - ' B1.Caption = '#39'Add to list'#39 - ' B1.TabOrder = 1' - ' Edit.Name = '#39'Edit1'#39 - ' Edit.Parent = P1' - ' Edit.Left = 168' - ' Edit.Top = 27' - ' Edit.Width = 121' - ' Edit.Height = 21' - ' Edit.TabOrder = 2' - ' Edit.Text = '#39'Add me to List'#39 - ' B2.Name = '#39'Button2'#39 - ' B2.Parent = P1' - ' B2.Left = 121' - ' B2.Top = 125' - ' B2.Width = 75' - ' B2.Height = 25' - ' B2.Caption = '#39'Close'#39 - ' B2.ModalResult = mrOk' - ' B2.TabOrder = 3' - ' def ClickHandler(Sender):' - ' print(Sender.Name, '#39' was clicked'#39')' - ' LB.Items.Add(Edit.Text)' - ' B1.OnClick = ClickHandler' - ' def KeyPressHandler(Sender, Key):' - ' if Key.Value == '#39'a'#39':' - ' Key.Value = '#39'z'#39 - ' Edit.OnKeyPress = KeyPressHandler' - ' def KeyDownHandler(Sender, Key, Shift):' - ' # forbid Ctrl+Home' - ' if Key.Value == 36 and ssCtrl in Shift:' - ' Key.Value = 0' - ' Edit.OnKeyDown = KeyDownHandler' - ' BtnNextPage = Button(MyForm)' - ' BtnNextPage.Parent = P1' - ' BtnNextPage.SetBounds(10, 200, 150, 24)' - ' BtnNextPage.Caption = "Select Next Page"' - ' def NextPageClick(Sender):' - ' Sender.Owner.MyPageControl.SelectNextPage(True, True)' - ' BtnNextPage.OnClick = NextPageClick' - ' P2 = TabSheet(MyForm)' - ' P2.PageControl = PC' - ' P2.Caption = "Page 2"' - ' BtnGotoPage3 = Button(MyForm)' - ' BtnGotoPage3.Parent = P2' - ' BtnGotoPage3.SetBounds(10, 10, 150, 24)' - ' BtnGotoPage3.Caption = "Goto Page 3"' - ' def GotoPage3Click(Sender):' - - ' Sender.Owner.MyPageControl.ActivePage = Sender.Owner.' + - 'Page3' - ' BtnGotoPage3.OnClick = GotoPage3Click' - '' - ' P3 = TabSheet(MyForm)' - ' P3.PageControl = PC' - ' P3.Caption = "Page 3"' - ' P3.Name = "Page3"' - ' BtnGotoFirstPage = Button(MyForm)' - ' BtnGotoFirstPage.Parent = P3' - ' BtnGotoFirstPage.SetBounds(10, 10, 150, 24)' - ' BtnGotoFirstPage.Caption = "Goto First Page"' - ' def GotoFirstPageClick(Sender):' - ' PC.ActivePageIndex = 0' - ' BtnGotoFirstPage.OnClick = GotoFirstPageClick' - ' chkAllowChange = CheckBox(MyForm)' - ' chkAllowChange.Parent = P3' - ' chkAllowChange.SetBounds(10, 40, 150, 24)' - ' chkAllowChange.Caption = "Allow Page Change?"' - ' chkAllowChange.Checked = True' - '' - ' def PCChanging(Sender, AllowChange):' - ' AllowChange.Value = chkAllowChange.Checked' - ' PC.OnChanging = PCChanging' - '' - ' MyForm.ShowModal()' - '' - ' def testFormSubclass(self):' - ' f = MyForm(Application)' - ' try:' - ' print(f.ShowModal())' - ' finally:' - ' f.Free()' - '' - ' def testFormSubclass2(self):' - ' f = TTestForm(Application)' - ' try:' - ' print(f.ShowModal())' - ' finally:' - ' f.Free()' - '' - ' def testPointConversions(self):' - ' p1 = Point(10, 10)' - ' p = MainForm.ClientToScreen(p1)' - ' print(p)' - ' p2 = MainForm.ScreenToClient(p)' - ' self.assertEqual(p2.X, p1.X)' - ' self.assertEqual(p2.Y, p1.Y)' - '' - ' def testObjectNotification(self):' - ' DVar.IValue = 0' - ' def ChangeHandler(Sender):' - ' print(Sender)' - ' Sender.IValue = 55' - ' DVar.OnChange = ChangeHandler' - ' if DelphiVersion >= 7:' - ' DVar.TriggerChange()' - ' self.assertEqual(DVar.IValue, 55)' - ' DVar.OnChange = None' - ' DVar.IValue = 0' - ' DVar.TriggerChange()' - ' self.assertEqual(DVar.IValue, 0)' - '' - ' def testActions(self):' - ' self.assertEqual(MainForm.ActionList1.ActionCount, 1)' - - ' self.assertEqual(MainForm.ActionList1.Actions[0], MainFo' + - 'rm.actTest)' - - ' self.assertEqual(MainForm.actTest in MainForm.ActionList' + - '1, True)' - ' DVar.IValue = 0' - ' MainForm.actTest.Execute()' - ' self.assertEqual(DVar.IValue, 1)' - ' def ActionHandler(Sender):' - ' print("Action", Sender.Name, "executed from Python")' - ' DVar.IValue = 2' - ' self.assertEqual(MainForm.actTest.OnExecute, None)' - ' MainForm.actTest.OnExecute = ActionHandler' - - ' self.assertEqual(MainForm.actTest.OnExecute, ActionHandl' + - 'er)' - ' DVar.IValue = 0' - ' MainForm.actTest.Execute()' - ' self.assertEqual(DVar.IValue, 2)' - ' MainForm.actTest.OnExecute = None' - ' self.assertEqual(MainForm.actTest.OnExecute, None)' - '' - ' def testScreen(self):' - ' self.assertEqual(Screen.DataModuleCount, 0)' - ' self.assertEqual(Screen.FormCount > 0, True)' - ' self.assertEqual(Screen.CustomFormCount > 0, True)' - ' idx = -1' - ' for i, f in enumerate(Screen.Forms):' - ' if f == MainForm:' - ' idx = i' - ' break;' - ' self.assertEqual(idx > -1, True)' - ' self.assertEqual(Screen.Forms[idx], MainForm)' - ' self.assertEqual(Screen.CustomForms[idx], MainForm)' - ' self.assertEqual(Screen.Width > 0, True)' - ' self.assertEqual(Screen.Height > 0, True)' - ' MainForm.Button1.SetFocus()' - ' self.assertEqual(Screen.ActiveControl, MainForm.Button1)' - ' def ActiveControlChangeHandler(Sender):' - ' print("ActiveControlChangeHandler fired")' - - ' print("New active constrol is", Sender.ActiveControl' + - '.Name)' - ' DVar.IValue = 2' - ' self.assertEqual(Screen.OnActiveControlChange, None)' - - ' Screen.OnActiveControlChange = ActiveControlChangeHandle' + - 'r' - - ' self.assertEqual(Screen.OnActiveControlChange, ActiveCon' + - 'trolChangeHandler)' - ' DVar.IValue = 0' - ' self.assertEqual(DVar.IValue, 0)' - ' MainForm.Memo2.SetFocus()' - ' self.assertEqual(DVar.IValue, 2)' - ' Screen.OnActiveControlChange = None' - ' self.assertEqual(Screen.OnActiveControlChange, None)' - ' DVar.IValue = 0' - ' MainForm.Button1.SetFocus()' - ' self.assertEqual(DVar.IValue, 0)' - ' if DelphiVersion >= 6:' - - ' m = Screen.MonitorFromPoint(Point(10, 10), mdNearest' + - ')' - ' self.assertEqual(isinstance(m, Monitor), True)' - '' - ' def testOpenDialog(self):' - ' print("OpenDialog test:")' - ' open_dialog = CreateComponent("TOpenDialog", None)' - ' if open_dialog.Execute():' - ' print("FileName:", open_dialog.FileName)' - ' open_dialog.Free()' - '' - ' def testClassProperty(self):' - - ' MainForm.ActiveControl = MainForm.Memo2 # Class property' + - '!' - ' self.assertEqual(MainForm.ActiveControl, MainForm.Memo2)' - ' ' - ' def testDir(self):' - ' L = dir(MainForm)' - ' self.assertTrue('#39'ComponentCount'#39' in L)' - ' self.assertTrue('#39'__owned__'#39' in L)' - ' self.assertTrue('#39'ShowModal'#39' in L)' - '' - ' def testRttiAccess(self):' - ' if DelphiVersion >= 15:' - ' rtti_var.Fruit = '#39'Apple'#39 - ' self.assertTrue(rtti_var.Fruit == '#39'Apple'#39')' - ' rtti_var.Fruits = ['#39'Apple'#39', '#39'Banana'#39']' - - ' self.assertTrue(rtti_var.Fruits == ['#39'Apple'#39', '#39'Banana'#39']' + - ')' - ' rtti_var.BuyFruits(['#39'Apple'#39', '#39'Orange'#39'])' - - ' self.assertTrue(rtti_var.Fruits == ['#39'Apple'#39', '#39'Orange'#39']' + - ')' - - ' rtti_var.SetFormCaption(MainForm, '#39'From TTestRTTIAcces' + - 's'#39')' - - ' self.assertEqual(MainForm.Caption, '#39'From TTestRTTIAcce' + - 'ss'#39')' - ' rtti_var.FruitField = '#39'Apple'#39 - ' self.assertTrue(rtti_var.FruitField == '#39'Apple'#39')' - ' rtti_var.FruitsField = ['#39'Apple'#39', '#39'Banana'#39']' - - ' self.assertTrue(rtti_var.FruitsField == ['#39'Apple'#39', '#39'Ban' + - 'ana'#39'])' - ' rtti_var.StringField = '#39'Hi'#39 - ' self.assertTrue(rtti_var.StringField == '#39'Hi'#39')' - ' rtti_var.DoubleField = 3.14' - ' self.assertTrue(rtti_var.DoubleField == 3.14)' - ' rtti_var.ObjectField = MainForm' - ' MainForm.Caption = '#39'From TTestRTTIAccess.ObjectField'#39 - - ' self.assertTrue(MainForm.Caption == '#39'From TTestRTTIAcc' + - 'ess.ObjectField'#39')' - '' - '' - 'if __name__ == '#39'__main__'#39':' - ' try:' - ' unittest.main()' - ' except SystemExit:' - ' pass') - ScrollBars = ssVertical - TabOrder = 0 - WordWrap = False - end - object Panel1: TPanel - Left = 0 - Top = 567 - Width = 721 - Height = 41 - Align = alBottom - BevelOuter = bvNone - TabOrder = 1 - object Button1: TButton - Left = 8 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Execute' - TabOrder = 0 - OnClick = Button1Click - end - end - object Memo2: TMemo - Left = 0 - Top = 0 - Width = 721 - Height = 169 - Align = alTop - ScrollBars = ssBoth - TabOrder = 2 - end - object PyEngine: TPythonEngine - DllName = 'python38.dll' - APIVersion = 1013 - RegVersion = '3.8' - UseLastKnownVersion = False - IO = PythonGUIInputOutput1 - Left = 16 - Top = 16 - end - object PythonModule: TPythonModule - Engine = PyEngine - Events = < - item - Name = 'TestFunction' - OnExecute = PythonModuleEvents0Execute - DocString.Strings = ( - 'doc for TestFunction') - end> - ModuleName = 'spam' - Errors = <> - Left = 72 - Top = 16 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = True - RawOutput = False - Output = Memo2 - Left = 168 - Top = 17 - end - object ActionList1: TActionList - Left = 16 - Top = 80 - object actTest: TAction - Caption = 'Test' - OnExecute = actTestExecute - end - end -end diff --git a/demos_delphi/Demo31/Unit1.pas b/demos_delphi/Demo31/Unit1.pas deleted file mode 100644 index 808c616..0000000 --- a/demos_delphi/Demo31/Unit1.pas +++ /dev/null @@ -1,255 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, - PythonEngine, PythonGUIInputOutput, WrapDelphi, ActnList, System.Actions; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - PyEngine: TPythonEngine; - PythonModule: TPythonModule; - Panel1: TPanel; - Button1: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - ActionList1: TActionList; - actTest: TAction; - procedure Button1Click(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure PythonModuleEvents0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); - procedure actTestExecute(Sender: TObject); - private - public - PyDelphiWrapper : TPyDelphiWrapper; - end; - - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -Uses - TypInfo, -{$IFNDEF FPC} - ObjAuto, -{$ENDIF} - Variants, - VarPyth, - WrapDelphiVCL; - - -////////////////////////////////////////////////////////////////////////// -// Using TPyDelphiObject you can wrap any Delphi object exposing published -// properties and methods. Note that the conditional defines TYPEINFO and -// METHODINFO need to be on -////////////////////////////////////////////////////////////////////////// - -{$TYPEINFO OFF} -{$IFNDEF FPC}{$METHODINFO OFF}{$ENDIF} -Type -TTestBase = class - fdouble : double; - function DoubleDValue : double; // not visible in subclasses -published - property DValue : Double read fdouble write fdouble; // will be visible in subclasses -end; - -function TTestBase.DoubleDValue : double; -begin - Result := 2 * fdouble; -end; - -type -{$TYPEINFO ON} -{$IFNDEF FPC}{$METHODINFO ON}{$ENDIF} -TTestClass = class(TTestBase, IFreeNotification, IInterface) -private - fSValue : string; - fIValue : integer; - fSL : TStrings; - fOnChange: TNotifyEvent; - fFreeNotifImpl : IFreeNotification; - // implementation of interface IUnknown - function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; - function _AddRef: Integer; stdcall; - function _Release: Integer; stdcall; -protected - property FreeNotifImpl : IFreeNotification read fFreeNotifImpl implements IFreeNotification; -public - constructor Create; - destructor Destroy; override; - procedure SetMeUp(S: string; I : Integer); - function DescribeMe(): string; - procedure TriggerChange; -published - property SL : TStrings read fSL; - property SValue : string read fSValue write fSValue; - property IValue : integer read fIValue write fIValue; - property OnChange : TNotifyEvent read fOnChange write fOnChange; -end; -{$TYPEINFO OFF} -{$IFNDEF FPC}{$METHODINFO OFF}{$ENDIF} - -constructor TTestClass.Create; -begin - inherited; - fFreeNotifImpl := TFreeNotificationImpl.Create(Self); - fSL := TStringList.Create; - fSL.AddObject('Form1', Form1); - fSL.AddObject('Form1.Button1', Form1.Button1); -end; - -destructor TTestClass.Destroy; -begin - fSL.Free; - inherited; -end; - -procedure TTestClass.SetMeUp(S: string; I : Integer); -begin - SValue := S; - IValue := I; -end; - -function TTestClass.Describeme() : string; -begin - Result := fSValue + ' : ' + IntToStr(IValue); -end; - -procedure TTestClass.TriggerChange; -begin - if Assigned(fOnChange) then - fOnChange(Self); -end; - -function TTestClass._AddRef: Integer; -begin - Result := -1; // we don't want reference counting -end; - -function TTestClass._Release: Integer; -begin - Result := -1; // we don't want reference counting -end; - -function TTestClass.QueryInterface(const IID: TGUID; out Obj): HResult; -begin - if GetInterface(IID, Obj) then - Result := 0 - else - Result := E_NOINTERFACE; -end; - -{$IFDEF EXTENDED_RTTI} -{TTestRTTIAccess} -type - TFruit = (Apple, Banana, Orange); - TFruits = set of TFruit; - -TTestRTTIAccess = class -private - FFruit: TFruit; - FFruits: TFruits; -public - FruitField :TFruit; - FruitsField: TFruits; - StringField: string; - DoubleField: double; - ObjectField : TObject; - procedure BuyFruits(AFruits: TFruits); - procedure SetFormCaption(Form: TForm; ACaption: string); - property Fruit: TFruit read FFruit write FFruit; - property Fruits: TFruits read FFruits write FFruits; -end; -{$ENDIF} - -{ TForm1 } - -procedure TForm1.Button1Click(Sender: TObject); -var - p : PPyObject; -begin - actTest.OnExecute := actTestExecute; - - // Wrap the Form itself. - p := PyDelphiWrapper.Wrap(Self); - PythonModule.SetVar( 'MainForm', p ); - PyEngine.Py_DecRef(p); - - // Now wrap the an instance our TestClass - // This time we would like the object to be destroyed when the PyObject - // is destroyed, so we need to set its Owned property to True; - p := PyDelphiWrapper.Wrap(TTestClass.Create, soOwned); - PythonModule.SetVar( 'DVar', p ); - PyEngine.Py_DecRef(p); - -{$IFDEF EXTENDED_RTTI} - // Then wrap the an instance our TTestRTTIAccess - // It will allow us to to test access to public fields and methods as well - // public (as well as published) properties. - // This time we would like the object to be destroyed when the PyObject - // is destroyed, so we need to set its Owned property to True; - p := PyDelphiWrapper.Wrap(TTestRTTIAccess.Create, soOwned); - PythonModule.SetVar( 'rtti_var', p ); - PyEngine.Py_DecRef(p); -{$ENDIF} - - p := PyEngine.PyInt_FromLong(Trunc(System.CompilerVersion)); - PythonModule.SetVar( 'DelphiVersion', p ); - PyEngine.Py_DecRef(p); - - // Excecute the script - PyEngine.CheckError; - PyEngine.ExecStrings( memo1.Lines ); -end; - -procedure TForm1.FormCreate(Sender: TObject); -begin - PyDelphiWrapper := TPyDelphiWrapper.Create(Self); // no need to destroy - PyDelphiWrapper.Engine := PyEngine; - PyDelphiWrapper.Module := PythonModule; - PyDelphiWrapper.Initialize; // Should only be called if PyDelphiWrapper is created at run time -end; - -procedure TForm1.PythonModuleEvents0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); -begin - ShowMessage(VarPythonCreate(Args).GetItem(0)); - Result := PyEngine.ReturnNone; -end; - -procedure TForm1.actTestExecute(Sender: TObject); -begin - Memo2.Lines.Add('Delphi event actTestExecute fired'); - Import('spam').DVar.IValue := 1; -end; - -{$IFDEF EXTENDED_RTTI} -{ TTestRTTIAccess } - -procedure TTestRTTIAccess.BuyFruits(AFruits: TFruits); -begin - Fruits := AFruits; -end; - -procedure TTestRTTIAccess.SetFormCaption(Form: TForm; ACaption: string); -begin - Form.Caption := 'From TTestRTTIAccess'; -end; -{$ENDIF} - -initialization - ReportMemoryLeaksOnShutdown := DebugHook <> 0; -end. diff --git a/demos_delphi/Demo31/Unit2.dfm b/demos_delphi/Demo31/Unit2.dfm deleted file mode 100644 index 8a00bb3..0000000 --- a/demos_delphi/Demo31/Unit2.dfm +++ /dev/null @@ -1,67 +0,0 @@ -object TestForm: TTestForm - Left = 213 - Top = 114 - Width = 870 - Height = 500 - Caption = 'Test Form' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Shell Dlg 2' - Font.Style = [] - OldCreateOrder = False - PixelsPerInch = 96 - TextHeight = 13 - object CheckBox1: TCheckBox - Left = 96 - Top = 16 - Width = 97 - Height = 17 - Caption = 'CheckBox1' - TabOrder = 0 - end - object CheckBox2: TCheckBox - Left = 96 - Top = 56 - Width = 97 - Height = 17 - Caption = 'CheckBox2' - Checked = True - State = cbChecked - TabOrder = 1 - end - object btnClose: TButton - Left = 88 - Top = 256 - Width = 75 - Height = 25 - Caption = 'Close' - TabOrder = 2 - OnClick = btnCloseClick - end - object Edit1: TEdit - Left = 96 - Top = 96 - Width = 121 - Height = 21 - TabOrder = 3 - Text = 'Edit1' - end - object ListBox1: TListBox - Left = 328 - Top = 48 - Width = 249 - Height = 169 - ItemHeight = 13 - TabOrder = 4 - end - object btnAdd: TButton - Left = 104 - Top = 128 - Width = 75 - Height = 25 - Caption = 'Add' - TabOrder = 5 - end -end diff --git a/demos_delphi/Demo31/Unit2.pas b/demos_delphi/Demo31/Unit2.pas deleted file mode 100644 index 26c9ce3..0000000 --- a/demos_delphi/Demo31/Unit2.pas +++ /dev/null @@ -1,40 +0,0 @@ -unit Unit2; - -interface - -uses - Windows, Messages, SysUtils, - Variants, Classes, Graphics, Controls, Forms, - Dialogs, StdCtrls; - -type - TTestForm = class(TForm) - CheckBox1: TCheckBox; - CheckBox2: TCheckBox; - btnClose: TButton; - Edit1: TEdit; - ListBox1: TListBox; - btnAdd: TButton; - procedure btnCloseClick(Sender: TObject); - private - { Private declarations } - public - { Public declarations } - end; - -var - TestForm: TTestForm; - -implementation - -{$R *.dfm} - -procedure TTestForm.btnCloseClick(Sender: TObject); -begin - Close; -end; - -initialization - RegisterClass(TTestForm); -end. - diff --git a/demos_delphi/Demo32/Project1.dpr b/demos_delphi/Demo32/Project1.dpr deleted file mode 100644 index 0ef026f..0000000 --- a/demos_delphi/Demo32/Project1.dpr +++ /dev/null @@ -1,17 +0,0 @@ -// JCL_DEBUG_EXPERT_GENERATEJDBG OFF -// JCL_DEBUG_EXPERT_INSERTJDBG OFF -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo32/Project1.dproj b/demos_delphi/Demo32/Project1.dproj deleted file mode 100644 index f67fff2..0000000 --- a/demos_delphi/Demo32/Project1.dproj +++ /dev/null @@ -1,153 +0,0 @@ - - - {26D3B086-D6C0-40C9-820A-269741BAC910} - Project1.dpr - Debug - DCC32 - 16.1 - VCL - True - Win64 - 3 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - Project1 - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - 1032 - Project1.exe - 00400000 - x86 - - - true - Project1_Icon.ico - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - 1033 - $(BDS)\bin\default_app.manifest - - - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - $(BDS)\bin\default_app.manifest - true - 1033 - Project1_Icon.ico - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - DEBUG;$(DCC_Define) - - - $(BDS)\bin\delphi_PROJECTICON.ico - 1033 - true - - - - MainSource - - -
Form1
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1032 - 1253 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - 12 - - -
diff --git a/demos_delphi/Demo32/Project1.res b/demos_delphi/Demo32/Project1.res deleted file mode 100644 index 0f3facb..0000000 Binary files a/demos_delphi/Demo32/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo32/Unit1.dfm b/demos_delphi/Demo32/Unit1.dfm deleted file mode 100644 index db6f391..0000000 --- a/demos_delphi/Demo32/Unit1.dfm +++ /dev/null @@ -1,173 +0,0 @@ -object Form1: TForm1 - Left = 214 - Top = 174 - Width = 592 - Height = 422 - VertScrollBar.Range = 210 - ActiveControl = Memo1 - Caption = 'Form1' - Color = clBtnFace - Font.Charset = DEFAULT_CHARSET - Font.Color = clWindowText - Font.Height = 11 - Font.Name = 'MS Sans Serif' - Font.Pitch = fpVariable - Font.Style = [] - OldCreateOrder = True - Visible = True - PixelsPerInch = 96 - TextHeight = 11 - object Splitter1: TSplitter - Left = 0 - Top = 169 - Width = 576 - Height = 3 - Cursor = crVSplit - Align = alTop - ExplicitWidth = 584 - end - object Memo1: TMemo - Left = 0 - Top = 172 - Width = 576 - Height = 170 - Align = alClient - Lines.Strings = ( - 'import spam' - '' - 'class MyPoint(spam.Point):' - ' def Foo(Self, v):' - ' Self.OffsetBy(v, v)' - '' - 'p = spam.Point(2, 5)' - 'print p, type(p)' - 'p.OffsetBy( 3, 3 )' - 'print p.x, p.y' - 'print "Name =", p.Name' - 'p.Name = '#39'Hello world!'#39 - 'print "Name =", p.Name' - '' - 'p = spam.Point(2, 5) ' - 'print p, type(p)' - 'p.OffsetBy( 3, 3 )' - 'print p.x, p.y' - '' - '# create a subtype instance' - 'p = MyPoint(2, 5)' - 'print p, type(p)' - 'p.OffsetBy( 3, 3 )' - 'print p.x, p.y' - 'p.Foo( 4 )' - 'print p.x, p.y' - 'print dir(spam)' - 'print spam.Point' - 'print "p = ", p, " --> ",' - 'if type(p) is spam.Point:' - ' print "p is a Point"' - 'else:' - ' print "p is not a point"' - 'p = 2' - 'print "p = ", p, " --> ",' - 'if type(p) is spam.Point:' - ' print "p is a Point"' - 'else:' - ' print "p is not a point"' - '' - '# You can raise error from a Python script to !' - - 'print "---------------------------------------------------------' + - '---------"' - 'print "Errors in a Python script"' - 'try:' - ' raise spam.EBadPoint, "this is a test !"' - 'except:' - ' pass' - '' - 'try:' - ' err = spam.EBadPoint()' - ' err.a = 1' - ' err.b = 2' - ' err.c = 3' - ' raise err' - - 'except spam.PointError, what: #it shows you that you can interce' + - 'pt a parent class' - ' print "Catched an error dirived from PointError"' - - ' print "Error class = ", what.__class__, " a =", what.a, " ' + - ' b =", what.b, " c =", what.c' - '' - 'if p == spam.Point(2, 5): ' - ' print "Equal"' - 'else:' - ' print "Not equal"') - ScrollBars = ssVertical - TabOrder = 0 - end - object Panel1: TPanel - Left = 0 - Top = 342 - Width = 576 - Height = 41 - Align = alBottom - BevelOuter = bvNone - TabOrder = 1 - object Button1: TButton - Left = 8 - Top = 8 - Width = 75 - Height = 25 - Caption = 'Execute' - TabOrder = 0 - OnClick = Button1Click - end - end - object Memo2: TMemo - Left = 0 - Top = 0 - Width = 576 - Height = 169 - Align = alTop - ScrollBars = ssBoth - TabOrder = 2 - end - object PythonEngine1: TPythonEngine - DllName = 'python27.dll' - APIVersion = 1013 - RegVersion = '2.7' - UseLastKnownVersion = False - IO = PythonGUIInputOutput1 - Left = 32 - Top = 16 - end - object PythonModule1: TPythonModule - Engine = PythonEngine1 - ModuleName = 'spam' - Errors = < - item - Name = 'PointError' - ErrorType = etClass - end - item - Name = 'EBadPoint' - ErrorType = etClass - ParentClass.Name = 'PointError' - end> - Left = 32 - Top = 72 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = True - RawOutput = False - Output = Memo2 - Left = 136 - Top = 16 - end - object PyDelphiWrapper: TPyDelphiWrapper - Engine = PythonEngine1 - OnInitialization = PyDelphiWrapperInitialization - Module = PythonModule1 - Left = 242 - Top = 15 - end -end diff --git a/demos_delphi/Demo32/Unit1.pas b/demos_delphi/Demo32/Unit1.pas deleted file mode 100644 index 8566c88..0000000 --- a/demos_delphi/Demo32/Unit1.pas +++ /dev/null @@ -1,166 +0,0 @@ -unit Unit1; -{ - Demo 26 reworked using WrapDelphi - See also Demo 31. - For further information on using WrapDelphi look - at the comments at the top of the unit. -} - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, - WrapDelphi, WrapDelphiClasses, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - PythonEngine1: TPythonEngine; - PythonModule1: TPythonModule; - Panel1: TPanel; - Button1: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - PyDelphiWrapper: TPyDelphiWrapper; - procedure Button1Click(Sender: TObject); - procedure PyDelphiWrapperInitialization(Sender: TObject); - private - public - end; - - { - Delphi class to be exported using WrapDelphi - Note the METHODINFO directive for automatically - exporting methods - } - {$METHODINFO ON} - TPoint = class(TPersistent) - private - fx, fy : Integer; - fName : String; - public - procedure OffsetBy( dx, dy : integer ); - published - property x : integer read fx write fx; - property y : integer read fy write fy; - property Name : string read fName write fName; - end; - {$METHODINFO OFF} - - // TPyPoint is TPyObject decscendent, more specifically - // a TPyDelphiPersistent (from WrapDelphi) descendent. - // It overrides a few key methods Repr, Create and CreateWith - TPyPoint = class(TPyDelphiPersistent) - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - // Basic services - function Repr : PPyObject; override; - - class function DelphiObjectClass : TClass; override; - end; - -var - Form1: TForm1; - -implementation - - -{$R *.dfm} - -// First, we need to initialize the property PyObjectClass with -// the class of our Type object - -{ TPoint } - -procedure TPoint.OffsetBy(dx, dy: integer); -begin - Inc(fx, dx); - Inc(fy, dy); -end; - -{ TPyPoint } - -// We override the constructors - -constructor TPyPoint.Create( APythonType : TPythonType ); -begin - inherited; - // we need to set DelphiObject property - DelphiObject := TPoint.Create; - with TPoint(DelphiObject) do begin - x := 0; - y := 0; - end; - Owned := True; // We own the objects we create -end; - -// Don't call the Create constructor of TPyPoint, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyPoint.Create will be automatically be called. - -constructor TPyPoint.CreateWith( PythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine, DelphiObject as TPoint do - begin - if PyArg_ParseTuple( args, 'ii:CreatePoint',@fx, @fy ) = 0 then - Exit; - end; -end; - -// Then we override the needed services - -class function TPyPoint.DelphiObjectClass: TClass; -begin - Result := TPoint; -end; - -function TPyPoint.Repr : PPyObject; -begin - with GetPythonEngine, DelphiObject as TPoint do - Result := VariantAsPyObject(Format('(%d, %d)',[x, y])); - // or Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[x, y])) ); -end; - -///////////////////////////////////////////////// -procedure TForm1.Button1Click(Sender: TObject); -var - DelphiPoint : TPoint; - p : PPyObject; -begin - // Here's how you can create/read Python vars from Delphi with - // Delphi/Python objects. - DelphiPoint := TPoint.Create; - DelphiPoint.x := 10; - DelphiPoint.y := 20; - - // DelphiPoint will be owned and eventually destroyed by Python - p := PyDelphiWrapper.Wrap(DelphiPoint, soOwned); - - PythonModule1.SetVar( 'myPoint', p ); - - // Note, that you must not free the delphi point yourself. - // Instead use the GetPythonEngine.Py_XDECREF(obj) method, - // because the object may be used by another Python object. - PythonEngine1.Py_DecRef(p); - - // Excecute the script - PythonEngine1.ExecStrings( memo1.Lines ); - -end; - -procedure TForm1.PyDelphiWrapperInitialization(Sender: TObject); -begin - // Register PythonType1 encapsulating Delphi Type TPoint - PyDelphiWrapper.RegisterDelphiWrapper(TPyPoint); -end; - -end. diff --git a/demos_delphi/Demo33/SortThds.pas b/demos_delphi/Demo33/SortThds.pas deleted file mode 100644 index 7f3aeb7..0000000 --- a/demos_delphi/Demo33/SortThds.pas +++ /dev/null @@ -1,166 +0,0 @@ -unit SortThds; - -{$I Definition.Inc} - -interface - -uses - Classes, - Graphics, ExtCtrls, Forms, - PythonEngine; - -type - -{ TSortThread } - - PSortArray = ^TSortArray; - TSortArray = array[0..MaxInt div SizeOf(Integer) - 1] of Integer; - - TSortThread = class(TPythonThread) - private - FModule: TPythonModule; - FScript: TStrings; - FBox: TPaintBox; - FSortArray: PSortArray; - FSize: Integer; - FI, FJ: Integer; - fpyfuncname: string; - running : Boolean; - - procedure DoVisualSwap; - - function getvalue(i: integer): integer; - protected - procedure ExecuteWithPython; override; - public - property value[i: integer]: integer read getvalue; default; - - constructor Create( AThreadExecMode: TThreadExecMode; script: TStrings; - module: TPythonModule; apyfuncname: string; - Box: TPaintBox; var SortArray: array of Integer); - - procedure VisualSwap(I, J: Integer); - procedure Stop; - end; - -procedure PaintLine(Canvas: TCanvas; I, Len: Integer); - -implementation - -procedure PaintLine(Canvas: TCanvas; I, Len: Integer); -begin - Canvas.PolyLine([Point(0, I * 2 + 1), Point(Len, I * 2 + 1)]); -end; - -{ TSortThread } - -constructor TSortThread.Create( AThreadExecMode: TThreadExecMode; script: TStrings; - module: TPythonModule; apyfuncname: string; - Box: TPaintBox; var SortArray: array of Integer); -begin - fpyfuncname := apyfuncname; - fScript := script; - FModule := module; - FBox := Box; - FSortArray := @SortArray; - FSize := High(SortArray) - Low(SortArray) + 1; - FreeOnTerminate := True; - ThreadExecMode := AThreadExecMode; - inherited Create(False); -end; - - - -{ Since DoVisualSwap uses a VCL component (i.e., the TPaintBox) it should never - be called directly by this thread. DoVisualSwap should be called by passing - it to the Synchronize method which causes DoVisualSwap to be executed by the - main VCL thread, avoiding multi-thread conflicts. See VisualSwap for an - example of calling Synchronize. } - -procedure TSortThread.DoVisualSwap; -type - pinteger = ^integer; -var t: integer; - pi,pj: pinteger; -begin - Application.ProcessMessages; - with FBox do - begin - Canvas.Pen.Color := clBtnFace; - pi := @(FSortArray^[FI]); - pj := @(FSortArray^[FJ]); - PaintLine(Canvas, FI, pi^); - PaintLine(Canvas, FJ, pj^); - Canvas.Pen.Color := clRed; - PaintLine(Canvas, FI, pj^); - PaintLine(Canvas, FJ, pi^); - - t := pi^; - pi^ := pj^; - pj^ := t; - end; -end; - -{ VisusalSwap is a wrapper on DoVisualSwap making it easier to use. The - parameters are copied to instance variables so they are accessable - by the main VCL thread when it executes DoVisualSwap } - -procedure TSortThread.VisualSwap(I, J: Integer); -begin - Py_BEGIN_ALLOW_THREADS; - if Terminated then - raise EPythonError.Create( 'Pythonthread terminated'); - FI := I; - FJ := J; - Synchronize(DoVisualSwap); - Py_END_ALLOW_THREADS; -end; - -{ The Execute method is called when the thread starts } - -procedure TSortThread.ExecuteWithPython; -var pyfunc: PPyObject; -begin - running := true; - try - with GetPythonEngine do - begin - if Assigned(FModule) and (ThreadExecMode = emNewInterpreter) then - FModule.InitializeForNewInterpreter; - if Assigned(fScript) then - ExecStrings(fScript); - pyfunc := FindFunction( ExecModule, fpyfuncname); - if Assigned(pyfunc) then - try - EvalFunction(pyfunc,[NativeInt(self),0,FSize]); - except - end; - - Py_DecRef(pyfunc); - end; - finally - running := false; - end; -end; - -procedure TSortThread.Stop; -begin - with GetPythonEngine do - begin - if running then - begin - PyEval_AcquireThread(self.ThreadState); - PyErr_SetString(PyExc_KeyboardInterrupt^, 'Terminated'); - PyEval_ReleaseThread(self.ThreadState); - end; - end; -end; - -function TSortThread.getvalue(i: integer): integer; -begin - if Terminated then - raise EPythonError.Create( 'Pythonthread terminated'); - Result := FSortArray^[i]; -end; - -end. diff --git a/demos_delphi/Demo33/ThSort.dfm b/demos_delphi/Demo33/ThSort.dfm deleted file mode 100644 index be8580e..0000000 Binary files a/demos_delphi/Demo33/ThSort.dfm and /dev/null differ diff --git a/demos_delphi/Demo33/ThSort.pas b/demos_delphi/Demo33/ThSort.pas deleted file mode 100644 index 892fa57..0000000 --- a/demos_delphi/Demo33/ThSort.pas +++ /dev/null @@ -1,256 +0,0 @@ -unit ThSort; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - ExtCtrls, StdCtrls, - PythonEngine, PythonGUIInputOutput, SortThds; - -type - TThreadSortForm = class(TForm) - StartBtn: TButton; - BubbleSortBox: TPaintBox; - SelectionSortBox: TPaintBox; - QuickSortBox: TPaintBox; - Label1: TLabel; - Bevel1: TBevel; - Bevel2: TBevel; - Bevel3: TBevel; - Label2: TLabel; - Label3: TLabel; - PythonMemo: TMemo; - PythonEngine1: TPythonEngine; - SortModule: TPythonModule; - Start2Btn: TButton; - LoadBtn: TButton; - PythonDialog: TOpenDialog; - SaveDialog: TSaveDialog; - SaveBtn: TButton; - Button1: TButton; - procedure BubbleSortBoxPaint(Sender: TObject); - procedure SelectionSortBoxPaint(Sender: TObject); - procedure QuickSortBoxPaint(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure StartBtnClick(Sender: TObject); - procedure Start2BtnClick(Sender: TObject); - procedure LoadBtnClick(Sender: TObject); - procedure SaveBtnClick(Sender: TObject); - procedure SortModuleInitialization(Sender: TObject); - procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); - procedure Button1Click(Sender: TObject); - private - OwnThreadState: PPyThreadState; - ThreadsRunning: Integer; - procedure RandomizeArrays; - procedure ThreadDone(Sender: TObject); - procedure InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings); - - function SortModule_GetValue( pself, args : PPyObject ) : PPyObject; cdecl; - function SortModule_Swap( pself, args : PPyObject ) : PPyObject; cdecl; - public - Thread1 : TSortThread; - Thread2 : TSortThread; - Thread3 : TSortThread; - - procedure PaintArray(Box: TPaintBox; const A: array of Integer); - end; - -var - ThreadSortForm: TThreadSortForm; - -implementation - -{$R *.dfm} - -type - PSortArray = ^TSortArray; - TSortArray = array[0..200] of Integer; - -var - ArraysRandom: Boolean; - BubbleSortArray, SelectionSortArray, QuickSortArray: TSortArray; - -{ TThreadSortForm } - -procedure TThreadSortForm.PaintArray(Box: TPaintBox; const A: array of Integer); -var - I: Integer; -begin - with Box do - begin - Canvas.Pen.Color := clRed; - for I := Low(A) to High(A) do PaintLine(Canvas, I, A[I]); - end; -end; - -procedure TThreadSortForm.BubbleSortBoxPaint(Sender: TObject); -begin - PaintArray(BubbleSortBox, BubbleSortArray); -end; - -procedure TThreadSortForm.SelectionSortBoxPaint(Sender: TObject); -begin - PaintArray(SelectionSortBox, SelectionSortArray); -end; - -procedure TThreadSortForm.QuickSortBoxPaint(Sender: TObject); -begin - PaintArray(QuickSortBox, QuickSortArray); -end; - -procedure TThreadSortForm.FormCreate(Sender: TObject); -begin - RandomizeArrays; -end; - -procedure TThreadSortForm.InitThreads(ThreadExecMode: TThreadExecMode; script: TStrings); -begin - RandomizeArrays; - ThreadsRunning := 3; - with GetPythonEngine do - begin - OwnThreadState := PyEval_SaveThread; - - Thread1 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc1', - BubbleSortBox, BubbleSortArray); - Thread1.OnTerminate := ThreadDone; - - Thread2 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc2', - SelectionSortBox, SelectionSortArray); - Thread2.OnTerminate := ThreadDone; - - Thread3 := TSortThread.Create( ThreadExecMode, script, SortModule, 'SortFunc3', - QuickSortBox, QuickSortArray); - Thread3.OnTerminate := ThreadDone; - - end; - - StartBtn.Enabled := False; - Start2Btn.Enabled := False; -end; - -procedure TThreadSortForm.Start2BtnClick(Sender: TObject); -begin - with GetPythonEngine do - begin - ExecStrings(PythonMemo.Lines); - self.InitThreads(emNewState,nil); - end; -end; - -procedure TThreadSortForm.StartBtnClick(Sender: TObject); -begin - InitThreads(emNewInterpreter,PythonMemo.Lines); -//PythonEngine1.ExecStrings(PythonMemo.Lines); -end; - -procedure TThreadSortForm.LoadBtnClick(Sender: TObject); -begin - with PythonDialog do if Execute then - PythonMemo.Lines.LoadFromFile(FileName); -end; - -procedure TThreadSortForm.SaveBtnClick(Sender: TObject); -begin - with SaveDialog do if Execute then - PythonMemo.Lines.SaveToFile(FileName); -end; - -procedure TThreadSortForm.RandomizeArrays; -var - I: Integer; -begin - if not ArraysRandom then - begin - Randomize; - for I := Low(BubbleSortArray) to High(BubbleSortArray) do - BubbleSortArray[I] := Random(170); - SelectionSortArray := BubbleSortArray; - QuickSortArray := BubbleSortArray; - ArraysRandom := True; - Repaint; - end; -end; - -procedure TThreadSortForm.ThreadDone(Sender: TObject); -begin - Dec(ThreadsRunning); - if ThreadsRunning = 0 then - begin - GetPythonEngine.PyEval_RestoreThread(OwnThreadState); - StartBtn.Enabled := True; - Start2Btn.Enabled := True; - ArraysRandom := False; - Thread1 := nil; - Thread2 := nil; - Thread3 := nil; - end; -end; - -{Checking for PyErr_Occurred() is very important if you want to properly terminate script -if PyErr_Occurred() not nil - you should return nil from your mapped function -} - -function TThreadSortForm.SortModule_GetValue( pself, args : PPyObject ) : PPyObject; cdecl; -var psort,index: integer; -begin - with GetPythonEngine do - begin - if (PyErr_Occurred() = nil) and (PyArg_ParseTuple( args, 'ii',@psort, @index) <> 0) then - begin - Result := PyInt_FromLong(TSortThread(psort)[index]); - end else - Result := nil; - end; -end; - - - -function TThreadSortForm.SortModule_Swap( pself, args : PPyObject ) : PPyObject; cdecl; -var psort,i,j: integer; -begin - - with GetPythonEngine do - begin - if (PyErr_Occurred() = nil) and (PyArg_ParseTuple( args, 'iii',@psort, @i, @j) <> 0) then - begin - TSortThread(psort).VisualSwap(i,j); - Result := ReturnNone; - end else - Result := nil; - end; -end; - - - -procedure TThreadSortForm.SortModuleInitialization(Sender: TObject); -begin - with Sender as TPythonModule do - begin - AddDelphiMethod( 'getvalue', - SortModule_GetValue, - 'GetValue(handle,index)' ); - AddDelphiMethod( 'swap', - SortModule_Swap, - 'swap(handle,index1,index2)'); - end; -end; - -procedure TThreadSortForm.Button1Click(Sender: TObject); -begin - if Assigned(Thread1) and not Thread1.Finished then Thread1.Stop(); - if Assigned(Thread2) and not Thread2.Finished then Thread2.Stop(); - if Assigned(Thread3) and not Thread3.Finished then Thread3.Stop(); -end; - -procedure TThreadSortForm.FormCloseQuery(Sender: TObject; - var CanClose: Boolean); -begin - CanClose := ThreadsRunning = 0; -end; - -end. diff --git a/demos_delphi/Demo33/ThrdDemo.dpr b/demos_delphi/Demo33/ThrdDemo.dpr deleted file mode 100644 index 2f87d30..0000000 --- a/demos_delphi/Demo33/ThrdDemo.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program ThrdDemo; - -uses - Forms, - SortThds in 'SortThds.pas', - ThSort in 'ThSort.pas' {ThreadSortForm}; - -{$R *.res} - -begin - Application.Initialize; - Application.MainFormOnTaskbar := True; - Application.CreateForm(TThreadSortForm, ThreadSortForm); - Application.Run; -end. diff --git a/demos_delphi/Demo33/ThrdDemo.dproj b/demos_delphi/Demo33/ThrdDemo.dproj deleted file mode 100644 index 8ae1e02..0000000 --- a/demos_delphi/Demo33/ThrdDemo.dproj +++ /dev/null @@ -1,195 +0,0 @@ - - - {9e78092e-5a16-44b9-97bf-b879c252b4ba} - Debug - DCC32 - ThrdDemo.exe - ThrdDemo.dpr - 18.4 - Debug - VCL - True - Win64 - 3 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - ThrdDemo.exe - ThrdDemo - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - 1049 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 - $(BDS)\bin\default_app.manifest - ThrdDemo_Icon.ico - true - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - $(BDS)\bin\default_app.manifest - ThrdDemo_Icon.ico - true - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - 1033 - - - 7.0 - 0 - False - 0 - RELEASE;$(DCC_Define) - - - true - true - - - true - true - - - 7.0 - DEBUG;JVCLThemesEnabled;COMPILER5_UP;PS_USESSUPPORT;$(DCC_Define) - C:\Users\alex\python4delphi-read-only\PythonForDelphi\Components\Sources\Core;$(DCC_UnitSearchPath) - C:\Users\alex\python4delphi-read-only\PythonForDelphi\Components\Sources\Core;$(DCC_ResourcePath) - C:\Users\alex\python4delphi-read-only\PythonForDelphi\Components\Sources\Core;$(DCC_ObjPath) - C:\Users\alex\python4delphi-read-only\PythonForDelphi\Components\Sources\Core;$(DCC_IncludePath) - - - true - true - - - true - true - - - Delphi.Personality.12 - - - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1049 - 1251 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - ThrdDemo.dpr - - - - True - True - - - 12 - - - - MainSource - - - -
ThreadSortForm
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - -
diff --git a/demos_delphi/Demo33/ThrdDemo.res b/demos_delphi/Demo33/ThrdDemo.res deleted file mode 100644 index 7bc2fd3..0000000 Binary files a/demos_delphi/Demo33/ThrdDemo.res and /dev/null differ diff --git a/demos_delphi/Demo33/test.py b/demos_delphi/Demo33/test.py deleted file mode 100644 index a52c520..0000000 --- a/demos_delphi/Demo33/test.py +++ /dev/null @@ -1,33 +0,0 @@ -from SortModule import getvalue,swap - -def SortFunc1(handle, low, high): - for i in range(low, high): - for j in range(low+1,high): - if getvalue(handle,j-1) > getvalue(handle,j): - swap(handle,j-1,j) - -def SortFunc2(handle,low,high): - for i in range(low,high-1): - for j in range(i+1,high): - if getvalue(handle,i) > getvalue(handle,j): - swap(handle,i,j) - -def SortFunc3(handle,low,high): - Lo = low - Hi = high-1 - Mid = getvalue(handle,(Lo+Hi) / 2) - while 1: - while getvalue(handle,Lo) < Mid: - Lo = Lo + 1 - while getvalue(handle,Hi) > Mid: - Hi = Hi - 1 - if Lo <= Hi: - swap(handle,Lo,Hi) - Lo = Lo + 1 - Hi = Hi - 1 - if Lo > Hi: - break - if Hi > low: - SortFunc3(handle,low,Hi+1) - if Lo < high-1: - SortFunc3(handle,Lo,high) diff --git a/demos_delphi/Demo34/Project1.dpr b/demos_delphi/Demo34/Project1.dpr deleted file mode 100644 index 6c330c4..0000000 --- a/demos_delphi/Demo34/Project1.dpr +++ /dev/null @@ -1,15 +0,0 @@ -program Project1; - -{$I Definition.Inc} - -uses - Forms, - Unit1 in 'Unit1.pas' {Form1}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. diff --git a/demos_delphi/Demo34/Project1.dproj b/demos_delphi/Demo34/Project1.dproj deleted file mode 100644 index fb14838..0000000 --- a/demos_delphi/Demo34/Project1.dproj +++ /dev/null @@ -1,558 +0,0 @@ - - - {910E2A03-F875-4153-9E58-3434C6D9AB6F} - Project1.dpr - Debug - DCC32 - 18.3 - VCL - True - Win32 - 3 - Application - - - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Cfg_1 - true - true - - - true - Cfg_1 - true - true - - - true - Base - true - - - true - Cfg_2 - true - true - - - true - Cfg_2 - true - true - - - Project1.exe - 00400000 - x86 - Project1 - Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;$(DCC_Namespace) - 1033 - CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= - - - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) - Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments=;ProgramID=com.embarcadero.$(MSBuildProjectName) - 1033 - $(BDS)\bin\default_app.manifest - Project1_Icon.ico - true - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - - - Project1_Icon.ico - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_44.png - $(BDS)\bin\Artwork\Windows\UWP\delphi_UwpDefault_150.png - System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) - Debug - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - $(BDS)\bin\default_app.manifest - - - false - RELEASE;$(DCC_Define) - 0 - 0 - - - true - true - - - true - true - - - DEBUG;$(DCC_Define) - - - true - true - - - true - true - true - CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - - - - MainSource - - -
Form1
-
- - Cfg_2 - Base - - - Base - - - Cfg_1 - Base - -
- - - Delphi.Personality.12 - VCLApplication - - - - Project1.dpr - - - False - True - False - - - False - False - 1 - 0 - 0 - 0 - False - False - False - False - False - 1033 - 1252 - - - - - 1.0.0.0 - - - - - - 1.0.0.0 - - - - Microsoft Office 2000 Sample Automation Server Wrapper Components - Microsoft Office XP Sample Automation Server Wrapper Components - - - - True - True - - - - - Project1.exe - true - - - - - 1 - - - Contents\MacOS - 0 - - - - - classes - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - library\lib\armeabi - 1 - - - - - library\lib\mips - 1 - - - - - library\lib\armeabi-v7a - 1 - - - - - res\drawable - 1 - - - - - res\values - 1 - - - - - res\drawable - 1 - - - - - res\drawable-xxhdpi - 1 - - - - - res\drawable-ldpi - 1 - - - - - res\drawable-mdpi - 1 - - - - - res\drawable-hdpi - 1 - - - - - res\drawable-xhdpi - 1 - - - - - res\drawable-small - 1 - - - - - res\drawable-normal - 1 - - - - - res\drawable-large - 1 - - - - - res\drawable-xlarge - 1 - - - - - 1 - - - 1 - - - 0 - - - - - 1 - .framework - - - 0 - - - - - 1 - .dylib - - - 0 - .dll;.bpl - - - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 1 - .dylib - - - 0 - .bpl - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - 1 - - - 1 - - - - - 1 - - - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF - 1 - - - - - - - - 1 - - - 1 - - - 1 - - - - - - - Contents\Resources - 1 - - - - - library\lib\armeabi-v7a - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 1 - - - 0 - - - - - 1 - - - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - Assets - 1 - - - Assets - 1 - - - - - - - - - - - - - 12 - - - -
diff --git a/demos_delphi/Demo34/Project1.res b/demos_delphi/Demo34/Project1.res deleted file mode 100644 index 4aaa52b..0000000 Binary files a/demos_delphi/Demo34/Project1.res and /dev/null differ diff --git a/demos_delphi/Demo34/Unit1.dfm b/demos_delphi/Demo34/Unit1.dfm deleted file mode 100644 index d99467e..0000000 Binary files a/demos_delphi/Demo34/Unit1.dfm and /dev/null differ diff --git a/demos_delphi/Demo34/Unit1.pas b/demos_delphi/Demo34/Unit1.pas deleted file mode 100644 index 9ff6951..0000000 --- a/demos_delphi/Demo34/Unit1.pas +++ /dev/null @@ -1,351 +0,0 @@ -unit Unit1; - -{$I Definition.Inc} - -interface - -uses - SysUtils, Classes, - Windows, Messages, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, PythonVersions, - PythonEngine, PythonGUIInputOutput; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - Panel1: TPanel; - Button1: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - cbPyVersions: TComboBox; - Label1: TLabel; - procedure Button1Click(Sender: TObject); - procedure PythonType1Initialization(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure cbPyVersionsSelect(Sender: TObject); - private - { Déclarations privées } - PythonEngine1: TPythonEngine; - PythonModule1: TPythonModule; - PythonType1: TPythonType; - PyVersions: TPythonVersions; - public - { Déclarations publiques } - procedure CreatePythonComponents; - end; - - // This is a Delphi class implementing a new Python type - // it must derive from TPyObject or one of its descendants. - // Then it must override some methods, like the constructors, - // the RegisterMethods and the type services' virtual methods. - TPyPoint = class(TPyObject) - x, y : Integer; - Name : String; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - - // Type services - //////////////// - - // Basic services - function Repr : PPyObject; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - class procedure RegisterMembers( PythonType : TPythonType ); override; - class procedure RegisterGetSets( PythonType : TPythonType ); override; - - // Methods of TPyPoint - procedure OffsetBy( dx, dy : Integer ); - - // Interface methods - function DoOffsetBy( args : PPyObject ) : PPyObject; cdecl; - function DoRaiseError( args : PPyObject ) : PPyObject; cdecl; - end; - -var - Form1: TForm1; - -implementation - -{$R *.dfm} - -procedure TForm1.cbPyVersionsSelect(Sender: TObject); -begin - CreatePythonComponents -end; - -procedure TForm1.CreatePythonComponents; -begin - if cbPyVersions.ItemIndex <0 then begin - ShowMessage('No Python version is selected'); - Exit; - end; - - // Destroy P4D components - FreeAndNil(PythonEngine1); - FreeAndNil(PythonType1); - FreeAndNil(PythonModule1); - - { TPythonEngine } - PythonEngine1 := TPythonEngine.Create(Self); - PyVersions[cbPyVersions.ItemIndex].AssignTo(PythonEngine1); - - PythonEngine1.IO := PythonGUIInputOutput1; - - - { TPythonModule } - PythonModule1 := TPythonModule.Create(Self); - - PythonModule1.Name := 'PythonModule1'; - PythonModule1.Engine := PythonEngine1; - PythonModule1.ModuleName := 'spam'; - with PythonModule1.Errors.Add do begin - Name := 'PointError'; - ErrorType := etClass; - end; - with PythonModule1.Errors.Add do begin - Name := 'EBadPoint'; - ErrorType := etClass; - ParentClass.Name := 'PointError'; - end; - - { TPythonType } - PythonType1 := TPythonType.Create(Self); - - PythonType1.Name := 'PythonType1'; - PythonType1.Engine := PythonEngine1; - PythonType1.OnInitialization := PythonType1Initialization; - PythonType1.TypeName := 'Point'; - PythonType1.Prefix := 'Create'; - PythonType1.Services.Basic := [bsRepr,bsStr,bsGetAttrO,bsSetAttrO]; - PythonType1.TypeFlags := - [tpfHaveGetCharBuffer,tpfHaveSequenceIn,tpfHaveInplaceOps, - tpfHaveRichCompare,tpfHaveWeakRefs,tpfHaveIter,tpfHaveClass,tpfBaseType]; - PythonType1.Module := PythonModule1; - - PythonEngine1.LoadDll; -end; - -procedure TForm1.FormCreate(Sender: TObject); -Var - PyVersion : TPythonVersion; -begin - PyVersions := GetRegisteredPythonVersions; - for PyVersion in PyVersions do - cbPyVersions.Items.Add(PyVersion.DisplayName); - if cbPyVersions.Items.Count > 0 then begin - cbPyVersions.ItemIndex := 0; - CreatePythonComponents; - end; -end; - - -// First, we need to initialize the property PyObjectClass with -// the class of our Type object -procedure TForm1.PythonType1Initialization(Sender: TObject); -begin - PythonType1.PyObjectClass := TPyPoint; -end; - -// We override the constructors - -constructor TPyPoint.Create( APythonType : TPythonType ); -begin - inherited; - x := 0; - y := 0; -end; - -// Don't call the Create constructor of TPyPoint, because -// we call the inherited constructor CreateWith that calls -// the Create constructor first, and because the constructors -// are virtual, TPyPoint.Create will be automatically be called. - -constructor TPyPoint.CreateWith( PythonType : TPythonType; args : PPyObject ); -begin - inherited; - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'ii:CreatePoint',@x, @y ) = 0 then - exit; - end; -end; - -// Then we override the needed services - -function TPyPoint.Repr : PPyObject; -begin - with GetPythonEngine do - Result := VariantAsPyObject(Format('(%d, %d)',[x, y])); - // or Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[x, y])) ); -end; - -// get/set functions -function TPyPoint_GetName( obj : PPyObject; context : Pointer) : PPyObject; cdecl; -begin - with GetPythonEngine do - Result := PyString_FromString(PAnsiChar(AnsiString(TPyPoint(PythonToDelphi(obj)).Name))); -end; - -function TPyPoint_SetName( obj, value : PPyObject; context : Pointer) : integer; cdecl; -begin - with GetPythonEngine do - begin - if PyString_Check(value) then - begin - TPyPoint(PythonToDelphi(obj)).Name := PyObjectAsVariant(value); - Result := 0; - end - else - begin - Result := -1; - PyErr_SetString(PyExc_AttributeError^, 'attribute Name expected a string value'); - end; - end; -end; - -// Class methods -// We register the methods of our type - -class procedure TPyPoint.RegisterMethods( PythonType : TPythonType ); -begin - inherited; - with PythonType do - begin - AddMethod( 'OffsetBy', @TPyPoint.DoOffsetBy, 'Point.OffsetBy( dx, dy )' ); - AddMethod( 'RaiseError', @TPyPoint.DoRaiseError, 'Point.RaiseError()' ); - end; -end; - -class procedure TPyPoint.RegisterMembers( PythonType : TPythonType ); -begin - with PythonType do - begin - AddMember( 'x', mtInt, NativeInt(@TPyPoint(nil).x), mfDefault, 'x coordinate'); - AddMember( 'y', mtInt, NativeInt(@TPyPoint(nil).y), mfDefault, 'y coordinate'); - end; -end; - -class procedure TPyPoint.RegisterGetSets( PythonType : TPythonType ); -begin - with PythonType do - begin - AddGetSet('Name', TPyPoint_GetName, TPyPoint_SetName, 'Name of a point', nil); - end; -end; - -// Methods of TPyPoint -// They do the real actions on the object -// It's better to split the functions that interface -// Delphi to Python and the functions that do the -// real implementation. - -procedure TPyPoint.OffsetBy( dx, dy : Integer ); -begin - Inc( x, dx ); - Inc( y, dy ); -end; - -// Interface methods -// They will be called directly by Python, so we extract the -// python arguments and we call the method that will really do -// the action. - -function TPyPoint.DoOffsetBy( args : PPyObject ) : PPyObject; -var - dx, dy : Integer; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // first we extract the arguments - if PyArg_ParseTuple( args, 'ii:Point.Offset',@dx, @dy ) <> 0 then - begin - // if it's ok, then we call the method that does the job - // with the correct arguments - OffsetBy( dx, dy ); - // Finally, we return nothing - Result := ReturnNone; - end - else // the arguments were not right - Result := nil; - end; -end; - -// Here's an example of how you can raise errors defined -// in the module linked to our type. -function TPyPoint.DoRaiseError( args : PPyObject ) : PPyObject; -begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // This is a simple call: - //GetModule.RaiseError( 'PointError', 'this is an example of raising an error !' ); - // This is an advanced call: - // We provide the instance vars as a dictionary, so that we can intercept the - // error with "except" and extract informations from the error object. - // ArrayToPyDict needs a list of pairs: varName (string), varValue (anything) - GetModule.RaiseErrorObj( 'EBadPoint', 'this is an example of raising an error !', - ArrayToPyDict( ['a', 1, 'b', 2, 'c', 3] ) ); - Result := nil; - end; -end; - -///////////////////////////////////////////////// - - -procedure TForm1.Button1Click(Sender: TObject); -var - DelphiPoint : TPyPoint; - p : PPyObject; -begin - // Here's how you can create/read Python vars from Delphi with - // Delphi/Python objects. - - // You should ask to the TPythonType to create an instance of its type - // because it will do some initialization. You can use CreateInstanceWith - // if you want to transmit some Python arguments. - // We receive a Python object pointer - p := PythonType1.CreateInstance; - PythonEngine1.CheckError; - // Then we cast the python object to the right delphi type - DelphiPoint := TPyPoint( PythonToDelphi(p) ); - // We do some changes on the delphi object - DelphiPoint.X:=10; - DelphiPoint.Y:=20; - // Add variable "myPoint" in the module "spam". - // So you'll access to the var in the module called spam with: - // import spam - // print spam.myPoint - PythonModule1.SetVar( 'myPoint', p ); - PythonEngine1.Py_DecRef(p); - { - Of course, if you want to retrieve a Python var from a module, - just use the PythonModule1.GetVar or PythonModule1.GetVarAsVariant - Example: - p := PythonModule1.GetVar('myPoint'); - if Assigned(p) then - begin - DelphiPoint := PythonToDelphi(p) as TPyPoint; - ... - Py_XDecRef(p); - end; - - end; } - // Excecute the script - PythonEngine1.ExecStrings( memo1.Lines ); - // Add the following line at the end of the script: - // print spam.myPoint - - // Note, that you must not free the delphi point yourself. - // Instead use the GetPythonEngine.Py_XDECREF(obj) method, - // because the object may be used by another Python object. -end; - -end. diff --git a/demos_delphi/readme.txt b/demos_delphi/readme.txt deleted file mode 100644 index 58bed99..0000000 --- a/demos_delphi/readme.txt +++ /dev/null @@ -1,35 +0,0 @@ -Demo01 A simple Python evaluator -Demo02 Evaluate a Python expression -Demo03 Defining Python/Delphi vars -Demo04 Defining Python/Delphi vars (advanced case) -Demo05 Defining a new Module -Demo06 Defining a new Type -Demo07 Using Delphi methods as Python functions -Demo08 Using Delphi classes for new Python types -Demo09 Making a Python module as a Dll -Demo10 Mapping Delphi VCL components inside Python using TPythonDatabase (BDE - not changed) -Demo10_FireDAC Database demo using FireDAC -Demo11 Using Threads inside Python -Demo12 Using PythonAtom. -> Deprecated since Delphi 6, See VarPyth instead -Demo13 Using TPythonDatabase. (BDE - not changed) -Demo14 Making a Dll with TPythonDatabase (BDE - not changed) -Demo15 Using a TDataset descendant with Python, except TTable and TQuery. (BDE - not changed) -Demo16 Using a TDelphiVar or Module methods ? (Kylix ready) -Demo17 Using variant arrays of 2 dimensions (Kylix ready) -Demo18 C++ Builder: using the Python Dll in a console application -Demo19 C++ Builder: this is a replicate of the Delphi Demo05 -Demo20 C++ Builder: this is a replicate of the Delphi Demo08 -Demo21 Using Events in TPythonModule or TPythonType (Kylix ready) -Demo22 Using Threading, Windows Console and Command line arguments (Kylix ready) -Demo23 Using Threading and Delphi log window. (Kylix ready) -Demo24 Using TAtomPythonEngine (Deprecated since Delphi 6, See VarPyth instead) -Demo25 Using VarPyth.pas (Kylix ready) -Demo26 Demo8 revisited to allow the new Python type to be subclassed -Demo27 Container indexing -Demo28 Iterator (Kylix ready) -Demo29 Using Python Imaging Library (PIL) -Demo30 Using Named Parameters (Kylix ready) -Demo31 Using WrapDelphi to access Delphi Form attributes (Requires Delphi5 or later) -Demo32 Demo08 revisited using WrapDelphi (Requires Delphi7 or later) -Demo33 Using Threads inside Python -Demo34 Dynamically creating, destroying and recreating PythonEngine. Uses PythonVersions diff --git a/demos_lazarus/Demo01/proc_py.pas b/demos_lazarus/Demo01/proc_py.pas deleted file mode 100644 index 9f01237..0000000 --- a/demos_lazarus/Demo01/proc_py.pas +++ /dev/null @@ -1,90 +0,0 @@ -unit proc_py; - -{$mode objfpc}{$H+} - -interface - -uses - SysUtils, - PythonEngine; - -type - TStringDecodeRecW = record - SFrom, STo: WideString; - end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); - -function SBegin(const s, sub: string): boolean; -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -function SWideStringToPythonString(const Str: Widestring): string; - -const - cDefFixedFontName = {$ifdef windows} 'Consolas' {$else} {$ifdef linux} 'Ubuntu Mono' {$else} 'Monaco' {$endif} {$endif}; - cDefFixedFontSize = {$ifdef windows} 9 {$else} 11 {$endif}; - - cDefVarFontName = {$ifdef windows} 'Tahoma' {$else} {$ifdef linux} 'Ubuntu' {$else} 'default' {$endif} {$endif}; - cDefVarFontSize = {$ifdef windows} 9 {$else} 10 {$endif}; - - -implementation - -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -var - i, j: Integer; - DoDecode: Boolean; -begin - Result := ''; - i := 1; - repeat - if i > Length(S) then Break; - DoDecode := False; - for j := Low(Decode) to High(Decode) do - with Decode[j] do - if (SFrom <> '') and (SFrom = Copy(S, i, Length(SFrom))) then - begin - DoDecode := True; - Result := Result + STo; - Inc(i, Length(SFrom)); - Break - end; - if DoDecode then Continue; - Result := Result + S[i]; - Inc(i); - until False; -end; - -function SWideStringToPythonString(const Str: Widestring): string; -const - Decode: array[0..0] of TStringDecodeRecW = - ((SFrom: '"'; STo: '"+''"''+"')); -begin - Result:= UTF8Encode(SDecodeW(Str, Decode)); - Result:= 'r"'+Result+'"'; -end; - -function SBegin(const s, sub: string): boolean; -begin - Result:= Copy(s, 1, Length(sub))=sub; -end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); -var - Str, Sign: string; - i: Integer; -begin - Str:= ''; - for i:= 0 to Length(Dirs)-1 do - Str:= Str + 'r"' + Dirs[i] + '"' + ','; - if DoAdd then - Sign:= '+=' - else - Sign:= '='; - Str:= Format('sys.path %s [%s]', [Sign, Str]); - GetPythonEngine.ExecString(Str); -end; - - - -end. - diff --git a/demos_lazarus/Demo01/project1.lpi b/demos_lazarus/Demo01/project1.lpi deleted file mode 100644 index 267c338..0000000 --- a/demos_lazarus/Demo01/project1.lpi +++ /dev/null @@ -1,202 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo01/project1.lpr b/demos_lazarus/Demo01/project1.lpr deleted file mode 100644 index c450b0c..0000000 --- a/demos_lazarus/Demo01/project1.lpr +++ /dev/null @@ -1,27 +0,0 @@ -program project1; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset - Forms, Unit1; - -{$IFDEF WINDOWS} -{$R project1.rc} -{$ENDIF} -{$IFDEF UNIX} -{$R *.res} -{$ENDIF} - -begin - //{$I project1.lrs} - RequireDerivedFormResource:=True; - Application.Scaled:=True; - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. - diff --git a/demos_lazarus/Demo01/project1.res b/demos_lazarus/Demo01/project1.res deleted file mode 100644 index 631a2cc..0000000 Binary files a/demos_lazarus/Demo01/project1.res and /dev/null differ diff --git a/demos_lazarus/Demo01/unit1.lfm b/demos_lazarus/Demo01/unit1.lfm deleted file mode 100644 index 8d01456..0000000 --- a/demos_lazarus/Demo01/unit1.lfm +++ /dev/null @@ -1,99 +0,0 @@ -object Form1: TForm1 - Left = 1311 - Height = 391 - Top = 261 - Width = 547 - Caption = 'Form1' - ClientHeight = 391 - ClientWidth = 547 - OnCreate = FormCreate - LCLVersion = '2.0.0.4' - object Panel1: TPanel - Left = 0 - Height = 391 - Top = 0 - Width = 547 - Align = alClient - ClientHeight = 391 - ClientWidth = 547 - TabOrder = 0 - object Memo1: TMemo - Left = 1 - Height = 183 - Top = 1 - Width = 545 - Align = alTop - TabOrder = 0 - end - object PairSplitter1: TPairSplitter - Left = 1 - Height = 8 - Top = 184 - Width = 545 - Align = alTop - Position = 45 - object PairSplitterSide1: TPairSplitterSide - Cursor = crArrow - Left = 0 - Height = 8 - Top = 0 - Width = 45 - end - object PairSplitterSide2: TPairSplitterSide - Cursor = crArrow - Left = 50 - Height = 8 - Top = 0 - Width = 495 - end - end - object Memo2: TMemo - Left = 1 - Height = 152 - Top = 192 - Width = 545 - Align = alClient - Lines.Strings = ( - 'print (2+2)' - ) - TabOrder = 2 - end - object Panel2: TPanel - Left = 1 - Height = 46 - Top = 344 - Width = 545 - Align = alBottom - ClientHeight = 46 - ClientWidth = 545 - TabOrder = 3 - object Button1: TButton - Left = 223 - Height = 25 - Top = 8 - Width = 75 - Caption = 'Execute' - OnClick = Button1Click - TabOrder = 0 - end - end - end - object PythonEngine1: TPythonEngine - AutoLoad = False - APIVersion = 1013 - RegVersion = '3.7' - UseLastKnownVersion = False - IO = PythonGUIInputOutput1 - PyFlags = [pfUseClassExceptionsFlag] - left = 96 - top = 48 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - DelayWrites = True - UnicodeIO = False - RawOutput = False - Output = Memo1 - left = 338 - top = 48 - end -end diff --git a/demos_lazarus/Demo01/unit1.pas b/demos_lazarus/Demo01/unit1.pas deleted file mode 100644 index a086cd7..0000000 --- a/demos_lazarus/Demo01/unit1.pas +++ /dev/null @@ -1,77 +0,0 @@ -unit Unit1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, PairSplitter, PythonEngine, PythonGUIInputOutput; - -type - - { TForm1 } - - TForm1 = class(TForm) - Button1: TButton; - Memo1: TMemo; - Memo2: TMemo; - PairSplitter1: TPairSplitter; - PairSplitterSide1: TPairSplitterSide; - PairSplitterSide2: TPairSplitterSide; - Panel1: TPanel; - Panel2: TPanel; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - procedure Button1Click(Sender: TObject); - procedure FormCreate(Sender: TObject); - private - procedure DoPy_InitEngine; - public - { public declarations } - end; - -var - Form1: TForm1; - -implementation - -uses - LclType, proc_py; - -{$R unit1.lfm} - -const - cPyLibraryWindows = 'python37.dll'; - cPyLibraryLinux = 'libpython3.7m.so.1.0'; - cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; - cPyZipWindows = 'python37.zip'; - -{ TForm1 } - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo2.Lines ); -end; - - -procedure TForm1.FormCreate(Sender: TObject); -begin - DoPy_InitEngine; -end; - -procedure TForm1.DoPy_InitEngine; -var - S: string; -begin - S:= - {$ifdef windows} cPyLibraryWindows {$endif} - {$ifdef linux} cPyLibraryLinux {$endif} - {$ifdef darwin} cPyLibraryMac {$endif} ; - PythonEngine1.DllPath:= ExtractFileDir(S); - PythonEngine1.DllName:= ExtractFileName(S); - PythonEngine1.LoadDll; -end; - -end. - diff --git a/demos_lazarus/Demo02/proc_py.pas b/demos_lazarus/Demo02/proc_py.pas deleted file mode 100644 index 9f01237..0000000 --- a/demos_lazarus/Demo02/proc_py.pas +++ /dev/null @@ -1,90 +0,0 @@ -unit proc_py; - -{$mode objfpc}{$H+} - -interface - -uses - SysUtils, - PythonEngine; - -type - TStringDecodeRecW = record - SFrom, STo: WideString; - end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); - -function SBegin(const s, sub: string): boolean; -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -function SWideStringToPythonString(const Str: Widestring): string; - -const - cDefFixedFontName = {$ifdef windows} 'Consolas' {$else} {$ifdef linux} 'Ubuntu Mono' {$else} 'Monaco' {$endif} {$endif}; - cDefFixedFontSize = {$ifdef windows} 9 {$else} 11 {$endif}; - - cDefVarFontName = {$ifdef windows} 'Tahoma' {$else} {$ifdef linux} 'Ubuntu' {$else} 'default' {$endif} {$endif}; - cDefVarFontSize = {$ifdef windows} 9 {$else} 10 {$endif}; - - -implementation - -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -var - i, j: Integer; - DoDecode: Boolean; -begin - Result := ''; - i := 1; - repeat - if i > Length(S) then Break; - DoDecode := False; - for j := Low(Decode) to High(Decode) do - with Decode[j] do - if (SFrom <> '') and (SFrom = Copy(S, i, Length(SFrom))) then - begin - DoDecode := True; - Result := Result + STo; - Inc(i, Length(SFrom)); - Break - end; - if DoDecode then Continue; - Result := Result + S[i]; - Inc(i); - until False; -end; - -function SWideStringToPythonString(const Str: Widestring): string; -const - Decode: array[0..0] of TStringDecodeRecW = - ((SFrom: '"'; STo: '"+''"''+"')); -begin - Result:= UTF8Encode(SDecodeW(Str, Decode)); - Result:= 'r"'+Result+'"'; -end; - -function SBegin(const s, sub: string): boolean; -begin - Result:= Copy(s, 1, Length(sub))=sub; -end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); -var - Str, Sign: string; - i: Integer; -begin - Str:= ''; - for i:= 0 to Length(Dirs)-1 do - Str:= Str + 'r"' + Dirs[i] + '"' + ','; - if DoAdd then - Sign:= '+=' - else - Sign:= '='; - Str:= Format('sys.path %s [%s]', [Sign, Str]); - GetPythonEngine.ExecString(Str); -end; - - - -end. - diff --git a/demos_lazarus/Demo02/project1.lpi b/demos_lazarus/Demo02/project1.lpi deleted file mode 100644 index 2fbc66c..0000000 --- a/demos_lazarus/Demo02/project1.lpi +++ /dev/null @@ -1,242 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo02/project1.lpr b/demos_lazarus/Demo02/project1.lpr deleted file mode 100644 index c450b0c..0000000 --- a/demos_lazarus/Demo02/project1.lpr +++ /dev/null @@ -1,27 +0,0 @@ -program project1; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset - Forms, Unit1; - -{$IFDEF WINDOWS} -{$R project1.rc} -{$ENDIF} -{$IFDEF UNIX} -{$R *.res} -{$ENDIF} - -begin - //{$I project1.lrs} - RequireDerivedFormResource:=True; - Application.Scaled:=True; - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. - diff --git a/demos_lazarus/Demo02/project1.res b/demos_lazarus/Demo02/project1.res deleted file mode 100644 index f6e8499..0000000 Binary files a/demos_lazarus/Demo02/project1.res and /dev/null differ diff --git a/demos_lazarus/Demo02/test_script_demo02.py b/demos_lazarus/Demo02/test_script_demo02.py deleted file mode 100644 index 6f406fc..0000000 --- a/demos_lazarus/Demo02/test_script_demo02.py +++ /dev/null @@ -1 +0,0 @@ -print (2+2) diff --git a/demos_lazarus/Demo02/unit1.lfm b/demos_lazarus/Demo02/unit1.lfm deleted file mode 100644 index 67ce20a..0000000 --- a/demos_lazarus/Demo02/unit1.lfm +++ /dev/null @@ -1,110 +0,0 @@ -object Form1: TForm1 - Left = 929 - Height = 337 - Top = 151 - Width = 528 - Caption = 'Demo 02 of Python' - ClientHeight = 337 - ClientWidth = 528 - Color = clBtnFace - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - OnCreate = FormCreate - LCLVersion = '2.0.0.4' - object Splitter1: TSplitter - Cursor = crVSplit - Left = 0 - Height = 3 - Top = 129 - Width = 528 - Align = alTop - ResizeAnchor = akTop - end - object Memo2: TMemo - Left = 0 - Height = 129 - Top = 0 - Width = 528 - Align = alTop - ScrollBars = ssVertical - TabOrder = 1 - end - object Memo1: TMemo - Left = 0 - Height = 137 - Top = 132 - Width = 528 - Align = alClient - Lines.Strings = ( - 'print (2+2)' - ) - ScrollBars = ssBoth - TabOrder = 2 - end - object Panel1: TPanel - Left = 0 - Height = 68 - Top = 269 - Width = 528 - Align = alBottom - BevelOuter = bvNone - ClientHeight = 68 - ClientWidth = 528 - TabOrder = 0 - object Button1: TButton - Left = 6 - Height = 25 - Top = 8 - Width = 115 - Caption = 'Evaluate script' - OnClick = Button1Click - TabOrder = 0 - end - object Button2: TButton - Left = 168 - Height = 25 - Top = 8 - Width = 91 - Caption = 'Load script...' - OnClick = Button2Click - TabOrder = 1 - end - object Button3: TButton - Left = 264 - Height = 25 - Top = 8 - Width = 89 - Caption = 'Save script...' - OnClick = Button3Click - TabOrder = 2 - end - end - object PythonEngine1: TPythonEngine - AutoLoad = False - DllName = 'libpython3.8.so' - APIVersion = 1013 - RegVersion = '3.7' - UseLastKnownVersion = False - IO = PythonGUIInputOutput1 - PyFlags = [pfUseClassExceptionsFlag] - left = 32 - end - object OpenDialog1: TOpenDialog - DefaultExt = '.*.py' - FileName = 'Unit1.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 176 - end - object SaveDialog1: TSaveDialog - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 208 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = True - RawOutput = False - Output = Memo2 - left = 64 - end -end diff --git a/demos_lazarus/Demo02/unit1.lrs b/demos_lazarus/Demo02/unit1.lrs deleted file mode 100644 index 8d208ec..0000000 --- a/demos_lazarus/Demo02/unit1.lrs +++ /dev/null @@ -1,33 +0,0 @@ -{ This is an automatically generated lazarus resource file } - -LazarusResources.Add('TForm1','FORMDATA',[ - 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3#170#4#6'Height'#3'Q'#1#3'Top'#3#12#1#5'Wi' - +'dth'#3#16#2#7'Caption'#6#17'Demo 02 of Python'#12'ClientHeight'#3'Q'#1#11'C' - +'lientWidth'#3#16#2#5'Color'#7#9'clBtnFace'#10'Font.Color'#7#12'clWindowText' - +#11'Font.Height'#2#245#9'Font.Name'#6#13'MS Sans Serif'#10'LCLVersion'#6#7'2' - +'.0.0.4'#0#9'TSplitter'#9'Splitter1'#6'Cursor'#7#8'crVSplit'#4'Left'#2#0#6'H' - +'eight'#2#3#3'Top'#3#129#0#5'Width'#3#16#2#5'Align'#7#5'alTop'#12'ResizeAnch' - +'or'#7#5'akTop'#0#0#5'TMemo'#5'Memo2'#4'Left'#2#0#6'Height'#3#129#0#3'Top'#2 - +#0#5'Width'#3#16#2#5'Align'#7#5'alTop'#7'OnEnter'#7#10'FormCreate'#10'Scroll' - +'Bars'#7#10'ssVertical'#8'TabOrder'#2#1#0#0#5'TMemo'#5'Memo1'#4'Left'#2#0#6 - +'Height'#3#137#0#3'Top'#3#132#0#5'Width'#3#16#2#5'Align'#7#8'alClient'#13'Li' - +'nes.Strings'#1#6#11'print (2+2)'#0#10'ScrollBars'#7#6'ssBoth'#8'TabOrder'#2 - +#2#0#0#6'TPanel'#6'Panel1'#4'Left'#2#0#6'Height'#2'D'#3'Top'#3#13#1#5'Width' - +#3#16#2#5'Align'#7#8'alBottom'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2 - +'D'#11'ClientWidth'#3#16#2#8'TabOrder'#2#0#0#7'TButton'#7'Button1'#4'Left'#2 - +#6#6'Height'#2#25#3'Top'#2#8#5'Width'#2's'#7'Caption'#6#15'Evaluate script'#7 - +'OnClick'#7#12'Button1Click'#8'TabOrder'#2#0#0#0#7'TButton'#7'Button2'#4'Lef' - +'t'#3#168#0#6'Height'#2#25#3'Top'#2#8#5'Width'#2'['#7'Caption'#6#14'Load scr' - +'ipt...'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#1#0#0#7'TButton'#7'Butt' - +'on3'#4'Left'#3#8#1#6'Height'#2#25#3'Top'#2#8#5'Width'#2'Y'#7'Caption'#6#14 - +'Save script...'#7'OnClick'#7#12'Button3Click'#8'TabOrder'#2#2#0#0#0#13'TPyt' - +'honEngine'#13'PythonEngine1'#8'AutoLoad'#8#7'DllName'#6#15'libpython3.8.so' - +#10'APIVersion'#3#245#3#10'RegVersion'#6#3'3.7'#19'UseLastKnownVersion'#8#2 - +'IO'#7#21'PythonGUIInputOutput1'#7'PyFlags'#11#24'pfUseClassExceptionsFlag'#0 - +#4'left'#2' '#0#0#11'TOpenDialog'#11'OpenDialog1'#10'DefaultExt'#6#5'.*.py'#8 - +'FileName'#6#8'Unit1.py'#6'Filter'#6'0Python files|*.py|Text files|*.txt|All' - +' files|*.*'#4'left'#3#176#0#0#0#11'TSaveDialog'#11'SaveDialog1'#10'DefaultE' - +'xt'#6#5'.*.py'#6'Filter'#6'0Python files|*.py|Text files|*.txt|All files|*.' - +'*'#4'left'#3#208#0#0#0#21'TPythonGUIInputOutput'#21'PythonGUIInputOutput1'#9 - +'UnicodeIO'#9#9'RawOutput'#8#6'Output'#7#5'Memo1'#4'left'#2'@'#0#0#0 -]); diff --git a/demos_lazarus/Demo02/unit1.pas b/demos_lazarus/Demo02/unit1.pas deleted file mode 100644 index 0cf8a3e..0000000 --- a/demos_lazarus/Demo02/unit1.pas +++ /dev/null @@ -1,113 +0,0 @@ -unit Unit1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, PairSplitter, PythonEngine, PythonGUIInputOutput; - -type - - { TForm1 } - - TForm1 = class(TForm) - Button1: TButton; - Button2: TButton; - Button3: TButton; - Memo1: TMemo; - Memo2: TMemo; - Splitter1: TSplitter; - Panel1: TPanel; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure FormCreate(Sender: TObject); - private - procedure DoPy_InitEngine; - public - { public declarations } - end; - -var - Form1: TForm1; - -implementation - -uses - LclType, proc_py; - -{$R unit1.lfm} - -const - cPyLibraryWindows = 'python37.dll'; - cPyLibraryLinux = 'libpython3.7m.so.1.0'; - cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; - cPyZipWindows = 'python37.zip'; - -{ TForm1 } - -procedure TForm1.Button1Click(Sender: TObject); -var - Result : PPyObject; - cmd : TStrings; -begin - with PythonEngine1 do - begin - cmd := Memo1.Lines; - Result := EvalStrings(cmd); - if Assigned(Result) then - begin - ShowMessage(Format('Eval: %s',[PyObjectAsString(Result)])); - //Memo2.Lines.Add('%s',[PyObjectAsString(Result)]); - Py_DECREF(Result); - end - else - ShowMessage('Could not evaluate the script'); - //Memo2.Lines.Add('Could not evaluate the script'); - end; -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.FormCreate(Sender: TObject); -begin - DoPy_InitEngine; -end; - -procedure TForm1.DoPy_InitEngine; -var - S: string; -begin - S:= - {$ifdef windows} cPyLibraryWindows {$endif} - {$ifdef linux} cPyLibraryLinux {$endif} - {$ifdef darwin} cPyLibraryMac {$endif} ; - PythonEngine1.DllPath:= ExtractFileDir(S); - PythonEngine1.DllName:= ExtractFileName(S); - PythonEngine1.LoadDll; -end; - -end. - diff --git a/demos_lazarus/Demo03/proc_py.pas b/demos_lazarus/Demo03/proc_py.pas deleted file mode 100644 index 9f01237..0000000 --- a/demos_lazarus/Demo03/proc_py.pas +++ /dev/null @@ -1,90 +0,0 @@ -unit proc_py; - -{$mode objfpc}{$H+} - -interface - -uses - SysUtils, - PythonEngine; - -type - TStringDecodeRecW = record - SFrom, STo: WideString; - end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); - -function SBegin(const s, sub: string): boolean; -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -function SWideStringToPythonString(const Str: Widestring): string; - -const - cDefFixedFontName = {$ifdef windows} 'Consolas' {$else} {$ifdef linux} 'Ubuntu Mono' {$else} 'Monaco' {$endif} {$endif}; - cDefFixedFontSize = {$ifdef windows} 9 {$else} 11 {$endif}; - - cDefVarFontName = {$ifdef windows} 'Tahoma' {$else} {$ifdef linux} 'Ubuntu' {$else} 'default' {$endif} {$endif}; - cDefVarFontSize = {$ifdef windows} 9 {$else} 10 {$endif}; - - -implementation - -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -var - i, j: Integer; - DoDecode: Boolean; -begin - Result := ''; - i := 1; - repeat - if i > Length(S) then Break; - DoDecode := False; - for j := Low(Decode) to High(Decode) do - with Decode[j] do - if (SFrom <> '') and (SFrom = Copy(S, i, Length(SFrom))) then - begin - DoDecode := True; - Result := Result + STo; - Inc(i, Length(SFrom)); - Break - end; - if DoDecode then Continue; - Result := Result + S[i]; - Inc(i); - until False; -end; - -function SWideStringToPythonString(const Str: Widestring): string; -const - Decode: array[0..0] of TStringDecodeRecW = - ((SFrom: '"'; STo: '"+''"''+"')); -begin - Result:= UTF8Encode(SDecodeW(Str, Decode)); - Result:= 'r"'+Result+'"'; -end; - -function SBegin(const s, sub: string): boolean; -begin - Result:= Copy(s, 1, Length(sub))=sub; -end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); -var - Str, Sign: string; - i: Integer; -begin - Str:= ''; - for i:= 0 to Length(Dirs)-1 do - Str:= Str + 'r"' + Dirs[i] + '"' + ','; - if DoAdd then - Sign:= '+=' - else - Sign:= '='; - Str:= Format('sys.path %s [%s]', [Sign, Str]); - GetPythonEngine.ExecString(Str); -end; - - - -end. - diff --git a/demos_lazarus/Demo03/project1.lpi b/demos_lazarus/Demo03/project1.lpi deleted file mode 100644 index 963342c..0000000 --- a/demos_lazarus/Demo03/project1.lpi +++ /dev/null @@ -1,350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo03/project1.lpr b/demos_lazarus/Demo03/project1.lpr deleted file mode 100644 index c450b0c..0000000 --- a/demos_lazarus/Demo03/project1.lpr +++ /dev/null @@ -1,27 +0,0 @@ -program project1; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset - Forms, Unit1; - -{$IFDEF WINDOWS} -{$R project1.rc} -{$ENDIF} -{$IFDEF UNIX} -{$R *.res} -{$ENDIF} - -begin - //{$I project1.lrs} - RequireDerivedFormResource:=True; - Application.Scaled:=True; - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. - diff --git a/demos_lazarus/Demo03/project1.res b/demos_lazarus/Demo03/project1.res deleted file mode 100644 index 0ad004b..0000000 Binary files a/demos_lazarus/Demo03/project1.res and /dev/null differ diff --git a/demos_lazarus/Demo03/test_script_demo03.py b/demos_lazarus/Demo03/test_script_demo03.py deleted file mode 100644 index 0270023..0000000 --- a/demos_lazarus/Demo03/test_script_demo03.py +++ /dev/null @@ -1,5 +0,0 @@ -test.Value = 10 -print ('test', test.Value) - -test.Value = [1,2,3] -print (test) diff --git a/demos_lazarus/Demo03/unit1.lfm b/demos_lazarus/Demo03/unit1.lfm deleted file mode 100644 index 9c1c0aa..0000000 --- a/demos_lazarus/Demo03/unit1.lfm +++ /dev/null @@ -1,138 +0,0 @@ -object Form1: TForm1 - Left = 1238 - Height = 375 - Top = 138 - Width = 544 - VertScrollBar.Range = 197 - ActiveControl = Button1 - Caption = 'Demo03 of Python' - ClientHeight = 375 - ClientWidth = 525 - Color = clBackground - Font.Color = clWindowText - Font.Height = 11 - Font.Name = 'MS Sans Serif' - Font.Pitch = fpVariable - OnCreate = FormCreate - LCLVersion = '2.0.0.4' - object Splitter1: TSplitter - Cursor = crVSplit - Left = 0 - Height = 3 - Top = 161 - Width = 525 - Align = alTop - ResizeAnchor = akTop - end - object Memo1: TMemo - Left = 0 - Height = 175 - Top = 164 - Width = 525 - Align = alClient - Lines.Strings = ( - 'test.Value = 10' - 'print (''test'', test.Value)' - '' - 'test.Value = [1,2,3]' - 'print (test)' - ) - ScrollBars = ssBoth - TabOrder = 1 - end - object Panel1: TPanel - Left = 0 - Height = 36 - Top = 339 - Width = 525 - Align = alBottom - BevelOuter = bvNone - ClientHeight = 36 - ClientWidth = 525 - TabOrder = 0 - object Button1: TButton - Left = 6 - Height = 25 - Top = 8 - Width = 115 - Caption = 'Execute script' - OnClick = Button1Click - TabOrder = 0 - end - object Button2: TButton - Left = 168 - Height = 25 - Top = 8 - Width = 91 - Caption = 'Load script...' - OnClick = Button2Click - TabOrder = 1 - end - object Button3: TButton - Left = 264 - Height = 25 - Top = 8 - Width = 89 - Caption = 'Save script...' - OnClick = Button3Click - TabOrder = 2 - end - object Button4: TButton - Left = 368 - Height = 25 - Top = 8 - Width = 105 - Caption = 'Show var content' - OnClick = Button4Click - TabOrder = 3 - end - end - object Memo2: TMemo - Left = 0 - Height = 161 - Top = 0 - Width = 525 - Align = alTop - TabOrder = 2 - end - object PythonEngine1: TPythonEngine - AutoLoad = False - DllName = 'libpython3.8.so' - APIVersion = 1013 - RegVersion = '3.7' - UseLastKnownVersion = False - InitScript.Strings = ( - 'import sys' - 'print (''Python Dll: '', sys.version)' - 'print (sys.copyright)' - 'print' - ) - IO = PythonGUIInputOutput1 - PyFlags = [pfUseClassExceptionsFlag] - left = 32 - end - object OpenDialog1: TOpenDialog - Title = 'Open' - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 176 - end - object SaveDialog1: TSaveDialog - Title = 'Save As' - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 208 - end - object PythonDelphiVar1: TPythonDelphiVar - Engine = PythonEngine1 - Module = '__main__' - VarName = 'test' - left = 128 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = False - RawOutput = False - Output = Memo2 - left = 64 - end -end diff --git a/demos_lazarus/Demo03/unit1.lrs b/demos_lazarus/Demo03/unit1.lrs deleted file mode 100644 index b554ebc..0000000 --- a/demos_lazarus/Demo03/unit1.lrs +++ /dev/null @@ -1,41 +0,0 @@ -{ This is an automatically generated lazarus resource file } - -LazarusResources.Add('TForm1','FORMDATA',[ - 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3#214#4#6'Height'#3'w'#1#3'Top'#3#138#0#5'W' - +'idth'#3' '#2#19'VertScrollBar.Range'#3#197#0#13'ActiveControl'#7#7'Button1' - +#7'Caption'#6#16'Demo03 of Python'#12'ClientHeight'#3'w'#1#11'ClientWidth'#3 - +#13#2#5'Color'#7#12'clBackground'#10'Font.Color'#7#12'clWindowText'#11'Font.' - +'Height'#2#11#9'Font.Name'#6#13'MS Sans Serif'#10'Font.Pitch'#7#10'fpVariabl' - +'e'#10'LCLVersion'#6#7'2.0.0.4'#0#9'TSplitter'#9'Splitter1'#6'Cursor'#7#8'cr' - +'VSplit'#4'Left'#2#0#6'Height'#2#3#3'Top'#3#161#0#5'Width'#3#13#2#5'Align'#7 - +#5'alTop'#12'ResizeAnchor'#7#5'akTop'#0#0#5'TMemo'#5'Memo1'#4'Left'#2#0#6'He' - +'ight'#3#175#0#3'Top'#3#164#0#5'Width'#3#13#2#5'Align'#7#8'alClient'#13'Line' - +'s.Strings'#1#6#15'test.Value = 10'#6#22'print test, test.Value'#6#0#6#20'te' - +'st.Value = [1,2,3]'#6#10'print test'#0#10'ScrollBars'#7#6'ssBoth'#8'TabOrde' - +'r'#2#1#0#0#6'TPanel'#6'Panel1'#4'Left'#2#0#6'Height'#2'$'#3'Top'#3'S'#1#5'W' - +'idth'#3#13#2#5'Align'#7#8'alBottom'#10'BevelOuter'#7#6'bvNone'#12'ClientHei' - +'ght'#2'$'#11'ClientWidth'#3#13#2#8'TabOrder'#2#0#0#7'TButton'#7'Button1'#4 - +'Left'#2#6#6'Height'#2#25#3'Top'#2#8#5'Width'#2's'#7'Caption'#6#14'Execute s' - +'cript'#7'OnClick'#7#12'Button1Click'#8'TabOrder'#2#0#0#0#7'TButton'#7'Butto' - +'n2'#4'Left'#3#168#0#6'Height'#2#25#3'Top'#2#8#5'Width'#2'['#7'Caption'#6#14 - +'Load script...'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#1#0#0#7'TButton' - +#7'Button3'#4'Left'#3#8#1#6'Height'#2#25#3'Top'#2#8#5'Width'#2'Y'#7'Caption' - +#6#14'Save script...'#7'OnClick'#7#12'Button3Click'#8'TabOrder'#2#2#0#0#7'TB' - +'utton'#7'Button4'#4'Left'#3'p'#1#6'Height'#2#25#3'Top'#2#8#5'Width'#2'i'#7 - +'Caption'#6#16'Show var content'#7'OnClick'#7#12'Button4Click'#8'TabOrder'#2 - +#3#0#0#0#5'TMemo'#5'Memo2'#4'Left'#2#0#6'Height'#3#161#0#3'Top'#2#0#5'Width' - +#3#13#2#5'Align'#7#5'alTop'#8'TabOrder'#2#2#0#0#13'TPythonEngine'#13'PythonE' - +'ngine1'#8'AutoLoad'#8#7'DllName'#6#15'libpython3.8.so'#10'APIVersion'#3#245 - +#3#10'RegVersion'#6#3'3.7'#19'UseLastKnownVersion'#8#18'InitScript.Strings'#1 - +#6#10'import sys'#6'!print "Python Dll: ", sys.version'#6#19'print sys.copyr' - +'ight'#6#5'print'#0#2'IO'#7#21'PythonGUIInputOutput1'#7'PyFlags'#11#24'pfUse' - +'ClassExceptionsFlag'#0#4'left'#2' '#0#0#11'TOpenDialog'#11'OpenDialog1'#5'T' - +'itle'#6#4'Open'#10'DefaultExt'#6#5'.*.py'#6'Filter'#6'0Python files|*.py|Te' - +'xt files|*.txt|All files|*.*'#4'left'#3#176#0#0#0#11'TSaveDialog'#11'SaveDi' - +'alog1'#5'Title'#6#7'Save As'#10'DefaultExt'#6#5'.*.py'#6'Filter'#6'0Python ' - +'files|*.py|Text files|*.txt|All files|*.*'#4'left'#3#208#0#0#0#16'TPythonDe' - +'lphiVar'#16'PythonDelphiVar1'#6'Engine'#7#13'PythonEngine1'#6'Module'#6#8'_' - +'_main__'#7'VarName'#6#4'test'#4'left'#3#128#0#0#0#21'TPythonGUIInputOutput' - +#21'PythonGUIInputOutput1'#9'UnicodeIO'#8#9'RawOutput'#8#6'Output'#7#5'Memo2' - +#4'left'#2'@'#0#0#0 -]); diff --git a/demos_lazarus/Demo03/unit1.pas b/demos_lazarus/Demo03/unit1.pas deleted file mode 100644 index 5889e3f..0000000 --- a/demos_lazarus/Demo03/unit1.pas +++ /dev/null @@ -1,101 +0,0 @@ -unit Unit1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, PairSplitter, PythonGUIInputOutput, PythonEngine; - -type - - { TForm1 } - - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - PythonDelphiVar1: TPythonDelphiVar; - Memo1: TMemo; - Memo2: TMemo; - Panel1: TPanel; - Splitter1: TSplitter; - Button1: TButton; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - procedure FormCreate(Sender: TObject); - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - private - procedure DoPy_InitEngine; - public - { D�clarations publiques } - end; - -var - Form1: TForm1; - -implementation - -uses - LclType, proc_py; - -{$R *.lfm} - -const - cPyLibraryWindows = 'python37.dll'; - cPyLibraryLinux = 'libpython3.7m.so.1.0'; - cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; - cPyZipWindows = 'python37.zip'; - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.Button4Click(Sender: TObject); -begin - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); -end; - -procedure TForm1.FormCreate(Sender: TObject); -begin - DoPy_InitEngine; -end; - -procedure TForm1.DoPy_InitEngine; -var - S: string; -begin - S:= - {$ifdef windows} cPyLibraryWindows {$endif} - {$ifdef linux} cPyLibraryLinux {$endif} - {$ifdef darwin} cPyLibraryMac {$endif} ; - PythonEngine1.DllPath:= ExtractFileDir(S); - PythonEngine1.DllName:= ExtractFileName(S); - PythonEngine1.LoadDll; -end; - -end. diff --git a/demos_lazarus/Demo04/proc_py.pas b/demos_lazarus/Demo04/proc_py.pas deleted file mode 100644 index 9f01237..0000000 --- a/demos_lazarus/Demo04/proc_py.pas +++ /dev/null @@ -1,90 +0,0 @@ -unit proc_py; - -{$mode objfpc}{$H+} - -interface - -uses - SysUtils, - PythonEngine; - -type - TStringDecodeRecW = record - SFrom, STo: WideString; - end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); - -function SBegin(const s, sub: string): boolean; -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -function SWideStringToPythonString(const Str: Widestring): string; - -const - cDefFixedFontName = {$ifdef windows} 'Consolas' {$else} {$ifdef linux} 'Ubuntu Mono' {$else} 'Monaco' {$endif} {$endif}; - cDefFixedFontSize = {$ifdef windows} 9 {$else} 11 {$endif}; - - cDefVarFontName = {$ifdef windows} 'Tahoma' {$else} {$ifdef linux} 'Ubuntu' {$else} 'default' {$endif} {$endif}; - cDefVarFontSize = {$ifdef windows} 9 {$else} 10 {$endif}; - - -implementation - -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -var - i, j: Integer; - DoDecode: Boolean; -begin - Result := ''; - i := 1; - repeat - if i > Length(S) then Break; - DoDecode := False; - for j := Low(Decode) to High(Decode) do - with Decode[j] do - if (SFrom <> '') and (SFrom = Copy(S, i, Length(SFrom))) then - begin - DoDecode := True; - Result := Result + STo; - Inc(i, Length(SFrom)); - Break - end; - if DoDecode then Continue; - Result := Result + S[i]; - Inc(i); - until False; -end; - -function SWideStringToPythonString(const Str: Widestring): string; -const - Decode: array[0..0] of TStringDecodeRecW = - ((SFrom: '"'; STo: '"+''"''+"')); -begin - Result:= UTF8Encode(SDecodeW(Str, Decode)); - Result:= 'r"'+Result+'"'; -end; - -function SBegin(const s, sub: string): boolean; -begin - Result:= Copy(s, 1, Length(sub))=sub; -end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); -var - Str, Sign: string; - i: Integer; -begin - Str:= ''; - for i:= 0 to Length(Dirs)-1 do - Str:= Str + 'r"' + Dirs[i] + '"' + ','; - if DoAdd then - Sign:= '+=' - else - Sign:= '='; - Str:= Format('sys.path %s [%s]', [Sign, Str]); - GetPythonEngine.ExecString(Str); -end; - - - -end. - diff --git a/demos_lazarus/Demo04/project1.lpi b/demos_lazarus/Demo04/project1.lpi deleted file mode 100644 index 823f36c..0000000 --- a/demos_lazarus/Demo04/project1.lpi +++ /dev/null @@ -1,380 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo04/project1.res b/demos_lazarus/Demo04/project1.res deleted file mode 100644 index 0ad004b..0000000 Binary files a/demos_lazarus/Demo04/project1.res and /dev/null differ diff --git a/demos_lazarus/Demo04/test_script_demo04.py b/demos_lazarus/Demo04/test_script_demo04.py deleted file mode 100644 index 08a13a6..0000000 --- a/demos_lazarus/Demo04/test_script_demo04.py +++ /dev/null @@ -1,12 +0,0 @@ -print ('Current value of var test is: ', test) -test.Value = 'New value set by Python' -print ('New value is:', test) -print ('-----------------------------------------------------') -class C: - def __init__(Self, Arg): - Self.Arg = Arg - def __str__(Self): - return '' -print ('Current value of var object is: ', object) -object.Value = C('Hello !') -print ('New value is:', object) diff --git a/demos_lazarus/Demo04/unit1.lfm b/demos_lazarus/Demo04/unit1.lfm deleted file mode 100644 index cac9b76..0000000 --- a/demos_lazarus/Demo04/unit1.lfm +++ /dev/null @@ -1,171 +0,0 @@ -object Form1: TForm1 - Left = 1228 - Height = 422 - Top = 124 - Width = 544 - Caption = 'Demo of Python' - ClientHeight = 422 - ClientWidth = 544 - Color = clBtnFace - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - OnCreate = FormCreate - LCLVersion = '2.0.0.4' - object Splitter1: TSplitter - Cursor = crVSplit - Left = 0 - Height = 3 - Top = 137 - Width = 544 - Align = alTop - ResizeAnchor = akTop - end - object Memo1: TMemo - Left = 0 - Height = 214 - Top = 140 - Width = 544 - Align = alClient - Lines.Strings = ( - 'print (''Current value of var test is: '', test)' - 'test.Value = ''New value set by Python''' - 'print (''New value is:'', test)' - 'print (''-----------------------------------------------------'')' - 'class C:' - ' def __init__(Self, Arg):' - ' Self.Arg = Arg' - ' def __str__(Self):' - ' return ''''' - 'print (''Current value of var object is: '', object)' - 'object.Value = C(''Hello !'')' - 'print (''New value is:'', object)' - ) - ScrollBars = ssBoth - TabOrder = 1 - end - object Panel1: TPanel - Left = 0 - Height = 68 - Top = 354 - Width = 544 - Align = alBottom - BevelOuter = bvNone - ClientHeight = 68 - ClientWidth = 544 - TabOrder = 0 - object Label1: TLabel - Left = 328 - Height = 14 - Top = 42 - Width = 48 - Caption = 'var test:' - ParentColor = False - end - object Button1: TButton - Left = 6 - Height = 25 - Top = 8 - Width = 115 - Caption = 'Execute script' - OnClick = Button1Click - TabOrder = 0 - end - object Button2: TButton - Left = 168 - Height = 25 - Top = 8 - Width = 91 - Caption = 'Load script...' - OnClick = Button2Click - TabOrder = 1 - end - object Button3: TButton - Left = 264 - Height = 25 - Top = 8 - Width = 89 - Caption = 'Save script...' - OnClick = Button3Click - TabOrder = 2 - end - object Button4: TButton - Left = 368 - Height = 25 - Top = 8 - Width = 89 - Caption = 'Show var test' - OnClick = Button4Click - TabOrder = 3 - end - object Edit1: TEdit - Left = 368 - Height = 22 - Top = 40 - Width = 161 - TabOrder = 4 - Text = 'Edit1' - end - end - object Memo2: TMemo - Left = 0 - Height = 137 - Top = 0 - Width = 544 - Align = alTop - Lines.Strings = ( - '' - ) - TabOrder = 2 - end - object PythonEngine1: TPythonEngine - AutoLoad = False - DllName = 'libpython3.8.so' - APIVersion = 1013 - RegVersion = '3.7' - UseLastKnownVersion = False - InitScript.Strings = ( - 'import sys' - 'print (''Python Dll: '', sys.version)' - 'print (sys.copyright)' - 'print' - ) - IO = PythonGUIInputOutput1 - PyFlags = [pfUseClassExceptionsFlag] - left = 32 - end - object OpenDialog1: TOpenDialog - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 176 - end - object SaveDialog1: TSaveDialog - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 208 - end - object PythonDelphiVar1: TPythonDelphiVar - Engine = PythonEngine1 - Module = '__main__' - VarName = 'test' - OnGetData = PythonDelphiVar1GetData - OnSetData = PythonDelphiVar1SetData - OnChange = PythonDelphiVar1Change - left = 128 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = False - RawOutput = False - Output = Memo2 - left = 64 - end - object PythonDelphiVar2: TPythonDelphiVar - Engine = PythonEngine1 - Module = '__main__' - VarName = 'object' - OnExtGetData = PythonDelphiVar2ExtGetData - OnExtSetData = PythonDelphiVar2ExtSetData - left = 128 - top = 32 - end -end diff --git a/demos_lazarus/Demo04/unit1.pas b/demos_lazarus/Demo04/unit1.pas deleted file mode 100644 index 0469995..0000000 --- a/demos_lazarus/Demo04/unit1.pas +++ /dev/null @@ -1,152 +0,0 @@ -unit Unit1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, PairSplitter, PythonGUIInputOutput, PythonEngine, - Messages, ComCtrls; - -type - - { TForm1 } - - TForm1 = class(TForm) - PythonEngine1: TPythonEngine; - Memo1: TMemo; - Memo2: TMemo; - Panel1: TPanel; - Splitter1: TSplitter; - Button1: TButton; - Button2: TButton; - Button3: TButton; - Button4: TButton; - Edit1: TEdit; - Label1: TLabel; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonDelphiVar1: TPythonDelphiVar; - PythonGUIInputOutput1: TPythonGUIInputOutput; - PythonDelphiVar2: TPythonDelphiVar; - procedure Button1Click(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - procedure PythonDelphiVar1Change(Sender: TObject); - procedure PythonDelphiVar1GetData(Sender: TObject; var Data: Variant); - procedure PythonDelphiVar1SetData(Sender: TObject; Data: Variant); - procedure PythonDelphiVar2ExtGetData(Sender: TObject; - var Data: PPyObject); - procedure PythonDelphiVar2ExtSetData(Sender: TObject; Data: PPyObject); - procedure FormCreate(Sender: TObject); - private - FMyPythonObject : PPyObject; - procedure DoPy_InitEngine; - public - { D�clarations publiques } - end; - -var - Form1: TForm1; - -implementation - -uses - LclType, proc_py; - -{$R *.lfm} - -const - cPyLibraryWindows = 'python37.dll'; - cPyLibraryLinux = 'libpython3.7m.so.1.0'; - cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; - cPyZipWindows = 'python37.zip'; - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.Button4Click(Sender: TObject); -begin - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1Change(Sender: TObject); -begin - with Sender as TPythonDelphiVar do - ShowMessage( 'Var test changed: ' + ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1GetData(Sender: TObject; - var Data: Variant); -begin - Data := Edit1.Text; -end; - -procedure TForm1.PythonDelphiVar1SetData(Sender: TObject; Data: Variant); -begin - Edit1.Text := Data; -end; - -procedure TForm1.PythonDelphiVar2ExtGetData(Sender: TObject; - var Data: PPyObject); -begin - with GetPythonEngine do - begin - Data := FMyPythonObject; - Py_XIncRef(Data); // This is very important - end; -end; - -procedure TForm1.PythonDelphiVar2ExtSetData(Sender: TObject; - Data: PPyObject); -begin - with GetPythonEngine do - begin - Py_XDecRef(FMyPythonObject); // This is very important - FMyPythonObject := Data; - Py_XIncRef(FMyPythonObject); // This is very important - end; -end; - -procedure TForm1.FormCreate(Sender: TObject); -begin - DoPy_InitEngine; -end; - -procedure TForm1.DoPy_InitEngine; -var - S: string; -begin - S:= - {$ifdef windows} cPyLibraryWindows {$endif} - {$ifdef linux} cPyLibraryLinux {$endif} - {$ifdef darwin} cPyLibraryMac {$endif} ; - PythonEngine1.DllPath:= ExtractFileDir(S); - PythonEngine1.DllName:= ExtractFileName(S); - PythonEngine1.LoadDll; -end; - -end. diff --git a/demos_lazarus/Demo05/proc_py.pas b/demos_lazarus/Demo05/proc_py.pas deleted file mode 100644 index 9f01237..0000000 --- a/demos_lazarus/Demo05/proc_py.pas +++ /dev/null @@ -1,90 +0,0 @@ -unit proc_py; - -{$mode objfpc}{$H+} - -interface - -uses - SysUtils, - PythonEngine; - -type - TStringDecodeRecW = record - SFrom, STo: WideString; - end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); - -function SBegin(const s, sub: string): boolean; -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -function SWideStringToPythonString(const Str: Widestring): string; - -const - cDefFixedFontName = {$ifdef windows} 'Consolas' {$else} {$ifdef linux} 'Ubuntu Mono' {$else} 'Monaco' {$endif} {$endif}; - cDefFixedFontSize = {$ifdef windows} 9 {$else} 11 {$endif}; - - cDefVarFontName = {$ifdef windows} 'Tahoma' {$else} {$ifdef linux} 'Ubuntu' {$else} 'default' {$endif} {$endif}; - cDefVarFontSize = {$ifdef windows} 9 {$else} 10 {$endif}; - - -implementation - -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -var - i, j: Integer; - DoDecode: Boolean; -begin - Result := ''; - i := 1; - repeat - if i > Length(S) then Break; - DoDecode := False; - for j := Low(Decode) to High(Decode) do - with Decode[j] do - if (SFrom <> '') and (SFrom = Copy(S, i, Length(SFrom))) then - begin - DoDecode := True; - Result := Result + STo; - Inc(i, Length(SFrom)); - Break - end; - if DoDecode then Continue; - Result := Result + S[i]; - Inc(i); - until False; -end; - -function SWideStringToPythonString(const Str: Widestring): string; -const - Decode: array[0..0] of TStringDecodeRecW = - ((SFrom: '"'; STo: '"+''"''+"')); -begin - Result:= UTF8Encode(SDecodeW(Str, Decode)); - Result:= 'r"'+Result+'"'; -end; - -function SBegin(const s, sub: string): boolean; -begin - Result:= Copy(s, 1, Length(sub))=sub; -end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); -var - Str, Sign: string; - i: Integer; -begin - Str:= ''; - for i:= 0 to Length(Dirs)-1 do - Str:= Str + 'r"' + Dirs[i] + '"' + ','; - if DoAdd then - Sign:= '+=' - else - Sign:= '='; - Str:= Format('sys.path %s [%s]', [Sign, Str]); - GetPythonEngine.ExecString(Str); -end; - - - -end. - diff --git a/demos_lazarus/Demo05/project1.lpi b/demos_lazarus/Demo05/project1.lpi deleted file mode 100644 index 370ee59..0000000 --- a/demos_lazarus/Demo05/project1.lpi +++ /dev/null @@ -1,404 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo05/project1.lpr b/demos_lazarus/Demo05/project1.lpr deleted file mode 100644 index c450b0c..0000000 --- a/demos_lazarus/Demo05/project1.lpr +++ /dev/null @@ -1,27 +0,0 @@ -program project1; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset - Forms, Unit1; - -{$IFDEF WINDOWS} -{$R project1.rc} -{$ENDIF} -{$IFDEF UNIX} -{$R *.res} -{$ENDIF} - -begin - //{$I project1.lrs} - RequireDerivedFormResource:=True; - Application.Scaled:=True; - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. - diff --git a/demos_lazarus/Demo05/project1.res b/demos_lazarus/Demo05/project1.res deleted file mode 100644 index 0ad004b..0000000 Binary files a/demos_lazarus/Demo05/project1.res and /dev/null differ diff --git a/demos_lazarus/Demo05/test_script_demo05.py b/demos_lazarus/Demo05/test_script_demo05.py deleted file mode 100644 index 8060f5e..0000000 --- a/demos_lazarus/Demo05/test_script_demo05.py +++ /dev/null @@ -1,2 +0,0 @@ -import spam -print (spam.foo('hello world', 1)) diff --git a/demos_lazarus/Demo05/unit1.lfm b/demos_lazarus/Demo05/unit1.lfm deleted file mode 100644 index d6cc20f..0000000 --- a/demos_lazarus/Demo05/unit1.lfm +++ /dev/null @@ -1,125 +0,0 @@ -object Form1: TForm1 - Left = 1313 - Height = 336 - Top = 167 - Width = 528 - Caption = 'Demo of Python' - ClientHeight = 336 - ClientWidth = 528 - Color = clBtnFace - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - OnCreate = FormCreate - LCLVersion = '2.0.0.4' - object Splitter1: TSplitter - Cursor = crVSplit - Left = 0 - Height = 3 - Top = 129 - Width = 528 - Align = alTop - ResizeAnchor = akTop - end - object Memo1: TMemo - Left = 0 - Height = 168 - Top = 132 - Width = 528 - Align = alClient - Lines.Strings = ( - 'import spam' - 'print (spam.foo(''hello world'', 1))' - ) - ScrollBars = ssBoth - TabOrder = 1 - end - object Panel1: TPanel - Left = 0 - Height = 36 - Top = 300 - Width = 528 - Align = alBottom - BevelOuter = bvNone - ClientHeight = 36 - ClientWidth = 528 - TabOrder = 0 - object Button1: TButton - Left = 6 - Height = 25 - Top = 8 - Width = 115 - Caption = 'Execute script' - OnClick = Button1Click - TabOrder = 0 - end - object Button2: TButton - Left = 168 - Height = 25 - Top = 8 - Width = 91 - Caption = 'Load script...' - OnClick = Button2Click - TabOrder = 1 - end - object Button3: TButton - Left = 264 - Height = 25 - Top = 8 - Width = 89 - Caption = 'Save script...' - OnClick = Button3Click - TabOrder = 2 - end - end - object Memo2: TMemo - Left = 0 - Height = 129 - Top = 0 - Width = 528 - Align = alTop - Lines.Strings = ( - 'Memo2' - ) - TabOrder = 2 - end - object PythonEngine1: TPythonEngine - AutoLoad = False - DllName = 'libpython3.8.so' - APIVersion = 1013 - RegVersion = '3.7' - UseLastKnownVersion = False - InitScript.Strings = ( - 'import sys' - 'print (''Python Dll: '', sys.version)' - 'print (sys.copyright)' - 'print' - ) - IO = PythonGUIInputOutput1 - PyFlags = [pfUseClassExceptionsFlag] - left = 32 - end - object PythonModule1: TPythonModule - Engine = PythonEngine1 - OnInitialization = PythonModule1Initialization - ModuleName = 'spam' - Errors = <> - left = 96 - end - object OpenDialog1: TOpenDialog - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 176 - end - object SaveDialog1: TSaveDialog - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 208 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = True - RawOutput = False - Output = Memo2 - left = 64 - end -end diff --git a/demos_lazarus/Demo05/unit1.pas b/demos_lazarus/Demo05/unit1.pas deleted file mode 100644 index 1401862..0000000 --- a/demos_lazarus/Demo05/unit1.pas +++ /dev/null @@ -1,121 +0,0 @@ -unit Unit1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, PairSplitter, PythonGUIInputOutput, PythonEngine, - Messages, ComCtrls; - -type - - { TForm1 } - - TForm1 = class(TForm) - Memo1: TMemo; - Memo2: TMemo; - Panel1: TPanel; - Splitter1: TSplitter; - Button1: TButton; - Button2: TButton; - Button3: TButton; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonModule1: TPythonModule; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - procedure FormCreate(Sender: TObject); - procedure Button1Click(Sender: TObject); - procedure PythonModule1Initialization(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - private - procedure DoPy_InitEngine; - public - { D�clarations publiques } - end; - - function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; - -var - Form1: TForm1; - -implementation - -uses - LclType, proc_py; - -{$R *.lfm} - -const - cPyLibraryWindows = 'python37.dll'; - cPyLibraryLinux = 'libpython3.7m.so.1.0'; - cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; - cPyZipWindows = 'python37.zip'; - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -// Here's an example of functions defined for the module spam - -function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - ShowMessage( 'args of foo: '+PyObjectAsString(args) ); - Result := ReturnNone; - end; -end; - -procedure TForm1.PythonModule1Initialization(Sender: TObject); -begin - // In a module initialization, we just need to add our - // new methods - with Sender as TPythonModule do - begin - AddMethod('foo', @spam_foo, 'foo'); - end; -end; - - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.FormCreate(Sender: TObject); -begin - DoPy_InitEngine; -end; - -procedure TForm1.DoPy_InitEngine; -var - S: string; -begin - S:= - {$ifdef windows} cPyLibraryWindows {$endif} - {$ifdef linux} cPyLibraryLinux {$endif} - {$ifdef darwin} cPyLibraryMac {$endif} ; - PythonEngine1.DllPath:= ExtractFileDir(S); - PythonEngine1.DllName:= ExtractFileName(S); - PythonEngine1.LoadDll; -end; - -end. diff --git a/demos_lazarus/Demo06/proc_py.pas b/demos_lazarus/Demo06/proc_py.pas deleted file mode 100644 index 9f01237..0000000 --- a/demos_lazarus/Demo06/proc_py.pas +++ /dev/null @@ -1,90 +0,0 @@ -unit proc_py; - -{$mode objfpc}{$H+} - -interface - -uses - SysUtils, - PythonEngine; - -type - TStringDecodeRecW = record - SFrom, STo: WideString; - end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); - -function SBegin(const s, sub: string): boolean; -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -function SWideStringToPythonString(const Str: Widestring): string; - -const - cDefFixedFontName = {$ifdef windows} 'Consolas' {$else} {$ifdef linux} 'Ubuntu Mono' {$else} 'Monaco' {$endif} {$endif}; - cDefFixedFontSize = {$ifdef windows} 9 {$else} 11 {$endif}; - - cDefVarFontName = {$ifdef windows} 'Tahoma' {$else} {$ifdef linux} 'Ubuntu' {$else} 'default' {$endif} {$endif}; - cDefVarFontSize = {$ifdef windows} 9 {$else} 10 {$endif}; - - -implementation - -function SDecodeW(const S: WideString; const Decode: array of TStringDecodeRecW): WideString; -var - i, j: Integer; - DoDecode: Boolean; -begin - Result := ''; - i := 1; - repeat - if i > Length(S) then Break; - DoDecode := False; - for j := Low(Decode) to High(Decode) do - with Decode[j] do - if (SFrom <> '') and (SFrom = Copy(S, i, Length(SFrom))) then - begin - DoDecode := True; - Result := Result + STo; - Inc(i, Length(SFrom)); - Break - end; - if DoDecode then Continue; - Result := Result + S[i]; - Inc(i); - until False; -end; - -function SWideStringToPythonString(const Str: Widestring): string; -const - Decode: array[0..0] of TStringDecodeRecW = - ((SFrom: '"'; STo: '"+''"''+"')); -begin - Result:= UTF8Encode(SDecodeW(Str, Decode)); - Result:= 'r"'+Result+'"'; -end; - -function SBegin(const s, sub: string): boolean; -begin - Result:= Copy(s, 1, Length(sub))=sub; -end; - -procedure Py_SetSysPath(const Dirs: array of string; DoAdd: boolean); -var - Str, Sign: string; - i: Integer; -begin - Str:= ''; - for i:= 0 to Length(Dirs)-1 do - Str:= Str + 'r"' + Dirs[i] + '"' + ','; - if DoAdd then - Sign:= '+=' - else - Sign:= '='; - Str:= Format('sys.path %s [%s]', [Sign, Str]); - GetPythonEngine.ExecString(Str); -end; - - - -end. - diff --git a/demos_lazarus/Demo06/project1.lpi b/demos_lazarus/Demo06/project1.lpi deleted file mode 100644 index 421ca8e..0000000 --- a/demos_lazarus/Demo06/project1.lpi +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo06/project1.lpr b/demos_lazarus/Demo06/project1.lpr deleted file mode 100644 index c450b0c..0000000 --- a/demos_lazarus/Demo06/project1.lpr +++ /dev/null @@ -1,27 +0,0 @@ -program project1; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset - Forms, Unit1; - -{$IFDEF WINDOWS} -{$R project1.rc} -{$ENDIF} -{$IFDEF UNIX} -{$R *.res} -{$ENDIF} - -begin - //{$I project1.lrs} - RequireDerivedFormResource:=True; - Application.Scaled:=True; - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. - diff --git a/demos_lazarus/Demo06/project1.res b/demos_lazarus/Demo06/project1.res deleted file mode 100644 index 0ad004b..0000000 Binary files a/demos_lazarus/Demo06/project1.res and /dev/null differ diff --git a/demos_lazarus/Demo06/test_script_demo06.py b/demos_lazarus/Demo06/test_script_demo06.py deleted file mode 100644 index 271c81a..0000000 --- a/demos_lazarus/Demo06/test_script_demo06.py +++ /dev/null @@ -1,12 +0,0 @@ -import sys -import spam -print (spam.foo('hello world', 1)) -p = spam.CreatePoint( 10, 25 ) -print ('Point: ', p) -p.x = 58 -print (p.x, p) -p.OffsetBy( 5, 5 ) -print (p) -print ('Current value of var test is: ', test) -test.Value = ('New value set by Python') -print ('getdouble: ', spam.getdouble()) diff --git a/demos_lazarus/Demo06/unit1.lfm b/demos_lazarus/Demo06/unit1.lfm deleted file mode 100644 index b92b9b7..0000000 --- a/demos_lazarus/Demo06/unit1.lfm +++ /dev/null @@ -1,173 +0,0 @@ -object Form1: TForm1 - Left = 31 - Height = 337 - Top = 143 - Width = 528 - Caption = 'Demo 06 of Python' - ClientHeight = 337 - ClientWidth = 528 - Color = clBtnFace - Font.Color = clWindowText - Font.Height = -11 - Font.Name = 'MS Sans Serif' - OnCreate = FormCreate - LCLVersion = '2.0.0.4' - object Splitter1: TSplitter - Cursor = crVSplit - Left = 0 - Height = 3 - Top = 145 - Width = 528 - Align = alTop - ResizeAnchor = akTop - end - object Memo1: TMemo - Left = 0 - Height = 121 - Top = 148 - Width = 528 - Align = alClient - Lines.Strings = ( - 'import sys' - 'import spam' - 'print (spam.foo(''hello world'', 1))' - 'p = spam.CreatePoint( 10, 25 )' - 'print (''Point: '', p)' - 'p.x = 58' - 'print (p.x, p)' - 'p.OffsetBy( 5, 5 )' - 'print (p)' - 'print (''Current value of var test is: '', test)' - 'test.Value = (''New value set by Python'')' - 'print (''getdouble: '', spam.getdouble())' - ) - ScrollBars = ssVertical - TabOrder = 1 - end - object Panel1: TPanel - Left = 0 - Height = 68 - Top = 269 - Width = 528 - Align = alBottom - BevelOuter = bvNone - ClientHeight = 68 - ClientWidth = 528 - TabOrder = 0 - object Button1: TButton - Left = 6 - Height = 25 - Top = 8 - Width = 115 - Caption = 'Execute script' - OnClick = Button1Click - TabOrder = 0 - end - object Button2: TButton - Left = 168 - Height = 25 - Top = 8 - Width = 91 - Caption = 'Load script...' - OnClick = Button2Click - TabOrder = 1 - end - object Button3: TButton - Left = 264 - Height = 25 - Top = 8 - Width = 89 - Caption = 'Save script...' - OnClick = Button3Click - TabOrder = 2 - end - object Button4: TButton - Left = 368 - Height = 25 - Top = 8 - Width = 89 - Caption = 'Show var test' - OnClick = Button4Click - TabOrder = 3 - end - object Edit1: TEdit - Left = 368 - Height = 22 - Top = 32 - Width = 161 - TabOrder = 4 - Text = 'Edit1' - end - end - object Memo2: TMemo - Left = 0 - Height = 145 - Top = 0 - Width = 528 - Align = alTop - Lines.Strings = ( - 'Memo2' - ) - TabOrder = 2 - end - object PythonEngine1: TPythonEngine - AutoLoad = False - DllName = 'libpython3.8.so' - APIVersion = 1013 - RegVersion = '3.7' - UseLastKnownVersion = False - InitScript.Strings = ( - 'import sys' - 'print (''Python Dll: '', sys.version)' - 'print (sys.copyright)' - 'print' - ) - IO = PythonGUIInputOutput1 - PyFlags = [pfUseClassExceptionsFlag] - left = 8 - end - object PythonType1: TPythonType - Engine = PythonEngine1 - OnInitialization = PythonType1Initialization - TypeName = 'Point' - Prefix = 'Create' - Services.Basic = [bsGetAttr, bsSetAttr, bsRepr, bsStr] - Services.InplaceNumber = [] - Services.Number = [] - Services.Sequence = [] - Services.Mapping = [] - left = 72 - end - object PythonModule1: TPythonModule - Engine = PythonEngine1 - OnInitialization = PythonModule1Initialization - ModuleName = 'spam' - Errors = <> - left = 104 - end - object OpenDialog1: TOpenDialog - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 176 - end - object SaveDialog1: TSaveDialog - DefaultExt = '.*.py' - Filter = 'Python files|*.py|Text files|*.txt|All files|*.*' - left = 208 - end - object PythonDelphiVar1: TPythonDelphiVar - Engine = PythonEngine1 - Module = '__main__' - VarName = 'test' - OnGetData = PythonDelphiVar1GetData - OnSetData = PythonDelphiVar1SetData - OnChange = PythonDelphiVar1Change - left = 136 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = True - RawOutput = False - Output = Memo2 - left = 40 - end -end diff --git a/demos_lazarus/Demo06/unit1.lrs b/demos_lazarus/Demo06/unit1.lrs deleted file mode 100644 index d8e0dc9..0000000 --- a/demos_lazarus/Demo06/unit1.lrs +++ /dev/null @@ -1,51 +0,0 @@ -{ This is an automatically generated lazarus resource file } - -LazarusResources.Add('TForm1','FORMDATA',[ - 'TPF0'#6'TForm1'#5'Form1'#4'Left'#2#31#6'Height'#3'Q'#1#3'Top'#3#143#0#5'Widt' - +'h'#3#16#2#7'Caption'#6#14'Demo of Python'#12'ClientHeight'#3'Q'#1#11'Client' - +'Width'#3#16#2#5'Color'#7#9'clBtnFace'#10'Font.Color'#7#12'clWindowText'#11 - +'Font.Height'#2#245#9'Font.Name'#6#13'MS Sans Serif'#10'LCLVersion'#6#7'2.0.' - +'0.4'#0#9'TSplitter'#9'Splitter1'#6'Cursor'#7#8'crVSplit'#4'Left'#2#0#6'Heig' - +'ht'#2#3#3'Top'#3#145#0#5'Width'#3#16#2#5'Align'#7#5'alTop'#12'ResizeAnchor' - +#7#5'akTop'#0#0#5'TMemo'#5'Memo1'#4'Left'#2#0#6'Height'#2'y'#3'Top'#3#148#0#5 - +'Width'#3#16#2#5'Align'#7#8'alClient'#13'Lines.Strings'#1#6#10'import sys'#6 - +#11'import spam'#6#30'print spam.foo(hello world, 1)'#6#30'p = spam.CreatePo' - +'int( 10, 25 )'#6#17'print "Point:", p'#6#8'p.x = 58'#6#12'print p.x, p'#6#18 - +'p.OffsetBy( 5, 5 )'#6#7'print p'#6',print "Current value of var test is: ",' - +' test'#6'&test.Value = "New value set by Python"'#6'%print "getdouble: ", s' - +'pam.getdouble()'#0#10'ScrollBars'#7#10'ssVertical'#8'TabOrder'#2#1#0#0#6'TP' - +'anel'#6'Panel1'#4'Left'#2#0#6'Height'#2'D'#3'Top'#3#13#1#5'Width'#3#16#2#5 - +'Align'#7#8'alBottom'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'D'#11'Cl' - +'ientWidth'#3#16#2#8'TabOrder'#2#0#0#7'TButton'#7'Button1'#4'Left'#2#6#6'Hei' - +'ght'#2#25#3'Top'#2#8#5'Width'#2's'#7'Caption'#6#14'Execute script'#7'OnClic' - +'k'#7#12'Button1Click'#8'TabOrder'#2#0#0#0#7'TButton'#7'Button2'#4'Left'#3 - +#168#0#6'Height'#2#25#3'Top'#2#8#5'Width'#2'['#7'Caption'#6#14'Load script..' - +'.'#7'OnClick'#7#12'Button2Click'#8'TabOrder'#2#1#0#0#7'TButton'#7'Button3'#4 - +'Left'#3#8#1#6'Height'#2#25#3'Top'#2#8#5'Width'#2'Y'#7'Caption'#6#14'Save sc' - +'ript...'#7'OnClick'#7#12'Button3Click'#8'TabOrder'#2#2#0#0#7'TButton'#7'But' - +'ton4'#4'Left'#3'p'#1#6'Height'#2#25#3'Top'#2#8#5'Width'#2'Y'#7'Caption'#6#13 - +'Show var test'#7'OnClick'#7#12'Button4Click'#8'TabOrder'#2#3#0#0#5'TEdit'#5 - +'Edit1'#4'Left'#3'p'#1#6'Height'#2#22#3'Top'#2' '#5'Width'#3#161#0#8'TabOrde' - +'r'#2#4#4'Text'#6#5'Edit1'#0#0#0#5'TMemo'#5'Memo2'#4'Left'#2#0#6'Height'#3 - +#145#0#3'Top'#2#0#5'Width'#3#16#2#5'Align'#7#5'alTop'#13'Lines.Strings'#1#6#5 - +'Memo2'#0#8'TabOrder'#2#2#0#0#13'TPythonEngine'#13'PythonEngine1'#18'InitScr' - +'ipt.Strings'#1#6#10'import sys'#6'!print "Python Dll: ", sys.version'#6#19 - +'print sys.copyright'#6#5'print'#0#2'IO'#7#21'PythonGUIInputOutput1'#4'left' - +#2#8#0#0#11'TPythonType'#11'PythonType1'#6'Engine'#7#13'PythonEngine1'#16'On' - +'Initialization'#7#25'PythonType1Initialization'#8'TypeName'#6#5'Point'#6'Pr' - +'efix'#6#6'Create'#14'Services.Basic'#11#9'bsGetAttr'#9'bsSetAttr'#6'bsRepr' - +#5'bsStr'#0#22'Services.InplaceNumber'#11#0#15'Services.Number'#11#0#17'Serv' - +'ices.Sequence'#11#0#16'Services.Mapping'#11#0#4'left'#2'H'#0#0#13'TPythonMo' - +'dule'#13'PythonModule1'#6'Engine'#7#13'PythonEngine1'#16'OnInitialization'#7 - +#27'PythonModule1Initialization'#10'ModuleName'#6#4'spam'#6'Errors'#14#0#4'l' - +'eft'#2'h'#0#0#11'TOpenDialog'#11'OpenDialog1'#10'DefaultExt'#6#5'.*.py'#6'F' - +'ilter'#6'0Python files|*.py|Text files|*.txt|All files|*.*'#4'left'#3#176#0 - +#0#0#11'TSaveDialog'#11'SaveDialog1'#10'DefaultExt'#6#5'.*.py'#6'Filter'#6'0' - +'Python files|*.py|Text files|*.txt|All files|*.*'#4'left'#3#208#0#0#0#16'TP' - +'ythonDelphiVar'#16'PythonDelphiVar1'#6'Engine'#7#13'PythonEngine1'#6'Module' - +#6#8'__main__'#7'VarName'#6#4'test'#9'OnGetData'#7#23'PythonDelphiVar1GetDat' - +'a'#9'OnSetData'#7#23'PythonDelphiVar1SetData'#8'OnChange'#7#22'PythonDelphi' - +'Var1Change'#4'left'#3#136#0#0#0#21'TPythonGUIInputOutput'#21'PythonGUIInput' - +'Output1'#9'UnicodeIO'#9#9'RawOutput'#8#6'Output'#7#5'Memo2'#4'left'#2'('#0#0 - +#0 -]); diff --git a/demos_lazarus/Demo06/unit1.pas b/demos_lazarus/Demo06/unit1.pas deleted file mode 100644 index 19eca74..0000000 --- a/demos_lazarus/Demo06/unit1.pas +++ /dev/null @@ -1,328 +0,0 @@ -unit Unit1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, PairSplitter, PythonGUIInputOutput, PythonEngine, - Messages, ComCtrls; - -type - - { TForm1 } - - TForm1 = class(TForm) - - Memo1: TMemo; - Memo2: TMemo; - Panel1: TPanel; - Edit1: TEdit; - Button1: TButton; - Button2: TButton; - Button3: TButton; - Button4: TButton; - Splitter1: TSplitter; - OpenDialog1: TOpenDialog; - SaveDialog1: TSaveDialog; - PythonEngine1: TPythonEngine; - PythonType1: TPythonType; - PythonModule1: TPythonModule; - PythonDelphiVar1: TPythonDelphiVar; - PythonGUIInputOutput1: TPythonGUIInputOutput; - procedure Button1Click(Sender: TObject); - procedure PythonModule1Initialization(Sender: TObject); - procedure PythonType1Initialization(Sender: TObject); - procedure Button2Click(Sender: TObject); - procedure Button3Click(Sender: TObject); - procedure Button4Click(Sender: TObject); - procedure PythonDelphiVar1Change(Sender: TObject); - procedure PythonDelphiVar1GetData(Sender: TObject; var Data: Variant); - procedure PythonDelphiVar1SetData(Sender: TObject; Data: Variant); - procedure FormCreate(Sender: TObject); - private - procedure DoPy_InitEngine; - public - end; - - PyPointRec = record - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - po_x : Integer; - po_y : Integer; - end; - PPyPoint = ^PyPointRec; - - function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; - function spam_CreatePoint( self, args : PPyObject ) : PPyObject; cdecl; - function spam_getdouble( self, args : PPyObject ) : PPyObject; cdecl; - - procedure PyPoint_dealloc(obj : PPyObject); cdecl; - function PyPoint_getattr(obj : PPyObject; key : PAnsiChar) : PPyObject; cdecl; - function PyPoint_setattrfunc(obj : PPyObject; key : PAnsiChar; value : PPyObject) : Integer; cdecl; - function PyPoint_repr(obj : PPyObject) : PPyObject; cdecl; - -var - Form1: TForm1; - -implementation - -uses - LclType, proc_py; - -{$R *.lfm} - -const - cPyLibraryWindows = 'python37.dll'; - cPyLibraryLinux = 'libpython3.7m.so.1.0'; - cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; - cPyZipWindows = 'python37.zip'; - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo1.Lines ); -end; - -// Here's an example of functions defined for the module spam - -function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; -begin - with GetPythonEngine do - begin - ShowMessage( 'args of foo: '+PyObjectAsString(args) ); - Result := ReturnNone; - end; -end; - -// This function is used to create a PyPoint instance -function spam_CreatePoint( self, args : PPyObject ) : PPyObject; cdecl; -var - x, y : Integer; - p : PPyPoint; -begin - with GetPythonEngine do - begin - // We want x and y values as argument - if PyArg_ParseTuple( args, 'ii:CreatePoint',@x, @y) <> 0 then - begin - new(p); - with p^ do - begin - ob_refcnt := 1; - ob_type := TypeByName('Point'); - // or we could write, because it's quicker: - // ob_type := Form1.PythonType1.TheTypePtr; - po_x := x; - po_y := y; - end; - Result := PPyObject(p); - end - else - Result := nil; - end; -end; - -function spam_getdouble( self, args : PPyObject ) : PPyObject; cdecl; -// you need to pass floating point numbers as doubles to Py_BuildValue -Const - x : double = 2.7172; - y : double = 3.14159; - z : double = 1.2e-12; -begin - with GetPythonEngine do - begin - Result := Py_BuildValue('(iiddid)',42,815,x,y,4711,z); - end; -end; - -procedure TForm1.PythonModule1Initialization(Sender: TObject); -begin - // In a module initialization, we just need to add our - // new methods - with Sender as TPythonModule do - begin - AddMethod( 'foo', @spam_foo, 'foo' ); - AddMethod( 'CreatePoint', @spam_CreatePoint, - 'function CreatePoint'+LF+ - 'Args: x, y'+LF+ - 'Result: a new Point object' ); - AddMethod( 'getdouble', @spam_getdouble, 'getdouble' ); - end; -end; - -// Here's an example of a new type object. -// That's more complex than a new module, but here's a -// template that you can follow. - -// Here's the destructor of the object -procedure PyPoint_dealloc(obj : PPyObject); cdecl; -begin - Dispose(obj); -end; - -// Here's the read access to the attributes of an object. -// In fact it is called each time you write: -// object.value -// object.method(args) -function PyPoint_getattr(obj : PPyObject; key : PAnsiChar) : PPyObject; cdecl; -begin - with GetPythonEngine, PPyPoint(obj)^ do - begin - // Check for attribute x - if key = 'x' then - Result := PyInt_FromLong( po_x ) - // Check for attribute y - else if key = 'y' then - Result := PyInt_FromLong( po_y ) - else - begin - // Else check for a method - Result := PyObject_GenericGetAttr(obj, PyString_FromString(key)); - if not Assigned(Result) then - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown attribute "%s"',[key]))); - end; - end; -end; - -// Here's the write access to the attributes of an object. -// In fact it is called each time you write: -// object.value = 1 -function PyPoint_setattrfunc(obj : PPyObject; key : PAnsiChar; value : PPyObject) : Integer; cdecl; -begin - Result := -1; - with GetPythonEngine, PPyPoint(obj)^ do - begin - // Check for attribute x - if key = 'x' then begin - if PyInt_Check(value) then - begin - po_x := PyInt_AsLong(value); - Result := 0; - end - else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Attribute "%s" needs an integer',[key]))); - // Check for attribute y - end else if key = 'y' then begin - if PyInt_Check(value) then - begin - po_y := PyInt_AsLong(value); - Result := 0; - end - else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Attribute "%s" needs an integer',[key]))); - end else - PyErr_SetString (PyExc_AttributeError^, PAnsiChar(Format('Unknown attribute "%s"',[key]))); - end; -end; - -// Here's how an object should be represented, when printed for instance. -function PyPoint_repr(obj : PPyObject) : PPyObject; cdecl; -begin - with GetPythonEngine, PPyPoint(obj)^ do - begin - Result := PyString_FromString( PAnsiChar(Format('(%d, %d)',[po_x, po_y]) ) ); - end; -end; - -// Here's a method of the object PyPoint -function PyPoint_OffsetBy(self, args : PPyObject) : PPyObject; cdecl; -var - x, y : Integer; -begin - with GetPythonEngine, PPyPoint(self)^ do - begin - if PyArg_ParseTuple( args, 'ii:OffsetBy',@x, @y) <> 0 then - begin - Inc( po_x, x ); - Inc( po_y, y ); - Result := ReturnNone; - end - else - Result := nil; - end; -end; - -procedure TForm1.PythonType1Initialization(Sender: TObject); -Var - PyType : PyTypeObject; -begin - with (Sender as TPythonType) do - begin - // In the initialization of a new type, we must - // define the attributes of this type - PyType := TheType; - with PyType do - begin - tp_basicsize := sizeof(PyPointRec); - tp_dealloc := @PyPoint_dealloc; - tp_getattr := @PyPoint_getattr; - tp_setattr := @PyPoint_setattrfunc; - tp_repr := @PyPoint_repr; - tp_str := @PyPoint_repr; - end; - TheType := PyType; - // And then add the methods of the object, if needed - AddMethod( 'OffsetBy', @PyPoint_OffsetBy, 'OffsetBy(dx, dy)' ); - end; -end; - -procedure TForm1.Button2Click(Sender: TObject); -begin - with OpenDialog1 do - begin - if Execute then - Memo1.Lines.LoadFromFile( FileName ); - end; -end; - -procedure TForm1.Button3Click(Sender: TObject); -begin - with SaveDialog1 do - begin - if Execute then - Memo1.Lines.SaveToFile( FileName ); - end; -end; - -procedure TForm1.Button4Click(Sender: TObject); -begin - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1Change(Sender: TObject); -begin - with Sender as TPythonDelphiVar do - ShowMessage( 'Var test changed: ' + ValueAsString ); -end; - -procedure TForm1.PythonDelphiVar1GetData(Sender: TObject; - var Data: Variant); -begin - Data := Edit1.Text; -end; - -procedure TForm1.PythonDelphiVar1SetData(Sender: TObject; Data: Variant); -begin - Edit1.Text := Data; -end; - -procedure TForm1.FormCreate(Sender: TObject); -begin - DoPy_InitEngine; -end; - -procedure TForm1.DoPy_InitEngine; -var - S: string; -begin - S:= - {$ifdef windows} cPyLibraryWindows {$endif} - {$ifdef linux} cPyLibraryLinux {$endif} - {$ifdef darwin} cPyLibraryMac {$endif} ; - PythonEngine1.DllPath:= ExtractFileDir(S); - PythonEngine1.DllName:= ExtractFileName(S); - PythonEngine1.LoadDll; -end; - -end. diff --git a/demos_lazarus/Demo25/fpc-res.res b/demos_lazarus/Demo25/fpc-res.res deleted file mode 100644 index cd6c436..0000000 Binary files a/demos_lazarus/Demo25/fpc-res.res and /dev/null differ diff --git a/demos_lazarus/Demo25/link.res b/demos_lazarus/Demo25/link.res deleted file mode 100644 index 9c94a2f..0000000 --- a/demos_lazarus/Demo25/link.res +++ /dev/null @@ -1,420 +0,0 @@ -SEARCH_DIR(C:\P4D\temp\) -SEARCH_DIR(C:\lazarus\lcl\units\i386-win32\) -SEARCH_DIR(C:\lazarus\lcl\units\i386-win32\win32\) -SEARCH_DIR(C:\lazarus\packager\units\i386-win32\) -SEARCH_DIR(.\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\zlib\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-jedi\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\winceunits\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\unzip\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\tcl\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\symbolic\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\sqlite\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\sdl\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\regexpr\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\pxlib\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\postgres\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\pcap\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\oracle\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\openssl\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\opengl\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\openal\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\oggvorbis\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\odbc\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\numlib\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\mysql\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\mad\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\libpng\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\libgd\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\lexyacc\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\imagemagick\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\ibase\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\httpd22\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\httpd20\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\httpd13\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\hash\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\gtk2\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\gtk1\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\graph\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\gdbint\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fv\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fppkg\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fpmkunit\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fpgtk\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fftw\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-xml\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-web\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-registry\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-process\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-passrc\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-net\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-json\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-fpcunit\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-db\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\chm\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\cdrom\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\cairo\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\bfd\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\a52\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\units\i386-win32\) -SEARCH_DIR(C:\lazarus\fpc\2.2.4\bin\i386-win32\) -INPUT( -C:\Delphi\Components\P4D\Demos\FPC\Demo25\project1.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\system.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\lineinfo.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\exeinfo.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\strings.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\windows.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\objpas.o -C:\lazarus\lcl\units\i386-win32\win32\interfaces.o -C:\lazarus\lcl\units\i386-win32\forms.o -C:\Delphi\Components\P4D\Demos\FPC\Demo25\unit1.o -C:\lazarus\lcl\units\i386-win32\lresources.o -C:\P4D\temp\p4dlaz.o -C:\lazarus\lcl\units\i386-win32\interfacebase.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\types.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\classes.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\sysutils.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\math.o -C:\lazarus\lcl\units\i386-win32\lclstrconsts.o -C:\lazarus\lcl\units\i386-win32\lcltype.o -C:\lazarus\lcl\units\i386-win32\lclproc.o -C:\lazarus\lcl\units\i386-win32\lmessages.o -C:\lazarus\lcl\units\i386-win32\graphtype.o -C:\lazarus\lcl\units\i386-win32\graphmath.o -C:\lazarus\lcl\units\i386-win32\themes.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\rtlconsts.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\typinfo.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\sysconst.o -C:\lazarus\lcl\units\i386-win32\fpcadds.o -C:\lazarus\lcl\units\i386-win32\avglvltree.o -C:\lazarus\lcl\units\i386-win32\fileutil.o -C:\lazarus\lcl\units\i386-win32\wsreferences.o -C:\lazarus\lcl\units\i386-win32\masks.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\contnrs.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\gettext.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\messages.o -C:\lazarus\lcl\units\i386-win32\tmschema.o -C:\lazarus\lcl\units\i386-win32\lclintf.o -C:\lazarus\lcl\units\i386-win32\graphics.o -C:\lazarus\lcl\units\i386-win32\imglist.o -C:\lazarus\lcl\units\i386-win32\dynqueue.o -C:\lazarus\lcl\units\i386-win32\lazconfigstorage.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpimage.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpcanvas.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpwritebmp.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpwritepng.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\pngcomn.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpreadpnm.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpwritepnm.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpreadjpeg.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpwritejpeg.o -C:\lazarus\lcl\units\i386-win32\intfgraphics.o -C:\lazarus\lcl\units\i386-win32\lclrescache.o -C:\lazarus\lcl\units\i386-win32\icnstypes.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\clipping.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\bmpcomn.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpimgcmn.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\zstream.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\zbase.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\gzio.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\dos.o -C:\lazarus\fpc\2.2.4\units\i386-win32\hash\crc.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\zdeflate.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\zinflate.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\trees.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\adler.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\infblock.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\infutil.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\infcodes.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\inftrees.o -C:\lazarus\fpc\2.2.4\units\i386-win32\paszlib\inffast.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jpeglib.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdapimin.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdatasrc.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdapistd.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jmorecfg.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdeferr.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jinclude.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jerror.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jmemmgr.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdmarker.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdinput.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcomapi.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jutils.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jmemnobs.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdmaster.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdcolor.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdsample.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdpostct.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jddctmgr.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdphuff.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdhuff.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdcoefct.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdmainct.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jquant1.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jquant2.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdmerge.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdct.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jidctfst.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jidctint.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jidctflt.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jidctred.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcapistd.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcapimin.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jdatadst.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcparam.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcinit.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcmarker.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcphuff.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jchuff.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcmaster.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jccolor.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcsample.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcprepct.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcdctmgr.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jccoefct.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jcmainct.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jfdctint.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jfdctfst.o -C:\lazarus\fpc\2.2.4\units\i386-win32\pasjpeg\jfdctflt.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpreadbmp.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-image\fpreadpng.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\syncobjs.o -C:\lazarus\lcl\units\i386-win32\lclclasses.o -C:\lazarus\lcl\units\i386-win32\wslclclasses.o -C:\lazarus\lcl\units\i386-win32\wsimglist.o -C:\lazarus\lcl\units\i386-win32\wsproc.o -C:\lazarus\lcl\units\i386-win32\wsfactory.o -C:\lazarus\lcl\units\i386-win32\controls.o -C:\lazarus\lcl\units\i386-win32\menus.o -C:\lazarus\lcl\units\i386-win32\utrace.o -C:\lazarus\lcl\units\i386-win32\propertystorage.o -C:\lazarus\lcl\units\i386-win32\actnlist.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\rttiutils.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\strutils.o -C:\lazarus\lcl\units\i386-win32\wsmenus.o -C:\lazarus\lcl\units\i386-win32\maps.o -C:\lazarus\lcl\units\i386-win32\lclversion.o -C:\lazarus\lcl\units\i386-win32\customtimer.o -C:\lazarus\lcl\units\i386-win32\clipbrd.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\custapp.o -C:\lazarus\lcl\units\i386-win32\helpintfs.o -C:\lazarus\lcl\units\i386-win32\wscontrols.o -C:\lazarus\lcl\units\i386-win32\wsforms.o -C:\lazarus\lcl\units\i386-win32\win32\win32int.o -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\activex.o -C:\lazarus\lcl\units\i386-win32\translations.o -C:\lazarus\lcl\units\i386-win32\comctrls.o -C:\lazarus\lcl\units\i386-win32\buttons.o -C:\lazarus\lcl\units\i386-win32\extctrls.o -C:\lazarus\lcl\units\i386-win32\stdctrls.o -C:\lazarus\lcl\units\i386-win32\win32\win32def.o -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\commctrl.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\variants.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\ctypes.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\varutils.o -C:\lazarus\lcl\units\i386-win32\stringhashlist.o -C:\lazarus\lcl\units\i386-win32\lconvencoding.o -C:\lazarus\lcl\units\i386-win32\toolwin.o -C:\lazarus\lcl\units\i386-win32\extendedstrings.o -C:\lazarus\lcl\units\i386-win32\textstrings.o -C:\lazarus\lcl\units\i386-win32\wsstdctrls.o -C:\lazarus\lcl\units\i386-win32\popupnotifier.o -C:\lazarus\lcl\units\i386-win32\wsextctrls.o -C:\lazarus\lcl\units\i386-win32\imagelistcache.o -C:\lazarus\lcl\units\i386-win32\wsbuttons.o -C:\lazarus\lcl\units\i386-win32\wscomctrls.o -C:\lazarus\lcl\units\i386-win32\wstoolwin.o -C:\lazarus\lcl\units\i386-win32\win32\win32proc.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsfactory.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsbuttons.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsextctrls.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsmenus.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsspin.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsstdctrls.o -C:\lazarus\lcl\units\i386-win32\win32\win32themes.o -C:\lazarus\lcl\units\i386-win32\arrow.o -C:\lazarus\lcl\units\i386-win32\calendar.o -C:\lazarus\lcl\units\i386-win32\spin.o -C:\lazarus\lcl\units\i386-win32\checklst.o -C:\lazarus\lcl\units\i386-win32\win32\win32extra.o -C:\lazarus\lcl\units\i386-win32\lclmessageglue.o -C:\lazarus\lcl\units\i386-win32\dialogs.o -C:\lazarus\lcl\units\i386-win32\buttonpanel.o -C:\lazarus\lcl\units\i386-win32\wsdialogs.o -C:\lazarus\lcl\units\i386-win32\extdlgs.o -C:\lazarus\lcl\units\i386-win32\grids.o -C:\lazarus\lcl\units\i386-win32\wscalendar.o -C:\lazarus\lcl\units\i386-win32\wsarrow.o -C:\lazarus\lcl\units\i386-win32\wsspin.o -C:\lazarus\lcl\units\i386-win32\wsextdlgs.o -C:\lazarus\lcl\units\i386-win32\wschecklst.o -C:\lazarus\lcl\units\i386-win32\dynamicarray.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-xml\xmlcfg.o -C:\lazarus\lcl\units\i386-win32\maskedit.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-xml\dom.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-xml\xmlread.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-xml\xmlwrite.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\avl_tree.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-xml\xmlutils.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\uriparser.o -C:\lazarus\lcl\units\i386-win32\wsgrids.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsarrow.o -C:\lazarus\lcl\units\i386-win32\win32\win32wscalendar.o -C:\lazarus\lcl\units\i386-win32\win32\win32wschecklst.o -C:\lazarus\lcl\units\i386-win32\win32\win32wscomctrls.o -C:\lazarus\lcl\units\i386-win32\win32\win32wscontrols.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsdialogs.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsextdlgs.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsforms.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsgrids.o -C:\lazarus\lcl\units\i386-win32\win32\win32wsimglist.o -C:\lazarus\lcl\units\i386-win32\win32\win32uxtheme.o -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\shlobj.o -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\shellapi.o -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\commdlg.o -C:\lazarus\lcl\units\i386-win32\pairsplitter.o -C:\P4D\temp\PythonEngine.o -C:\P4D\temp\PythonGUIInputOutput.o -C:\lazarus\lcl\units\i386-win32\wspairsplitter.o -C:\P4D\temp\TinyWideStrings.o -C:\P4D\temp\MethodCallBack.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-registry\registry.o -C:\lazarus\fpc\2.2.4\units\i386-win32\fcl-base\inifiles.o -C:\P4D\temp\VarPyth.o -C:\lazarus\packager\units\i386-win32\lazaruspackageintf.o -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\sysinitpas.o -) -GROUP( -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\libimpsystem.a -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\libimpwindows.a -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\libimpsysutils.a -C:\lazarus\lcl\units\i386-win32\libimplclintf.a -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\libimpdos.a -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\libimpactivex.a -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\libimpcommctrl.a -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\libimpvarutils.a -C:\lazarus\lcl\units\i386-win32\win32\libimpwin32wsforms.a -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\libimpshlobj.a -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\libimpshellapi.a -C:\lazarus\fpc\2.2.4\units\i386-win32\winunits-base\libimpcommdlg.a -C:\lazarus\fpc\2.2.4\units\i386-win32\rtl\libimpsysinitpas.a -) -SEARCH_DIR("/usr/i686-pc-cygwin/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api"); -OUTPUT_FORMAT(pei-i386) -ENTRY(_mainCRTStartup) -SECTIONS -{ - . = SIZEOF_HEADERS; - . = ALIGN(__section_alignment__); - .text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) : - { - *(.init) - *(.text .stub .text.* .gnu.linkonce.t.*) - *(SORT(.text$*)) - ___CTOR_LIST__ = .; __CTOR_LIST__ = . ; - LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*)); LONG (0); - ___DTOR_LIST__ = .; __DTOR_LIST__ = . ; - LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*)); LONG (0); - *(.fini) - PROVIDE (etext = .); - *(.gcc_except_table) - } - .data BLOCK(__section_alignment__) : - { - __data_start__ = . ; - *(.data .data.* .gnu.linkonce.d.* .fpc*) - *(.data2) - *(SORT(.data$*)) - __data_end__ = . ; - *(.data_cygwin_nocopy) - } - .rdata BLOCK(__section_alignment__) : - { - *(.rdata) - *(.rodata .rodata.* .gnu.linkonce.r.*) - *(SORT(.rdata$*)) - *(.eh_frame) - ___RUNTIME_PSEUDO_RELOC_LIST__ = .; - __RUNTIME_PSEUDO_RELOC_LIST__ = .; - *(.rdata_runtime_pseudo_reloc) - ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; - __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; - } - .pdata BLOCK(__section_alignment__) : { *(.pdata) } - .bss BLOCK(__section_alignment__) : - { - __bss_start__ = . ; - *(.bss .bss.* .gnu.linkonce.b.*) - *(SORT(.bss$*)) - *(COMMON) - __bss_end__ = . ; - } - .edata BLOCK(__section_alignment__) : { *(.edata) } - .idata BLOCK(__section_alignment__) : - { - SORT(*)(.idata$2) - SORT(*)(.idata$3) - /* These zeroes mark the end of the import list. */ - LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); - SORT(*)(.idata$4) - SORT(*)(.idata$5) - SORT(*)(.idata$6) - SORT(*)(.idata$7) - } - .CRT BLOCK(__section_alignment__) : - { - ___crt_xc_start__ = . ; - *(SORT(.CRT$XC*)) /* C initialization */ - ___crt_xc_end__ = . ; - ___crt_xi_start__ = . ; - *(SORT(.CRT$XI*)) /* C++ initialization */ - ___crt_xi_end__ = . ; - ___crt_xl_start__ = . ; - *(SORT(.CRT$XL*)) /* TLS callbacks */ - /* ___crt_xl_end__ is defined in the TLS Directory support code */ - ___crt_xp_start__ = . ; - *(SORT(.CRT$XP*)) /* Pre-termination */ - ___crt_xp_end__ = . ; - ___crt_xt_start__ = . ; - *(SORT(.CRT$XT*)) /* Termination */ - ___crt_xt_end__ = . ; - } - .tls BLOCK(__section_alignment__) : - { - ___tls_start__ = . ; - *(.tls .tls.*) - *(.tls$) - *(SORT(.tls$*)) - ___tls_end__ = . ; - } - .rsrc BLOCK(__section_alignment__) : - { - *(.rsrc) - *(SORT(.rsrc$*)) - } - .reloc BLOCK(__section_alignment__) : { *(.reloc) } - .stab BLOCK(__section_alignment__) (NOLOAD) : { *(.stab) } - .stabstr BLOCK(__section_alignment__) (NOLOAD) : { *(.stabstr) } - .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) } - .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) } - .debug_info BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) *(.gnu.linkonce.wi.*) } - .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) } - .debug_line BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) } - .debug_frame BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) } - .debug_str BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) } - .debug_loc BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) } - .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) } - .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_weaknames) } - .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_funcnames) } - .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_typenames) } - .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_varnames) } - .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) } -} diff --git a/demos_lazarus/Demo25/ppas.bat b/demos_lazarus/Demo25/ppas.bat deleted file mode 100644 index 0261eff..0000000 --- a/demos_lazarus/Demo25/ppas.bat +++ /dev/null @@ -1,16 +0,0 @@ -@echo off -c:\lazarus\fpc\2.2.4\bin\i386-win32\windres.exe --include c:/lazarus/fpc/222A9D~1.4/bin/I386-W~1/ -O res -o C:\Delphi\Components\P4D\Demos\FPC\Demo25\project1.res C:/Delphi/COMPON~1/P4D/Demos/FPC/Demo25/project1.rc --preprocessor=c:\lazarus\fpc\2.2.4\bin\i386-win32\cpp.exe -if errorlevel 1 goto linkend -SET THEFILE=C:\Delphi\Components\P4D\Demos\FPC\Demo25\project1.exe -echo Linking %THEFILE% -c:\lazarus\fpc\2.2.4\bin\i386-win32\ld.exe -b pe-i386 -m i386pe --gc-sections --subsystem windows --entry=_WinMainCRTStartup -o C:\Delphi\Components\P4D\Demos\FPC\Demo25\project1.exe C:\Delphi\Components\P4D\Demos\FPC\Demo25\link.res -if errorlevel 1 goto linkend -c:\lazarus\fpc\2.2.4\bin\i386-win32\postw32.exe --subsystem gui --input C:\Delphi\Components\P4D\Demos\FPC\Demo25\project1.exe --stack 16777216 -if errorlevel 1 goto linkend -goto end -:asmend -echo An error occured while assembling %THEFILE% -goto end -:linkend -echo An error occured while linking %THEFILE% -:end diff --git a/demos_lazarus/Demo25/project1.lpi b/demos_lazarus/Demo25/project1.lpi deleted file mode 100644 index 5c2c9df..0000000 --- a/demos_lazarus/Demo25/project1.lpi +++ /dev/null @@ -1,286 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo25/project1.lpr b/demos_lazarus/Demo25/project1.lpr deleted file mode 100644 index 3f84c6e..0000000 --- a/demos_lazarus/Demo25/project1.lpr +++ /dev/null @@ -1,21 +0,0 @@ -program project1; - -{$mode objfpc}{$H+} - -uses - {$IFDEF UNIX}{$IFDEF UseCThreads} - cthreads, - {$ENDIF}{$ENDIF} - Interfaces, // this includes the LCL widgetset - Forms, Unit1, LResources, P4DLaz - { you can add units after this }; - -{$IFDEF WINDOWS}{$R project1.rc}{$ENDIF} - -begin - {$I project1.lrs} - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.Run; -end. - diff --git a/demos_lazarus/Demo25/project1.lrs b/demos_lazarus/Demo25/project1.lrs deleted file mode 100644 index 2747aa9..0000000 --- a/demos_lazarus/Demo25/project1.lrs +++ /dev/null @@ -1,5237 +0,0 @@ -LazarusResources.Add('MAINICON','ICO',[ - #0#0#1#0#6#0#0#0#0#0#1#0' '#0#226#145#0#0'f'#0#0#0#128#128#0#0#1#0' '#0'('#8#1 - +#0'H'#146#0#0'@@'#0#0#1#0' '#0'(B'#0#0'p'#154#1#0'00'#0#0#1#0' '#0#168'%'#0#0 - +#152#220#1#0' '#0#0#1#0' '#0#168#16#0#0'@'#2#2#0#16#16#0#0#1#0' '#0'h'#4#0#0 - +#232#18#2#0#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#1#0#0#0#1#0#8#6#0#0#0'\r' - +#168'f'#0#0#145#169'IDATx'#218#236']'#5#128#28#245#213#127#235'n'#231'w9I.N' - +#136#144#4#139#17#220'['#220#221#138';!'#184'|'#180#148#2#197'Kq'#13'R('#20 - +'(V'#180#197#3#9'!'#144#144#16#187#156#219#202#173#251'~'#239#253'gfo'#246'r' - +'~'#187';{'#242#131#201#236#173#204#204#202#251#253#159'?'#25#140'a'#12'c'#24 - +#181#144'I}'#1'c'#24#195#24#164#195#24#1#140'a'#12#163#24'c'#4'0'#134'1'#140 - +'b'#140#17#192#24#198'0'#138'1F'#0'c'#24#195'('#198#24#1#140'"'#140#155'}2}' - +#223#6#220'L'#184#25'q'#11#227#230#161#173#225#167#21#17#169#175'o'#12#217 - +#199#24#1#12'c'#160'@'#155'q7'#21#183'i'#184'M'#198#173#8'8'#225'N'#217'd2' - +#153'p'#155#132#191#167#239'<'#132#155''''#145'H0B'#224'7'#175#232'v'#7'n' - +#219'p'#219#128#219'F'#220'j'#145'4'#18'R'#127#6'c'#24#26#198#8' '#199#129'B' - +'.'#199#221'x'#224#132'|'#170#176#161'P'#211#223'%='#189'N'#214#195'7+'#235 - +#230'+O@'#207'r'#156#232#249#161#0#146#197'&'#232'$'#132#228#134#196#224#145 - +#250's'#27'C'#255'0F'#0'9'#6#20'x'#18#234#189'q'#219#7#183'=P'#208'ie'#215 - +#136#159'#'#22'nA'#160'e'#194#157#226#199'DO'#20'nwG'#12'b!O'#240#127'$R'#238 - +#236#230'q'#209#157']I'#2#159#211#136#187#181#184'}'#198'o'#171#145#20'bR' - +#127#182'c'#216#17'c'#4' 1P'#224#11'p'#183#20'8'#161#223#27#5'u'#186#240'X' - +#167'L'#239'('#228't'#155#219#0#228#244#12#185#140'{'#158#140'{'#157#140#191 - +'!'#235#250'|'#232'<'#166' '#196#130#252#146'ps'#27'pRM'#255#203#184#191#197 - +#143#209#235#196#247'AbGb'#232'B'#10#29#248#248#255#160#147#16'~'#26'3'#31'r' - +#3'c'#4#144'e'#160#192'[p'#183#23#240#171'<'#10#229'L'#224#191#7#177#192#203 - +'8)'#6#185'\'#158#20'h'#185#156#187'_.'#227#4#158#30#163#219#10'z'#142#188 - +#203#227#252#30'D'#247#201#21#10#220'+AF{P@\'#22#135'D,'#134#194#26#131'8' - +#238#227#241#24'/'#216'qn'#31'O'#0#222#194#251#241#223'8@'#28#255#137#199#185 - +#191#227#137#4#187#157#224#239'#'#2#136''''#186''''#134'nH'#193#129#247#127 - +#14''#193#238#139#11'['#146'(R'#9#161#139#217'A&' - +#195#10#220#158'G2'#248'E'#234#239'k4a'#140#0'2'#4#20'z%'#238#246#7'N'#232 - +#127#143'{'#29#221'/'#172#230#226#21'^,'#240'$'#172'$'#224'J'#165#2#148#180 - +'W)A'#163#214'3'#1#215#144#176'ku'#160#209#242'B'#175'V'#129#10#159#175'T' - +#202#217's'#233'u'#10#185'p'#172'.'#26#129#130'3'#21#184#251#216#149'p'#23 - +#202'Vn'#224'Vo'#129#4#226#156#128#198'x'#1#142#197'8'#161#142'E'#19#16'E!' - +#143'D'#227#16'Eb'#8'!'#9#132#131'~n'#11's'#251#16'#'#135'0>/'#134#207#225'6' - +#129#16#24'A'#136#8#129#206#215'U;'#192#251#215#224#238#5#220'^B2h'#150#250 - +'{'#28#233#24'#'#128'4'#3#5#127'.'#238'N'#197#237'D'#20#190'b'#186'O,'#244 - +#130#170#174#144#209'*.c'#2#175#228#133'^'#173'T'#162'P'#171'Ao'#178#130'^o' - +#3#157#209#10'Z'#29#10#187'J'#129#171'=nL'#208#233#182#156#221'V)'#21#201'=#' - +#11'%G'#0'D$r9g'#247#211#185#146'&'#3#179#8'd)'#206'AnE'#134#20'5'#30'e'#149 - +#187#29#231'6"'#128'h'#156#132'9'#158'$'#128'H'#132#246'1'#238#182'h'#31#198 - +'}8'#24#130#128#175#3#252'^'''#248'}N'#8#5'}'#236'1'#129#16#162#177#174#132 - +#16'g'#218#1#153#24#220'5'#177']'#12#175#225'c'#224#200#224'M$'#3#191#212#223 - +#237'H'#196#24#1#164#1'('#244#21#184';'#25#183'SQ'#184'v'#162#251#186#21'z~' - +#133#231'Vv'#18'^'#20'x'#149#10#244'('#232'z'#163#13#12#6#220#27#204#184#226 - +#227#170#175'Q'#130'V'#173'`'#194'O'#127#171'U'#188#192#171':'#133'^'#197#142 - +#195#173#254't'#31'g&p'#171#127#210#148#160#235#224#29#132#130#250#159#18#9 - +#224#205#0#178#245#133#21#153#217#251#252#223'$'#155'$'#160#209'8'#183#250'w' - +#146#0#10'2'#145#0#222#14'G8'#2#160'=m'#161'H'#20#205#132#24#4#195#220#237'@' - +' '#0'~'#143#139#145#1#145'B'#136#204#8#188#159'#'#131#24'gJ'#224'qbq'#193 - +#223#176#131#153#224'E2'#248'''pd@>'#131#184#212#223#249'H'#193#24#1#12#1'(' - +#248#243'pw='#10#219#17#192'-'#174#12'rN'#210'8'#149'\&O'#170#244'*'#21#9#178 - +#146#9#188#193'd'#195'}'#30'nf'#208'jT'#160#19#132#30'7'#29#19'~%G'#4'<'#9 - +#168#149#220#202'O'#171'<'#169#253#10#165#12#148'ra'#213#167's'#164#10'>]'#2 - +'wA'#188#192#11#209#129'D*'#1'$U'#239#164'g'#159#255#139#183#215#227#188'3P' - +#16#206'(o'#14#16#9#196#4'2Hj'#5#164#1#160#208#147#224#135#163'l'#31#8'E!(' - +#222'P'#240#253'>'#31#4#188'.'#240'!'#25#248'<'#14'4'#27#130#248#218'(#'#5'F' - +#4#140#12'x"'#232#226'3'#192#191')'#25#233'/'#184'='#131'D'#16#146#250'70' - +#220'1F'#0#131#0#10#254'"'#220#221#128#194'v'#16#253#157'\'#237'y'#207''#198#147'BLl'#30#136#136#0#133'>'#16'N%'#1#250 - +';'#16#196'-'#20#129'` '#2#30#183#3'<'#174'f'#240'x'#218'Q;'#8'32 '#13'C'#236 - +'d'#20'L'#4#17#17#144#227#240'^'#220#30'C"'#240'I'#253#155#24#174#24'#'#128#1 - +#0#5#159#156'z7'#162'0-'#161#191#185#24'<-'#181#220'j'#159'j'#203#163'0'#235 - +'t`'#182#20#131#201'V'#2'F'#147#25#244'Z'#21#24'p'#163#189'^G'#130#174'b'#194 - +#175#21'V|'#141#130#9'='#17#6#19#252#164#131#143#183#229#153#195#16'D6=''' - +#224#178#174#241#254'.'#215'-'#147#13#236'k'#22''''#1#137's'#4#128#251#159'#' - +#2#193'THtF'#16#146#132'@'#26'B$'#158'4'#11'B'#145'N'#141' '#200#147'A '#24#1 - +'?'#146#128#31'I'#192#239#167#219#184#5#130#224'v'#181#129#219#217#194'i'#6 - +','#242#16'c'#14#199#164#137#16#139#167'h'#5'x'#187#29'/'#233'~'#220#30'F"' - +#232#144#250'72'#220'0F'#0'}'#128'/'#160#249#29'p+'#254#174't'#31#23'^'#239 - +#12#209'1!Ur'#234#189'V'#171#1#147#165#136#173#244'&K'#30'/'#236'j0'#232'T' - +#201'M'#199#147#128'V'#195#169#248#156#208'+83A'#201#31'O.'#178#231'{'#17'v' - +#254'&'#183#239'A'#208#7'"'#255'='#165#254'v%'#133'D'#167#154#176#3')p^'#255 - +#4#243#27#196'D'#142'C'#210#10#194#188'_'#128#153#7'A'#142#8'|'#129'0n'#17 - +#182#249'i'#143'Z'#128#23#205#4#15#18#1#145#129#223#239#193#215'E'#153'f'#192 - +#162#11#188#19#177#139#175#128#146#141#30#193#253'}H'#4#237'R'#255'n'#134#11 - +#198#8#160#7#240'9'#248#199#1'g'#227'S'#178#206#14#130#175#18#236'z\'#189#13 - +'&+X'#243#199#161#224#23#162#144#235'P'#232'U`'#228#5#158#8#192#168#231#132 - +'^'''#8'>'#9#189'Z'#145't'#230'q'#26#132'8'#254'/J'#254#17'.'#170#15'u>['#232 - +#202#17']'#201#128#249#14#4#13'A'#228'?`'#209#4'2'#17'b'#228','#140'32 '#159 - +#0#167#13#136#8#0'5'#2'/'#146#130#159#255#219#227'qA'#135#179#25':'#28#141'h' - +'R'#132'92Hj'#5';'#16#129#31#207#255#24#238#239'A"h'#148#224#227#25'V'#24'#' - +#128'n'#128#194#191#27#238#30'EA'#163#144'^'#138#224'+yU_'#141'6'#188#6'7' - +#163'9'#15'l'#133#149'`'#177#230#163#176#227'J'#143#130'n'#212#171#217'mN' - +#232#213'('#244'h'#235'k95_'#205'<'#250#188#7'_'#217#25#183#239'N'#173'g'#231 - +#22'.j8|S]'#202#7'RR'#135'E'#230'B,'#193#231#20#240#161'Cf"'#136'|'#3'$'#244 - +'^A+'#240#163'6 '#236'}~p'#180#213'!'#17'4'#224#243#130#140#8':#'#9#169'D' - +#128#231#14#224'%'#220#137#219'_'#198#156#133'=c8'#252#172#178#6#20#252'<' - +#220#221#137#194'w.'#240'2'#152'"'#248#188#154#175'A'#219#221'd)`'#130'oE5' - +#223'hP3'#161'7'#25'4L'#232#13#188#202#159#180#241#153#224#139#156'y'#188'z/' - +#8#190'8'#127'?'#165#208'g'#128#182'{'#174#161''''#167'b2'#225#136'O2'#226 - +#180#2'!'#140'H>'#130'X'#167#143#0#137#192'C'#194#207#8' '#12'n'#220'{'#188 - +'~p'#182#215#131#203'^'#15'A'#127#144#249#10'z!'#2#170'X'#188#24'I'#224'?R' - +#127#30#185#136#225#253#11'K'#19'x;'#255','#220#238'B'#161#203#23#156'{2'#133 - +#160#234's+'#183#22'W|'#147#181#8#242#138'+'#193'l'#182#129#137#9'='''#248'&' - +'#'#238'Q'#240'uL'#229'W'#177#24#190#134'9'#243'RU|qr'#14#8#222'z'#254':d#' - +#248#235#216#161'z0'#25'f'#228'3'#17#197'&'#2'i'#5'Q^+ '#18#8'F'#152#22#224 - +#245#133#192'C$'#224'#R'#8#129#215#27#0#167#189#1#156#168#21'P'#174'A('#140 - +'D@9'#9'T'#215#192';'#11#227#157#213#141#175#225#238#10'$'#130#6#169'?'#139 - +'\'#194#200#253#197#245#19'('#252#187#224#238'o('#152'{'#136#195'y,'#227#142 - +'6'#18'|T'#227'-'#214#18#176#21'U'#160#224'['#153#208#155'I'#232'y'#225'g'#26 - +#128#150#19'|q'#248'N'#156#158'+'#8'>'#147#249#212'z'#222#209#9'Q'#232'1'#233 - +'7'#224#137#128#204#132#8#159'tDQ'#0#166#17#132#200'9'#136#155#143#211#8#220 - +'H'#6'D'#4#28')'#4#145#8#26#145#8'j'#193#239#247'!qt'#18#1#167'm'#196#5'm' - +#128#26#156#220#138#219#3'H'#4'Q'#169'?'#130'\'#192'h'#253#249#9'Uyw'#160'0^' - +#128'{'#133#160#238#179'"'#27#222#185'G'#9':'#228#205'/('#169'F'#193'71a'#239 - +'I'#240#5#199#30'K'#203'U'#202'S'#236'zN'#232#187#177#235#199#176'C'#30'BB' - +#172#25#176#236'CN+'#8'G'#163#157'D'#192#251#4'8m'#128'#'#2#143'@'#4'm'#13 - +#224'h'#169'A'#205'!'#192#136' '#194#155#6']'#204#2'*8'#186#16'I'#224#11#169 - +#223#191#212#24#149#191'E'#20#254'Spw'#15#229#234'''Km'#21'|J-+'#190'A;'#222 - +'hB'#193#159#4#182#252'"&'#244'f#'''#252'f^'#240#13#188'W_'#219'e'#197'O&' - +#231#240'R'#223#25#162#147#250']'#231'>D'#193#4'n/'#242#21'$S'#144'{'#210#8 - +#188'!'#232' '#18#160'}'#135#23#218#155#183#130#203#217#4#193'`'#152#249#21 - +#136#8#226#172#246' %'#153#232'y'#220']'#141'D'#208'&'#245'{'#151#10#163#234 - +'g'#137#130'O'#141'0'#31'G'#193'?'#145#254#22'Vh'#5#191#234#171'U*'#180#225 - +'5'#204#185'WP2'#30','#6#29'XL'#26#176#24'9'#2#160'U'#159#9#190'F'#136#225'+' - +'9'#167#30#139#219#11'y'#255'\'#213']'#231'''<'#170'>'#226#244'A'#228'@L@gM' - +#2#249#9'"'#2#17#136#162#6#130'Y'#208#225#9'22'#160#205#225'h'#135#246#166'M' - +'H'#10#29#156'6'#192#242#8#226#156#127#160'S'#27#160'P'#225#137'H'#2#255#147 - +#250'-K'#129'Q'#243#235'D'#225#159#141#187#127#160#144'N'#17'V}'#5#159'i'#199 - ,#169#251'h'#215'['#11#160#176't2'#218#251'f&'#244'V'#163#22#204'D'#0#6'-S' - +#251'){'#143#4#159#203#244#227#146'u'#196'e'#183'];'#248#140'a'#232#16#151#11 - +#11#230'A,'#193#167#30'G'#184#228'"'#230','#196#205#195#155#5#29#222' '#18'A' - +#136#237#221'H'#8#237#173#181#224'l'#217#14#254'`'#16'B'#225'0'#159'f'#28'Oj' - +#24#192'U'#30#222#130#251';G['#161#209#168#248#165#162#240#159#135#187#7'PH' - +#181'2'#190#6'_H'#217#165#144#158#222'`'#196#21#127'"'#228#229#151#178#149 - +#158'V}+['#249'9'#193'7'#232#213'l'#213#167#172'='#242#234's'#9';\'#201#173 - +'Pp'#195'>'#204'Q'#241'iJ'#131#206'DDn'#229'N'#166#31#147'F'#16#229#170#16')' - +#143#128#210#138#189#188'I'#224#18#17'A'#135#219#11'mM'#155#161#195#209#130 - +'&'#4#146#0'%'#19#9#209#130'Nm'#224'#<'#193')H'#2#173'R'#191#223'laD'#255'd' - +#249'N<'#143#137'U~'#193#214#167'D'#30#29#174#250'yE'#168#238#23'O'#0#179'Y' - +#199#4'>'#185#242#27'9[_H'#217'e'#169#186#138#212#226#155#222#26'm'#142'!3' - +#224#139#21#147#14#195'd>A'#148'K7'#230'2'#11'9"'#224#28#132'H'#4'n$'#0#242 - +#13#144'Y`o'#133#246#230'M'#224#243'x:'#181#129'h\'#28')h'#194'3'#156#140'$' - +#240#153#212#239'5'#27#24#177'?]^'#229#127#141#186#234#138'='#252#172#180'VE' - +'N>#'#148#148#239#4'V[>'#191#226'k'#25#1#144#202'O'#241'}'#178#245'uj~'#213 - +#23'j'#237'E^}'#246#225#141#216'O/'#247#145'$'#2#232#236'AH)'#199'Q'#190#0 - +#137#10#142#168#208#200#231#227#136#128#132#223#229#9'2'#31'A'#135''''#0#173 - +#13#191#177#208'a'#144'O-'#142'&C'#134#236#200#184'K'#220#142#251#255#27#233 - +'&'#193#136#252#9#163#240#255#1'w'#247#139'U~'#174#147#14#197#244'U`'#177#21 - +'Cq'#249'4'#176#153#13'('#252'Z&'#252#164#242's'#153'|\'#234'.'#173#250'\5' - +#30#223'aG&'#235'6'#23#127#12#210'"'#145'd'#1#224#27#152#242'D'#16#137#179 - +#162'#"'#2#31#239'$'#228#132'?'#4'N'#158#8#236'm'#13#208#214#248#27'j'#11'A' - +#150'D$D'#10'D&'#193#167#192'i'#3'#'#182'5'#217#136#250'%'#243'*?y'#249'O' - +#160#191#197'*'#191'FM'#130#173#129#252#210'j(,'#169'bj'#190#213#162#5#155'I' - +#155#12#241#137#227#249'B'#18'Ogn>$k'#236#199#144'['#160#214#229#157#185#4 - +#188'Y'#192#218#152'qY'#133#212#153'('#192#215#23'0'#223#0#145#128';'#128#166 - +#1#238#157'Nh'#169'_'#15'^O'#7#231#27#216#209'$h'#1#206'/'#240#177#212#239'3' - +#19#24'1'#191'f'#20'~'#26#139#245#30#10#255#188#174'I=\\'#159'T'#254#25'`' - +#203#207'c+'#190#205#164#3#171'Y'#203#135#247#212#172'XGH'#221'e'#13'7'#146 - +#234#190'h'#229#151#250'M'#142#161'G'#136'|'#132#220','#131'8'#223#201'('#193 - +'7)'#9'sNB'#210#6#220#188'9@'#190#1#167#155#246#254#164'I'#16#224#27#146'DY' - +#155#244'$'#9'P'#214#224#217'H'#2#207'K'#253'>'#211#141#17#241#155'F'#225#159 - +#128#187#255#160#240'O'#18#132#159'b'#243#228#229'gi'#188#182'"T'#249#167#163 - +#192#163#202#143'B'#159#135#155#133'_'#249#141'|}'#190#154'o'#192'A'#141':' - +#229'2Q'#231#220#17#241#9#141'B'#240#13'L'#200#128#23'Z'#153#9#185#3'T['#224 - +#241#134#185'('#1'j'#1#14#212#6#220#168#21#180#183#212'C['#243'&'#214#152#132 - +#202#142#133#156#1#222'/'#128'<'#144'X'#134'$p'#143#212'o-'#157#24#246'?o' - +#222#217#247#1#10#127#137#216#222#167#226#29#157'V'#203#210'x'#11'H'#229''';' - +#223#204#169#252't'#155'e'#243#233':='#252#201#10'='#161':O'#234'76'#134#161 - +'#'#193#165#26#11'-'#200#163#188#147#144#186#19#177#188#1'_8'#169#13'8'#153 - +'F'#16'@'#147#160#3'Z'#234#214'1'#147#128#146#135'('#5'YD'#2't'#172#187'qw' - +#237'H'#153'l4'#172#127#231'('#252'4a'#231'-'#20'~'#139' '#252','#163#143'T~' - +#131#1#138'+f@^^A'#167#224#155#185'0'#31#9'?+'#213#229#227#250'B'#231#29#232 - +'R'#142';'#134#145#1'q'#163#211'd'#164' '#202#165#19#11#225'Br'#14':'#220#28 - +#9#208#214'Z'#191#1'\'#246'&'#212#24#194','#170#16''''#191#0'$M'#130#231#240 - +#128#231#140#132#130#162'a'#251'sG'#225'?'#10'w/'#161#240'k'#132#240#28#169 - +#252'j'#170#213'7'#153#160#164'r6'#216'lff'#235#219#204#218#164#189'/'#180 - +#228'R'#243#173#183#200#209''''#212#225#143#9#255#200#133#144'H'#148'lJ'#130 - +'&A'#24#237#252#16'_n'#204#162#4'nN'#27' '#147#128#162#4'-'#13#155#192#209'Z' - +#203#234#9'('#162' '#174'%@'#18#248'7'#30#238'8$'#129#128#212#239'm('#24#150 - +'?y>'#204'G%'#188'r'#193#211'/8'#251#168#15'_i'#213'L'#176'YM'#144'G'#206'>' - +#139'.'#25#226#211#179'&'#29#202'd'#223'='#161'D'#151#251' '#134#229'G1'#134 - +#1'B<'#216'Th^J+'#188'@'#2'd'#18#144'c'#208#217#17'`'#251#182#230#237#208#214 - +#180#9#130#129'03'#7#186'D'#8#190#194'C'#30#142'$'#224#148#250'}'#13#22#195 - +#238'W'#143#194#127'3'#10#238'mt['#16'~5_'#193'g'#177#22'@i'#229'L'#176'Z' - +#245'L'#240#137#0#200#233#199#132#159'o'#201'%'#30#160#193'>'#128#177'e'#127 - +#212'A<'#2']'#156'' - +#129#253#135#147'c0'#231#197#1#133#159#198'o'#189#141#178#175#18#219#252':' - +#173#26#10#203#166'@Aq%'#243#240''''#133#159'<'#253'$'#252#201#10'>'#174'tW6' - +#22#219#135#223#29'0'#11#2#254#29#167'hi'#181':'#184#231#161#151'`'#234#244 - +'YR_'#162'd'#224'9 '#233#23#136'D'#184#209'f'#228#28'd'#21#133#148''''#208#17 - +'d'#161'B'#167#203#141'$'#240#19'x<'#29#221#145#192';x'#168'#'#145#4'bR'#191 - +#167#254' '#167'e'#130#239#207#255')'#10#191'A,'#252#180#242#23#148'N'#130 - +#162#210#241'I'#225#23'r'#250#5#225#231'Fi'#203'E='#249'r'#250#173'f'#5'''' - +#31#181#16#218#219#186#175'kQ('#148'p'#239'#'#175#192#244#25#187'H}'#153#146 - +'AhP'#10#2#9'D'#185#225'%b'#18'pv'#8#155#27#154'j'#214#128#215#227'fm'#201 - +#187'8'#6#159'F'#2'8['#234#247#211#31#228#172'T'#160#240'O'#193#221'W('#184#5 - +'B'#146#143' '#252#249'EU'#156#205#207#132#159#203#235'gi'#189'z.'#179#143#28 - +#131#138#148#148'^'#24#157'F'#127#23','#191#252#20#248'i'#245#183'=>N$p'#215 - +#131'/'#194#140#153#243#165#190'T'#233#144#28'f'#2#201#129#167'D'#2#212#127 - +#144#230#18#8'$@'#230#128#195#233'B'#18#248#17'|>'#127'2:'#192'&'#21'q'#14 - +#198'?#'#9'\'''#245#219#233#11'9)'#21'('#252#165#184#251#26#133#127#188'8' - +#195#143'9'#252#10#199'AI'#197'N,'#185''''#143#247#246#179#236'>'#157#154#13 - +#215'd'#194'/j'#211#149#179'oR'#2#216#219'Z'#224#180#227#150#224#15#180#231 - +#18'w'#185'B'#1'w'#222#251'<'#204#156#179#155#212#151'+'#9#196#195'P'#133#206 - +'CD'#2'!VC'#16'e'#221#135#133'""'#202#21' '#199' i'#2#1#170#31#160#241#230 - +#204#28'H'#8'$@s'#8#238#151#250'='#245#134#156#147#13#190']'#247#255'Pxg%' - +#133#31#127#148#26#190#168#167#140#226#252#164#242'S'#156#223',R'#251#213'JP' - +#170#184'>}c!'#190#158'q'#255']'#215#194''''#31#190#217#235's'#228'r'#5#252 - +#249#129#21'h'#14#204#149#250'r%'#133#16'*'#20'r'#5'h'#132#25#149#21#139#205 - +#1#210#4#236#237#173#208#178#253'g'#8#132#130#140'('#132#218#129#4'7R'#249 - +#148#134#159'^zI'#234#247#210#19'rJJP'#248#201#21#253#17#141#223#22#170#250 - +#148'|'#134#159#217#146#7'%'#19'fC'#158#201#0'6'#171#150#197#250#217#202#143 - +#194#175#213'(S'#187#246#228#212#187#202'-'#196#227'Q8'#254#176'y'#16#194#31 - +'ko'#208'hu'#240#220'k_'#130'^o'#148#250#146'%'#133#216'1('#152#3#204''''#224 - +#237'L'#27'&'#231' '#151','#180#129#235'0'#20'I!'#129#8#30#225'0$'#129#156#28 - +'M'#150'S'#162#130#4#240#16#10#255#197#226#146'^'#141#138'r'#251'-P:a'#23'\' - +#249#141'l'#213'g'#194'o'#226'V~-'#133#250'D'#243#246'r'#234#13#229'('#222 - +#254#231#179#240#244#223#255#220#231#243#202'+'#171#225#225#167#222#147#250 - +'r%Grr'#17#175#9#4#187#144#128#144''''#208#218'T'#3#246#166#205#157'$'#208 - +#217'O'#192#145'H'#196'vi\'#251'J'#173#212#239#165'+rF^'#248#226#158#127#138 - +#19'}'#168'A'#7'5'#242'('#173#154#11'y63W'#213#199#215#242#147#195#143'*'#250 - +#132#129#28#178#177#149#127'@8'#251#132'%'#224't'#244'='#15'c'#191#131#143 - +#133#11#175#184']'#234#203#149#28'B1'#17'9'#249'"|'#187'1.O '#204'J'#137#137 - +#4':P'#19'hi'#220#4#246#214#237#16#162#198'"'#169'ME'#190#142#4#28'K['#127'{' - +'?"'#245'{'#17'#''D'#134'o'#232#241'#'#149#245#10#225'>'#18'~'#157'^'#15#165 - +#227'w'#1#155#205#154't'#248'Y'#153#218#175#225#235#248';'#213'~!'#183#127#12 - +#253#195'/?}'#7#183',;'#163'_'#207#189#234#134#251'`'#193#146#131#164#190'd' - +#201#145#28'Y'#22#227#204#1#210#4'|B'#155#177'dw'#161' 4'#213#173#131#14#190 - +#148'85<'#24#191#27'M'#129'k!e'#144#186#180#144'\jx'#187#255'K'#20#254']'#187 - +#134#251#138'+w'#134#130#130#210'd'#172#191#179'}'#151#138#235#207#207#183 - +#232#22#6'}'#140'a`8'#239#228#165#168#5#244#221#2#159#194#131#15'='#253#1#20 - +#22#149'I}'#201#146#131'K'#27#230'5'#1#190#185#8'M.'#166#218#1#18'~'#135'''' - +#192'Z'#140'5m'#253#17'' - +#202#242'3'#25#185#149#159#230#241'q'#133'=\'#168'Oj'#6#251#237#215#31#225 - +#230'kNM'#185#143'H'#224#222#199#222#134#210#210'*'#137#175#174'wl\'#183#26 - +'n'#185#246#180'~?'#127#238#174'{'#193#178'['#30#145#250#178's'#2#180'|s-' - +#200#169#187#16#154#3'An"'#17#235','#212#17#20#149#17#175'Ov'#27#22#249#3#190 - ,#12'y['#246'n'#223#242#177#228#29#133'$'#147#31#20'~'#146#14#178#251'm'#226 - +'4_='#218#253'e'#19#230#161#221'oa'#130#207'9'#253'h'#229'W'#179#22'^\I'#175 - +'<9r[j'#220'y'#243'y'#240#243#143#223#236'p'#127'qi'#5#220#247'xnz'#208#219 - +'['#155#224#213#23#30#128'5?|'#1'>'#175'{@'#175'='#243#130#27'`'#255'CN'#144 - +#250'-H'#14'![0'#193#135#7'I'#192'i"'#145#208'^'#140'5'#20'Am'#160#185#238'W' - +'p'#182#215'C8'#196'u'#26'&'#194#224#15'pg'#253'O+n'#0#137'M'#1'ID'#8#133'_' - +#5'\'#178#207#30#226'L?'#157'F'#3'E'#21';'#163#250'_'#146'l'#229'%T'#246'Q3' - +#15#214#194'K)'#227#166#239#230#130#244'#'#206'8z.D#;:v'#149'J'#21'<'#251#198 - +'j'#169'//'#137'p8'#12#239#188#254#4#252#247#227'7'#193#209#222'2'#232#227 - +#200#240#187':'#253#188#235'`'#191'1'#18'H'#166#13#11#227#203'Y'#162#144'P7' - +#144#236'%'#224'GS`5x'#221#174#29#252#1'h1'#30'R'#183'f'#197#135' !'#9'HE'#0 - +'w'#161#240'/'#163#219#10#161#139#175'F'#9#249#133#227#161#168'|2o'#247'wv' - +#239'e'#225#190'd'''#159#220'q'#248#213'l^'#15'7]'#221#179' <'#241#202#183 - +#160#213#234'%'#189#198'`'#208#15#127#185#245#15#176'y'#227#207#189#166#0#15 - +#20#147#167#205#134#229#183'?'#1'j'#181'V'#210#247'''5'#18#162'a'#165'\'#142 - +#0'?{'#128'H'#128#138#134'<\'#205'@'#179#216#31#208'i'#10#180'i'#212#138#217 - +'['#191#127#190#25'$"'#129#172'K'#18#10#255#28#220#253#128#4#160#16#199#251 - +#141'f'#206#238#183#176#6#158#188#221'o'#224'j'#250#233'q*'#238#145#201'd9' - +#21#239#127#255'_'#207#193'+'#207#253#181#199#199#175#189#237'q'#216'i'#214 - +#238#146']'#223#166#13'?'#193#221'('#252#161'Pf'#202#211#213#26'-\t'#245#221 - +'0g'#254#18#201#222#163#212'H$'''#18#9#21#132#220'\'#194'dk1'#26'C'#198'g'#10 - +#182'5n`'#13'F'#187#148#15#191#220#240#211#10#234'w'#193#15'8'#203'.'#178'*J' - +'('#252't'#190#175#197#170#191'`'#247#151#140'G'#187#223'jN'#246#239#167'Q]' - +#212#193'W'#173#22'M'#229#205#21#201#231#241#183'{'#151#193#247'_'#247#156 - +#225'y'#197#13#15#195#172#185#139'$'#185#182#230#198#237'p'#253#165'G'#166'u' - +#213#239#9#187'.'#216#31'.'#188#234'nI'#222'g'#174'@('#30'bN'#193#8#231#15 - +#160'Qd'#212'i'#216#201#166#19#147'?`='#184#218#27'v('#26#146#203#18#251#213 - +#173'y'#137#166#17'g'#157#4#178'M'#0#231#2'7'#187#143#169#254#148#234#171'U' - +#171'Q'#237#223#9#237#254'q,'#212'G'#4'@'#19'z'#141#186'N'#187'_'#220#202'+' - +#151'p'#203'U'#199'A}'#237#166#30#31'?'#245#188#27'a'#233#254'GKrm'#203'/:' - +#12'W'#157#236#181#168'3'#154#173'p'#205#205#143'Cy'#213'dI'#222'o.@p'#10'F' - +#226#220'(2'#214'iX(!&'#18#240#248#161'q'#235#15#224#247'y'#216'0R'#145')' - +#176#161#208#28#223'e'#205#23'/'#135'`'#164#18#0#10#127#1#238'6'#162#240#231 - +#145',+'#168#194#15#5#220'l-'#130#210#170#217#220#136'nQ'#129#15#169#254#201 - +#210#222#28#136#245'w'#135#171#207';'#0':\'#237'=>>{'#222#18#184#248#218#236 - +'W'#131#174#250#246#19#248#251'_'#175#201#250'y'#169#148#248#162'k'#254#138 - +'Z'#207#226#172#159';W@>'#129'x'#12#152#199#159':'#10#249#168#183#160#159's' - +#10#18#17#216#219'['#160#165'v-'#155':'#20#21'B'#131'@?'#239#196#245'{L'#14 - +#255#229#181#215'^'#139'C'#22'I '#155#4#240'4'#10#255#153'B'#194#15'e'#242'i' - +#181#26'('#171#222#21'l'#22'+X-'#26#150#227'o'#210#11#241'~E'#206'W'#247']y' - +#206#190#224#245#184'z|'#220'`'#180#192'}O}'#154#245#235'z'#230'o'#183#192'7' - +#255#253#183'$'#159#9'iw'''#156#185#12#246'>0'#247#19#161'2'#1'nE'#231'z'#11 - +'R'#166' '#181#26'gIB'#194'@R'#26'8R'#251#11#184#28'M]K'#135'}'#10'Yd'#230'Y' - +'G'#236#180#253#214'[o'#205#154')'#144#21#209'B'#225'_'#136#187'/'#196'M=)' - +#225''''#191'x'#2#20#150'M'#228#236'~'#190#159#31#27#209#205''''#251#200#20 - +'|'#154'o'#142#142#228#190#242#156#165'L'#157#235#13#203'n'#127#22#170'''' - +#207#204#234'u'#253#241#186#147#160#174'f'#163#148#31#13#236'{'#200#201'p' - +#236#169'WJz'#13'R!'#217'e'#152'2'#5'Q'#19#160#162'!'#174#155#16'_='#232'rC' - +#211#214#239'!'#16#12'tI'#16#138#191'5'#217#214'x'#204#231#159#127'.h'#1#25 - +''''#129#140'K'#22#10#191#18'w'#171'Q'#246'g'#138#29#127#6#163#9'W'#255#221 - +'P'#232'u'#220#234'o'#20'B~'#156#221#175#148'Q?'#191#172'\'#226#160'q'#229'Y' - +'KX'#152#173'7L'#156':'#27#174#186#229')v'#155#190#232#141#235#190#135'_~' - +#252#2'j6'#255#2#173'-u'#16#14#5#161#176#184#28'f'#238#178#24#150#236#127',' - +#216#242#139#135'|]w\{<4'#214'm'#145#250#227#129'='#150#28#6#167#157#127#171 - +#212#151'!'#13'(*'#144#224#187#9#133'R'#203#135'iko'#222#14#237'M'#155' '#28 - +#230'M'#1#222'!'#168#144#197#143#216'}r'#244#223#217'2'#5#178'A'#0#201'~'#254 - +#130#227#143'V'#255#226#138'Y'#144'_X'#194#170#251#204#204#235#175'f3'#251'4' - +#194#164'^'#5#191#242#231#174#252#195#21'g.'#198'/0'#216#231#243'*''L'#135 - +#246#214#6'^['#232#253';'#173#154'8'#3'.^'#246' '#232#141#230'A_'#215#223#239 - +#189#18'~^'#253#133#212#31#15#195#137'g]'#7#139#246'=J'#234#203#200':'#196 - +#249#1#194#172#1#242#7'P4'#192#229#14#129#27'I'#160'q'#219#15#204#132#236#146 - +#27#176#173#196#26#155'S]'#20#243'e'#131#4'2*^('#252#229#184#251#21#133#223 - +'(8'#254'h'#245'7'#219#138#161#164'r&'#179#249#201#243'o'#22#169#254#148#240 - +#195#138'j'#134#193#140#238'+'#206'\'#4#209'H8'#237#199#165#234#187#227#207 - ,#188#22#246'\'#250#251'A'#189#254#173#151#31#130#143#223'}A'#234#143#135#129 - +'4'#190#229#127'Z'#1#165#229#19#165#190#148#172'#9'#131#144'R'#133#249#209'c' - +'n'#26'I'#206#180#128#16'8'#236'm'#208'R'#187#134#213#10#136#27#138#202'e' - +#137'?'#21')6'#222#186'j'#213'*j-'#158'QS '#211#4#240','#238'N'#231#194'x\' - +#165#159'N'#167#129#210#9#187#162#218'o'#6'3o'#247#155'x'#213'_'#165'Rt'#198 - +#251's\'#248#9'W'#158#177'p'#135'A'#27#233#2'}'#6'W'#160#233'@'#26#193'@'#225 - +#180#183#192#173#151#255'N'#234#143''''#9#157#222#8'w<'#244'>(G'#227#240#145 - +#132#184#167' '#167#5#176#198#162#158#16#155'@'#220'Z'#255'+t8'#26#152'C0'#22 - +#139#9#164#17#210'(";W'#154'[k>'#255#252's'#129#4'2'#130#140#137#25'_'#236 - +#179#25#127#200#202'd'#147#15'\'#225#243'J&Aa'#201#4'&'#248#22'>'#219#143#188 - +#254'B'#194#143#208#214'K6'#28'4'#128'3'#22#160#234#150#185#249#15#148'F'#252 - +#199'G>'#4#165'j'#224#130#243#199'k'#143#131#214#166#237'R~<)'#168#24'?'#13 - +#174#190#253'9'#169'/#'#171'H'#206#31#20'G'#5#130'\'#150' E'#5#152'&'#224#246 - +'A'#211#182#149#16#240#7#146#25#130'd6'#160#22#240#216#30#147'#'#151#226#203 - +'c'#153'4'#5'2I'#0#127#195#221#5#194#234'O'#171#187#222'`'#198#213#127'>'#174 - +#252#186#164#234'O1'#127#13#175#250#11#173#188's5'#236#215#21'W"'#1'd:'#211 - +'n'#206'n'#251#194#233#23#253'q'#192#175'['#245#205#135#240#226#223'o'#145 - +#234#163#233#22'{'#29'x'#2#28'q'#210#229'R_FV'#145'L'#21'&_'#0#223'T4'#16#226 - +#18#132'H'#3' "ho'#169#5'{'#211#198#174'a'#193#160'Y'#23#157#174#143'ln'#200 - +#164')'#144#17'Q'#227#251#250'oCa'#214#8#171#191#150#194'~'#227'v'#130#130 - +#194'q,'#233#135'R}'#169#198#159#10'}'#146#173#189#134'Y['#175#171#207'^'#136 - +'_lf'#9'@'#173#209#193#157#127#31'\.'#193'u'#231#239#3#225#12#213#1#12#22#231 - +'^y'#31'L'#155#185#135#212#151#145'u'#136'G'#145'S'#130#16#171#21#224'K'#135 - +'I'#19' -'#192#231#245'$'#147#131#226#156'/'#224#129#137#214#198#229#133#133 - +#133#145'Li'#1#153'"'#128'{pw'#149#216#246'7'#24'q'#245#175#222#21'W}m'#146#0 - +'('#215'_'#163'Q'#138'r'#253'3'#253'5'#164#23#203#206'Y'#196#190#172'L'#131 - +#132'f'#234#206#3'/*'#250#199'3'#127#130#149'_H'#147#16#212#19#242#10'J'#225 - +#250#191#252'S'#234#203#200':'#132#4'!'#161'V'#128#229#6#8#166'@W-'#128#250#8 - +#178'(B'#194'k'#209#248#166#203'|'#155'Z'#143'='#246#216'h&'#18#132#210'.r(' - +#252#249#184#219'.'#158#231'G*~~'#233'4(('#174'`'#182#191'9'#153#238#171'J' - +#233#231'?'#220#176#252#188#197#25#245#1#8#152#188#211#174'H'#2#15#12#248'u~' - +#159#27'n'#187#252#224#164'-'#154'+'#184#244#198#167#161'|'#252'4'#169'/#' - +#235'`i'#194#162#178'a'#214'U'#152#143#10'Px'#176'i'#203'w'#224#247#251#152 - +#22' D'#4#20#178#248'_'#198#233'jn'#213'h4'#145'L8'#4'3A'#0#255#135#187#27 - +#133#184'?'#173#254'z'#189#1#202'&'#238#193#4#159'<'#255#20#243#167#176#31 - +#149#249#178'b'#31#190#189#207'p'#226#128#166#186#205'p'#255'm'#167'g'#229'\' - +'&K>'#220'xo'#255'z'#247'u'#197#227#247'\'#10'[6'#172#202#230'G'#211'''*'#171 - +'w'#134#139#174#127'L'#234#203'H'#162'v'#235'z'#248#224#141#191#179'U'#248 - +#202#219'^'#4'm'#6#134#161#236'P6LZ'#0's'#8#134'Xkq'#242#7#216'['#182#131#189 - +'y'#19#203#11#16'E'#4':'#10#13#222#25#165#150'p'#187#209'h'#140#166#219#20'H' - +#171#200#161#240'S'#246#10#173#254#214'd'#193#15#10'y^'#233#20#200'/'#170'd' - +#4'`'#225'+'#253#132#213'_.'#204#241'K'#251'G'#158'Y<'#245#192#149#176'i'#221 - +#202#172#156#139#138'l'#254#244#232#127#7#245'Z'#183#171#13#238#188#246#168 - +#156#210#2'hq'#184#225#158'w'#192'h'#178'Jz'#29'?'#175#250#12#222'z'#233#175 - +#224#245'8'#147#247'Yl'#133'p'#237#157#175#225'oR'#153#246#243#9'#'#200#147 - +#29#132#216#188#193#8'x'#242#5'P'#181#224'w'#16#164#136'@'#172'S'#11 - +'P'#202#227#255'7'#181#208'~'#151#221'n'#15#167#219'!'#152'n'#2#184#30'w'#127 - +#20#175#254#172#183#127#245#238#184#234#235'p'#245'Ws'#157'}'#249'b'#159'd' - +#216'o8-'#253#192#133'tn'#190'x'#31#136'g('#7#160';\'#247#151#183#152'&0'#24 - +';d'#213'_'#204#156#191#15#156'x'#174#180#3'G'#222'|'#225'.'#248 - +#254#203'wv'#184#191'x\5\v'#243#243#25'9'#167'0'#130'<'#22#19#194#130#145'd' - +#243#16#210#4#218#155#183#130#179'uk'#215'r'#225#246#170'<'#255',u'#194#233 - +'L'#183'C0m'#146#135#194'O'#189#175'jP'#152#11#133#156#127'J'#249#205'+'#158 - +#4#249#197#227'q'#245'Ws'#131'6'#127#209#225'p'#196')'#203'2r^'#241#152'1'#234'#'#232#167 - +#228' >*@Z@'#211#150'o!'#24#10'B4'#210'Y#'#160'R'#196'o'#24#167#171'}'#200 - +#229'r'#133#210#233#16'L'''#1'\'#134#187#251#133#22#223'JV'#238#171#195#213 - +#127#15'0'#25#185')'#190#228#249#215#137'W'#255'af'#247#11#248#203'uG'#130 - +#167#195#158#213's'#206#156#191'/'#28'w'#214#224#227#250#143#254#249'\h'#172 - +#149#182'B'#176'+'#14':'#234'"X'#184#223#241#146#157#127#235#198#213#168#29 - +'u'#159#151' '#147#201#225#218#187#254#5#6'cf'#204#148#148#185#2'4v<'#16#6 - +#143#151'#'#129#246#166#205#224'j'#171'I'#169#17#192#127#154'&'#216#218#230 - ,'DC'#30'O:'#29#130#233'$'#128#159#196'#'#189')'#231#223'VT'#13#249'%'#213',' - +#219#143'y'#254'u'#157#147'|'#5#219#127#184#161#177#246'7x'#236#174's'#179'~' - +#222#130#226'J'#184#228#230#193#231#247'?'#250#167#179#160#185'A'#250#10'A1' - +#170#167#205#131#211'/'#249#235#208#15'4H'#4#253'^'#184#243#154'C{|'#188'j' - +#210'l8'#235#138#7'3rn'#161'N'#128#204#0'J'#14#242#5#195#172'd'#152#204#0#183 - +#199#11#205#219'V'#162#22#16'Ji'#29#166'SFO'#221'i\'#224'-$'#128#208#140#25 - +'3'#210#162#5#164'E'#2#199#205':q'#14#200#228'?'#166#14#248'PC'#217#196'=' - +#193'h'#212'%'#195'~]m'#127'v'#1#195'L'#5'x'#246#129#203#160'f'#211#154#172 - +#159'W'#161'T'#193'M'#247#127'<'#232#215'?p'#203#9#224#180'7e'#253#186'{'#131 - +#209#156#15'W'#255#233#13'I'#175#225#214'K'#150'v'#186#232#187#193'y'#203#158 - +#128#178#202')i='#167'`'#138'u'#230#5#196'Y#Qj'#28'Bu'#2#20#26'lk'#218#8#238 - +#246':'#22'-'#16#210#131#21#242#196#191''''#231#181#156#145#151#151#231'okkK' - +#139#22#144#30#2#152'}'#242#189#184#187'R'#156#248'c'#206'+'#133#162#242#25 - +'l'#245#167#141'l'#255#174#5'?'#195'L'#246#25#238#184'|'#191#140#21#0#245#133 - +#195'O'#186#6#230#238'y'#232#160'^{'#207#245'G0_@.'#129'4'#197#155#30#200'~' - +#199'$1'#250#250'>+&'#236#12'g]'#249#240#0#142#216'?'#8#26'@gD'#160#179#135 - +' +'#22'r9'#160#173'v'#245#14'EB'#165'F'#215#156'Bs'#188#209'h4'#6#211#161#5 - +#12'Y'#4#11'&'#238#167#212#24#139#235'P'#160'K'#196#206#191#194#242'Y`'#205 - +'+J'#18#0'7'#211'O'#148#243#159#246#143'4'#243#168#223#182#14#158#185#255'b' - +#201#206'o+('#131#139'oZ1'#168#215#222'u'#237#161#16#238#163'y'#137#20#184 - +#225#222#143'@'#174#148#206#17'x'#247#242#195'!'#24#240#246#248'8'#249#2#150 - +#223#243'>.j'#233#175'd'#20#198#139#209#198':'#9#135'"\'#15'A$'#0'2'#7#154'k' - +#190'g'#201'\bg'#160'F'#17#185'~'#130#205#254'x'#186#180#128'!'#203#225#184 - +#217''''#29#130#135'yW'#172#254#235'tz('#157#184#7#152#244#26#214#229#135'e' - +#253#241#171'?'#169#255#220#7#155#246#207'3'#227'xg'#197#159'a'#237#247#255 - +#25#250#129#134#128'E'#7#158#10'{'#29'|'#230#128'_'#247#231#171#15'D{2'#167 - +'F'#211'3\q'#199#27#160#207#144#163#173'?x'#232#182#19#192#237#236'}B'#242 - +#194#253'N'#130#165#135#157#147#145#243''''#135#138#196'83'#128#178#3'='#188 - +')`o'#169#1'g'#203#230'd'#219'0'#190'Jp'#213#228#188#230#223#163#6#224'N'#135 - +'/`'#168'b(C'#245#255'%'#220#159' '#174#250#179#20'TAA'#233'd'#182#242#147 - +#240#179#156#127'a'#180#215'0'#140#251#11'x'#152'~,'#174#190#199'ig'#18#244 - +#217#157'q'#249'#PZ9'#176'T'#218';'#175#220'/+3'#2#6#138#11#174#127#1'l'#133 - +#227'$;'#255'S'#247#156#7'-'#13#155'{}'#142#193'd'#131#203'n'#207'L'#253#2 - +#203#11#192#175'%'#154#156'''@y'#1'\'#207#0#143#199#3#205#219#190#235'j'#6'$' - +#242#180#158#189#139#140#190'_'#210#161#5#12'I'#18'Kw>'#214'"W'#168#155#240 - +'G'#169#19'w'#252')'#170#154#7#22#139#141#9#191#208#231'O'#205#175#254#178'a' - +#24#247#23'p'#215'5'#251'g'#188#250#175'?'#208'h'#13'p'#217'mo'#12'Hu'#206 - +#149'k'#239#138#11'oz'#5#204#214'B'#201#206#255#226#195#151#161'i'#247'K'#159 - +#207';'#227#138'G'#161#164'<'#189#206'@'#1#226'J'#193#0#211#2#194'L'#11' 3' - +#160#165'n'#13#248#220#246#20'3@'#173#136'>2)'#223#241''''#157'N'#231#25#170 - +#22'0'#20'I'#148#141#155'u'#210'Y('#205'O'#138'c'#255':'#189#25'J&'#236#202 - +'B~F'#3#183#250'k'#133#138'?'#129#0'2'#242'1f'#30'w]'#189#159#212#151#144'DE' - +#245',8'#233#194#254#135#208#238'^v@V*'#23#7#2#250#221','#187#251#163#172#159 - +#215#209'V'#7#171#190#252#23'4'#213'n'#128#182#230'm'#253'j'#235'V5i'#23'8' - +#225#252#244'O?'#18'$'#150#141#26#143'u:'#3'}'#228#12'D"p'#182'7'#128#189#241 - +#215#20'3@&K'#212'M'#201'k'#222#27'??'#215'P'#181#128#161#17#192#236#147'?' - +#199#253#18'.'#166#207'M'#248#181#22'q'#153#127'$'#248#194'`O'#173#134'k'#244 - +#169#16#226#254#195'P'#3#8#6#189#240#208'MGH}'#25')'#216#231'w'#23#194#188 - +#197#253'k'#184'y'#239#181#7'f'#165'rq '#160'^'#7#151#221#241#206#208#15#212 - +#7#162#209'0'#252#188#242#3#216#176#230'S'#166#238'G'#250#209#200#181'+'#228 - +'r'#5'\q'#231#251#236'w'#158'v'#240#209#0#193#25#200'B'#130#188'/'#192#231#11 - +'@'#243#214'o'#184#190#129#157'f'#0'X'#181#129'S'#202#173#190'OQ'#3#240'644' - +#4#15'?'#252#240#216'`'#180#128'AKb'#217#204#227#170'er'#21#181#252#146#137 - +#213#255#226#234#221#209#246'7'#166#172#254#164#254#211#7''''#31#198#234#127 - +'['#211'Vx'#238#190'?H}'#25') '#15#245'YW?'#133'6ty'#159#207#253#235#242#131 - +'r'#142#0#242#138'*'#217#245'g'#18#159#189#243'wX'#245#5#229#26#12'='#13'z' - +#241'Ag'#194#238#251#156#148#145#235'$'#225#23#18#131#184'"!./'#128#234#4#218 - +#234#215#131#167#163#169'Kjp'#236#141')'#5#142#171'U*'#149#203#135',1'#216#26 - +#129#193'J'#163#172'|'#246#201'7'#226#153'n'#23'{'#255#141#230#2'('#172#152 - +#205#173#254'z'#21#232#209#12#160'6'#223'*'#149#144#246';<'#133#159#176'm' - +#195'w'#240#230#179'7I}'#25';'#128'<'#232#231#223#248#143'>'#159'w'#255#13 - +#135'd'#181'x'#169'?'#216#251#240#11'`'#151#133'Gf'#236#248#219'6'#174#132'7' - +#159#185'1m'#199#179#228#149#194#217#203'2'#211#215'P'#152'+'#200':'#8'G'#185 - +#225#162'>'#161'i'#136#179#21#218#235#215#166'$'#5#201' '#209'19'#191'u'#145 - ,'\'#150'h'#195#197#215'+'#170#20#28#144#157'7h'#2'@'#245#159#234'S'#23#139'+' - +#255#242'J'#167#131'-'#191#12#244'zU2'#244#199#138'~'#134'q'#222#191#128#159 - +#191#127#31'>~#'#251's'#254#250#131'I;/'#130#195'O'#238#157#156#30#188#241'P' - +#201#18#152#186#3#149'8_v'#251#191'I'#183#206#200#241#253'^'#23''#232#163'7|'#247#217#10#248#230#163#204 - +#148#136#166#3#135#156'p=L'#153#181'W'#143#143'?q'#231#137#224#243'8'#164#190 - +#204'$'#170'&'#207#131'#'#207#252'S'#198#142#255#244#221#167#129#219#217#146 - +#246#227#238#182#247#137#176'`'#255'3'#210'~\'#241' '#145#168#168'y('#133#4 - +'I'#19'ho\'#7#30'gsJm'#128'^'#21'y'#180#210'b'#191#31'I'#193#129'&'#128'o0' - +#206#192'A'#17'@'#197#156#147#247#195#235#252#143'X'#253#215#234#200#251'?' - +#159#9#190#1'5'#0#193#249#199#133#254#134'o'#234#175#128#207#223'y'#4#214'~' - +#155'y'#135#213'`'#161'Ti'#224#194'['#223#234#241#241#247'^'#186#3'6'#175#251 - +'R'#234#203#228#175'U'#13#231','#127'%c+'#233#251#175#222#9#155#214#14#174 - +#129'J'#223#215#174#129#243'o~3#'#206'@ae'#167'h@'#152#31'$B'#137'AD'#0'N{=8' - +#155'6'#166#180#11'S'#202'c'#223'O'#202'k;'#7#175#165'='#18#137#184'='#30'Oh' - +#160#13'C'#6'E'#0'h'#255#255#9#143#190'\'#28#254'3'#219'*'#209#4#152#204#236 - +#127#218'h'#188#183'Z'#24#243'5'#12#171#254#186#226#235#15#159#130#213'_'#190 - +'.'#245'e'#244#138#5#7#156#9's'#23'w?'#149'w'#203#250#175#224#253#151#239#144 - +#250#18#25#14';'#229'6'#24'?u'#183#140#28';'#232'w'#195#147#127'>'#161#215#2 - +#159#161'b'#202#172#189#225#128'c3'#215'+'#128#181#12#19#204#0#158#0'|^/'#180 - +#212'|'#151','#17#230#252#0#16#156'\'#208#182#31#138'Y'#227'`'#157#129#3#149 - +'L'#217#173#183#222'*{'#226#205'M_'#225#237'='#196#197'?y'#227'v'#6#171#173 - +#152#23'~n'#245#231#188#255#178'a'#217#240#179'+'#182#172#255#18'>x%s*k:'#160 - +#213#153#224#236#235'^'#237#254'A'#252#209#252#237#182#195'%o'#10'2e'#246#222 - +#176#255#209#215'd'#236#248#159#188'q/lX'#243'IF'#223#3'-|''_'#246'$s'#10#166 - +#27'I3 '#206#153#1','''#0#9#128#136#128#8' '#24#240#165#248#1#10#244#254'K' - +#11#13#158#143'Q'#11#176'SH'#16#181#128#240'@'#204#128#1#19#192#148#221'N2' - +#251'B'#178'v'#154#248#211'i'#255#171#160#164'zO'#208#235'u'#172#232#135#156 - +#127'Z>'#245'W>'#12#219'}w'#7'ZY'#158#185#235'D'#169'/'#163'O'#236'{'#212#213 - +'L'#200#186#195#11#247#158#14'^w'#187'd'#215'V4n2'#28'}^f'#29#169'O'#220'q' - +#20'D#'#161#140#191#23'K'#254'88'#233#210#199#211'~'#220#174#237#195')'#26'@' - +'$'#16' ?@'#211#6#240'8'#27#187#250#1'^'#172'0'#183#223#135'ZA'#171'N'#167's' - +#15#180'Jp'#160#162')/'#159'}'#226'!'#9#144#191'#'#216#244#20#255#215#27#172 - +'PX9'#151#9'?'#249#0#152#250#175'$'#239#191#208#244'cd'#144#192'cl'#5#205#173 - +'l'#186#174'(.'#159#6'G'#158'so'#183#143#173#252#228'9X'#253'E'#223'!'#195'L' - +' '#191'x'#2#28'{A'#250#203'j'#197#248'u'#213#7#240#223'w'#30#202#218'{Zt' - +#240#249#176#243#238#135#167#245#152'|'#247#31#212#0#184'nA'#194'hq6^'#220 - +#209#4#142#166'_'#187#250#1#214'M'#206'o?'#31#9#160#9#205#0'g('#20#242#15#196 - +#12#24#136'X2I.'#159's'#242#221'x'#222'+'#197#14'@s~%'#235#253'G'#194#175'G' - +#225#167'a'#31'D'#0'r'#133'l'#216#135#255#196'x'#225#222'S'#193#239'u'#14#253 - +'@'#25#132'Zk'#128'3'#175'}'#181#199#199#223'x'#252'rhk'#218'<'#128'#'#14#29 - +#214#130'r8'#254'"'#154#20#151#153#144#159#128#151#30'8'#27'<'#174#244'{'#254 - +'{'#2#245'5fV'#248 - +#219#26'7'#193#191#158#186'2+'#239'I'#140#25#187#30#6#11#14'Jo'#134'hgRPg' - +#159#0#193#20'h'#175#253#129#245#8#16'u'#12#134'|'#157#247#230'b'#147#255'}' - +#148#201#22'$'#128#14'2'#3'P'#3#136'B?'#162#1#3#17'O'#249#132'9G'#230#133#19 - +#250'f'#188#173'H'#150#255#170')'#254#191#16#237'~'#174#233#7#197#254'5|'#242 - +#15#215#245'w'#228'0'#128#179'm;'#188#241#152't'#13'A'#250#139#197#135']'#10 - +'S'#230#236#223#235#251'x'#243#241'K3n'#206#204'^x'#28#204#223#251#212#172 - +#188#231#183#159#190#10'I'#224#183#172#156'K'#12#149'Z'#11#167'-{-'#189#7'Mp' - +'9'#1#228#8#140'D'#184'h'#128#16#18't'#182'lBS'#160'N'#1'D'#2'd'#226 - +#216#27#215#165'8'#2'U'#242#216'&4'#3'.'#198#219#13']'#204#128'>'#163#1#253 - +'&'#0'R'#255#191#217#164#186')'#145#144#221'"'#216#255'4'#247#207#156'?'#30 - +#172'E'#19#152#240#147#243#143'&'#1#177#220#127#249#200#178#255#5'|'#251#225 - +'c'#240#235#170#247#164#190#140'^ '#195#21#233#31'h'#154#245#175#133#213#170 - +#207'_'#128'u+'#223#198#31'T'#223'%'#177'}'#158#25'5'#194#9#211#23#194'B'#212 - +'@2'#209'B'#171'''|'#242#250#157'P'#251#219#183'Y;_W'#152'l%p'#204#5#233#27 - +'u&D'#2#132#226' V'#27#16#138'23 '#16#8'B'#203#182#175#240#251#138''''#29#129 - +'2Y'#194'7'#173#160#245'd4'#11#234'('#26'`6'#155';'#182'l'#217#18'Z'#183'n' - +#29#153#1#189#170'y'#253'&'#128#165'K'#151'*6'#187#198#189#128#231';A'#236#0 - +#180#149'L'#7#147#181#132#9'?'#167#254'wv'#254'aC?F'#152#6#16#143'Ga'#5'j'#1 - +#180#207'E'#232#12'68'#238#146'g'#7#250#174#224#251'O'#158#133#223#214'|0@' - +#141'@'#198#178#250'4:3'#20#148'N'#130#5#7'_'#12'jm'#250#231#234#245'z'#229 - +#236#251'8N'#210'JG'#146#135#211#174#253'WZ'#143#201'R'#131'y?'#0#155#29#128 - +#4'@'#27#17'A'#235#182#239' '#28#246#167#248#1#198'['#237#231'j'#20#225#245 - +'J'#165#178#9'W'#127#167'N'#167#11#244#167'6'#160#191#210')'#159'7o'#158#162 - +'9:'#141'hv'#174#152#0#10'*'#230#130#201'le'#194#175#213't'#134#255#134's' - +#235#175#190#240#213'{'#15#194#230#28'u'#6#142#199#21'x'#175#223#15'>'#209 - +#134#242#29#234'6}'#7'M'#219#215#178'N4'#241'X'#132'U'#17#146#160#145#160'[' - +#242#203#153#176#23'W'#236#4#230'<'#233'Zy'#9#248#254#147#167'a'#253#247#131 - +#27#156#154'N,='#234'Z'#168#154#178'g'#218#142#215'u'#132#24'5'#10#9#242'Z@{' - +#253'Oh'#246#216'S'#8#160#216#232#249#147'M'#235#251#24#239'k'#196#191#237 - +#161'P'#200#215#159#1'"'#253#145'Pf'#255#31'|'#240#193#170#181#141'ymx'#219 - +'$'#142#0#20'MX'#8#6#157#134'['#253#133#226#31#249#200'I'#0#234#14'$'#12#175 - +'=tF'#214'<'#233#253#6'~'#224'G'#254#225'Q0Z'#138#165#190#146#172#225#229#191 - +#158#136'Z'#203#192#27'|'#164#27#21#147'wC'#18#184'.m'#199'K'#13#7'v'#18#0 - +#141#21'w4'#253#6'^WC'#151#6'!'#254#23#139#244#174#151#209#254#175#139'F'#163 - +'mj'#181#218#211#159#18#225'~'#17#0#217#255#171'6'#199'+Cq'#237#214#164#3#16 - +#237'='#181'F'#143#4#176#27#203#250'c'#171#191'Z'#193#186#2')'#21'#'''#249 - +#167''''#216'['#182#192#7'/,'#203'h'#206#249'@Q9e'#15'X'#252#251#204#228#168 - +#231'"6'#253#248#1#172#252'8'#253#217'x'#131#129'Vo'#129#163'/z&'#173#199#20 - +#210#130#201#214''''#2#16#162#1#29#246':'#232'h'#221#156#18#9'0'#168'C'#159 - +'UZ\'#15#163'|'#214#14'$'#28#216#31#17#149#163#253'/'#175'q'#151#238#23#137 - +#201#223'O'#137#0#24#242'!'#191'b'#22#155#3'@'#177#127'F'#0#138#206#8#192'H' - +#199#154#255#189#0#235'W'#190')'#245'e0'#144#231#253#152'K^'#204#170#243'Mj' - +#188#249#232#217#16#240#229'Fb'#150#12#127#240'''^'#153#222'b1a'#148'x'#140 - +#207#7' '#2#8#134'#'#224#235#176#131#189#241#231#148'H'#128'F'#25#253#181#218 - +'f'#191#3#229's;'#254#221#20#12#6#157'J'#165#178#207#226#160'~'#17#192#140#25 - +'3'#148'n'#213#172#11#226#9#249#253'b'#2'0'#217#202#193'V<'#25'U'#255'N'#2'H' - +#142#252#30#225#26#128#128#207'^'#191#29#154'j'#178'?*L'#12#242#190#239'}' - +#204'MPR5['#234#143'#kh'#220#182#26'>'#255'gnT7'#10'8'#225#242'W@'#158'&'#2 - +'f'#170'='#223'#@'#240#3#176'~'#129#148#16#228#247'B'#235#246#149')'#4#160 - +#148#199#237#147#242'Z'#175'E'#185#164#9#221#13#129'@'#192#238#247#251'}&' - +#147#169#215#226#160#190'D'#148#169#255'^'#175'W'#249'K'#147#237#190'xBv'#129 - +#152#0#172#197'S'#192#130'$'#160#161#8#128'J!'#234#254#3#204#30#29#13#4'@' - +#248#238#195'G`'#235'/'#210'8'#5#233#251'Xr'#228#245'P6a'#174#212#31'CV'#241 - +#239#167'/'#6#143'3'#183'f'#29#238'{'#252#237'l'#28'^'#186#144#236#15' '#26 - +'%N&@'#24'5'#129#230'-_B4'#18'I'#18#0'">5'#191#229'r'#20#203#173#248'w]8'#28 - +#166'Va'#30'Q'#143#128'n'#253#0#253'"'#128#182#182'6'#213'fW'#217';'#137#132 - +'l?q'#17'P'#222#184#153'`4'#23#178#213#159#171#254#235','#0#26'%'#178#159#196 - +'/'#223#252#3#183'W'#135'~'#160#1#128':'#213'.8'#236'*('#159#180#187#212'o?' - +#171'p'#182'l'#133#15'Wd'#174#164'x'#176#152#179#228't'#152'6'#255'wi;'#30'_' - +#23#196'|'#0#177'(?D'#20'M'#0'r'#6#182'm'#255#1#194'A/'#171#9#16#136#162#210 - +#226#252#139'A'#29#254#142#252#0#161'P'#168#197'`0t'#212#214#214#6'{'#203#7 - +#232#147#0'('#254#143'j'#132#250#199'Z'#243'z'#27#205#196#146'wv'#1'RB'#209#132'E'#160#165#236'?u'#151#177#223#195#184 - +#253#247'PA'#171#211#234'O'#30#3'G3'#253'@'#211'O'#4'*'#181#30'v^t'#18'L'#154 - +'s'#176#212'oU'#18#248#221'm'#240#238#147#231'K}'#25#221'b'#210#156#131'`' - +#151'}'#206'M'#235'1'#217'b'#194#143#14#139#242'&'#0#249#1'\'#246'm'#224'm' - ,#175'I!'#0#139'6'#240'q'#153#201'M'#163#250#182#225#223#141#184'''?'#128#191 - +#188#188'<g'#255 - +#167'$'#0#201'G'#141#237#223#27#130'~'#23#172#254#244'Ih'#216#250'=2'#248#208 - +#179#212#244'hj'#237#188#231#9'0~'#250'^C>'#214'p'#198#127#223#248'?h'#169 - +#253'I'#234#203#232#22'S'#230#30#206#204#128'tB'#136#4'P80'#18#163'\'#0#218 - +'"'#172'1'#136#171'ecJ2'#16#170#255'?V'#152#29#143#201#229#242'mx'#127'='#154 - +#233#237'}u'#9#234'MTY'#251#175#239#190#251'N'#245'['#171'q~0'#170#254'R'#198 - +#229#246'2'#2#208#26#242#160#160'|6'#18#0'7'#248'S'#171#230#186#255#202'y' - +#239#255#232#243#2't'#15#250#130'~'#254#250'%'#168#221#240'?'#22#178#234'o'#5 - +#30'y'#246#13#150'"('#169#154#3#147#231#28#2'f'#155#244'YwR#'#26#14#194#27 - +#143#158'"y['#179#158'0}'#215#163'`'#214#194#147#211'v'#248'1'#228#14#254#249#192#9'h'#3#167's'#208'gzA+'#255'A' - +#167#167#127#230'A'#178',8'#193'E'#148#136#0'hX('#245#5'h'#221#250#5#27#248 - +'*Z'#145#187#141'N'#20'*'#13#28'}'#233#203#25 - +';'#190#160#248'PYp'#8'5'#0#31#18#128'?D3'#2'VA$'#232'N!'#128#234'<'#251#11 - +#26'Et='#222#220#138#191#231#237'h'#2#244#26#10#236#145#0'('#4'XXX'#168'B3' - +#192#248'K'#147#237#159#241#132'l1{@ '#128'q'#179#193'h'#202#7#147#137''''#0 - +#26#3#206#183#1#207#4#9#188#243#216#185#224#239'E'#160#199#207#216#27'v?'#248 - +#18#230')^'#245#241#19#3'N'#191'U'#170#180#176#199'!'#151#193#184#201#163#171 - +#178'n8'#128'l'#223#215#239';6g3'#0#231#238's6'#211'&3'#5'!'#29#152'"'#1#212 - ,#25#200#235#11#177'\'#0'J'#4#10#251#157')'#4'0'#222#234#248#135'N'#21'YK&'#0 - +#229#2#224#234'O'#205'A\'#212'$t'#247#221'w'#143#12#136#0'('#7' '#20#10#25 - +#127'm-x'#27#9#128'IF'''#1#204#5#163#217#10'f'#163#22#180'H'#0#212#9'H'#166 - +#200'\'#15#128#143'W,'#7'{'#227#198#30#31'''/l'#193#184'i'#208'Z'#251#243#144 - +#206'SX1'#3#150#28'u#j'#19#218#204#188#145'1'#12#10#239'>q'#1'x]'#205'R_'#198 - +#14#160#26#141#195#255#144#217#182'd'#9'^d'#217#192#208'p'#20'<^'#158#0#234 - +#215'B8`O!'#128'J'#139#227#13#189'*L'#197#18#201'\'#0#212#226#157'H'#6#221 - +#230#2#244'J'#0'j'#181'Z'#19#139#197#140#155#28'E'#175#196#226#242#165#236#1 - +#222#203'o+'#157#131'&@>'#243#1'P$@'#145't'#2'f'#134#1'V~'#240' l'#203'R'#211 - +#13#5#146#201#220#253#206#131#234#153#251#15#253'`cH'#11#214'|'#254'LN'#166#1 - +#31'p'#234'=`+'#158#148#209's'#8#233#192'q'#158#0#220'D'#0#254'0'#18#192#26 - +'4'#1'\)'#4'0'#193#230'x]'#171#140#172#3'>'#27#144#186#4#247'6-'#168'O'#2#8 - +#135#195#166'm'#29#165'OF'#227'r'#166#227#8#4'`)'#153#9'f['#17#24'y'#2#160'f' - +' '#178#12'N'#2'j'#174'Y'#3#255'}'#237#214#140'~'#208']a+'#158#8'K'#143#187 - +'-'#235#189#238#199#176'#'#130#254#14'x'#251'og'#230#212't'#230#146#9#187#192 - +'^'#199#220#146#241#243#8'EAqf'#2'D'#192#235#14#129#151#8#160'n'#21'DB'#30 - +#238'9<'#1'L'#180#181#189#162'R'#196'6Q='#128#208#30#12'I'#192#209'S2PO'#210 - +#154#204#2'D'#152'6'#180#218#238#143#198#21#201'('#0#17#128#185#136#250#194 - +#151#128#201#164#3#131'^'#197#17'@'#134#235#0'^'#187#247'('#180#131#178#251#3 - +#144#203#149'0{'#233#25'0y'#222'aY='#239#24'v'#196#166#213#239#194#143#159'<' - +'!'#245'e0'#208#140#132'C'#207#251'{'#210#241#156#13#196#248'T`'#143''''#8'>' - +'$'#0'J'#5#142#133#131')'#190#145')'#249'-+'#208#26#175#1'>'#25#8#247#13'(' - +#252#164#1#248#186#235#11#208''''#1#168'T*'#243'f{'#254#31#195'1'#197#25#236 - +#5'<'#1#152#10#166#176'D '#179'Y'#139#4#160'a'#4#192'f'#1'f'#144#4#200#14#244 - +'8'#26#135'~'#160'A'#192'RP'#9'{'#31#127#27'h'#141'y'#146#156#127#12#28'>}' - +#233#6'h'#173#251'E'#210'k'#208#155#242#225#16#18#254',u`f&@'#28'X'#243#15'J' - +#0'r'#187#3#204#7#208'F'#169#192#209#136#152#0#18#211#11'[^'#196#191#235'I'#3 - +'P('#20#219'"'#145'H'#3#222#223'>h'#2'@5'#194'R'#227'*'#188'>'#20'S^'#200'^' - +#192#11#184')'#127'"'#152#11#171#192'l'#210#128#209#160#3#165#138'k'#6#154 - +#201'>'#0#171'>~'#156#173#2'R'#129'Z?'#239#188#240'$'#152#177'gzK>'#135#27 - +#220#246'zh'#216#252#29#11#183#6'|.'#8#5#220#172'V_'#165#214#129'Zg'#2#173 - +#222#12'Fk)TN['#12'zsAZ'#207'MCY'#222#127'J'#186#134#160#244#190#14'9'#231'a' - +#166#25'f'#11#156#15#144'/'#7#14'F'#160#163'#'#192#178#1#219#182#254#143'/' - +#20#226#228'Y.KDP'#3'x'#149'R'#128#129#171#5'`'#233#192#184#136#183#187'\.ow' - +#147#130'z%'#0#170#3#192#23'['#234#189#197#151#6'"'#202'd'#23'F"'#1#131#181 - +#10#172'%'#19#193'd'#208#130#201#172'I'#154#0#178#12#134#210'i '#194#7'OH?' - +#158#219'd+'#133#165''''#252#31#232'-'#133'R_J'#198'A'#130']'#187#225'Kh'#218 - +#242#3'ks'#22#244#216#7'4'#135#143#134#148#26#172#197'P1u'#1#236#180#240#184 - +#180#9#206#215'o'#221#13'u'#191'~'#153#213#207#194'Z4'#30#14'<'#235'>'#188 - +#149#253'|'#17#166#1#160#249#27'@'#193'w'#185#209#4#240#5#161'}'#235#23#220 - +'c<'#1'('#229#241#224#164#188#214#127#226'M'#154#18'L'#234#255#214#190':'#3 - +#245'J'#0#227#198#141#211#6#131'Ak'#141#211'r'#182'/'#172'Nz;H'#208#245#214 - +'r'#176'P='#0#154#0'&'#147'6'#217#15' '#211'x'#253#158'c'#210'2'#201'v'#168 - +#160#228#163'Is'#15#129#185#251#159''''#245#165#164#21'm'#245#235#161'n'#195 - +'W'#208'^'#183#142#173#178#209'4'#142'B'#167#207#172#160'b'''#152#179#247#153 - +#144'W:y'#200#199#219#188#250'='#248#241#227'''3>'#168#149#186'/O'#158#127'8' - +#204#217#231#172#140#158#167'W$'#184#17'a'#1#180#253']'#164#1'x}`'#223#254#13 - +#255#16''''#207'*E'#204';)'#175#157#6'%'#146#218#207'4'#0#154#24'L#'#195#245 - +'z'#189#167#191#4#192#10#129#208'VPVVVjc'#177#152'e'#187#211'|'#162'7'#172 - +#185'+'#249#4'j'#9'f*'#5'['#201'4\'#253#181','#23'@'#165'Qr'#149#128#221#229 - +'j'#164#145#23#254#243#236#149',3,W@'#17#130'='#127'w5'#148'T'#15#207#190#252 - +'q$'#211#205'?~'#0'5'#235'>'#135#142#182#154'n'#11#174'2'#129#252#178#169#176 - +#232#152#27#217'H'#173'!]?'#10#255#143#31'?'#1'['#127#250#152#13'2M+'#240'w^' - +'>y'#15#216#253#176'+'#178#155#23#210#141#12'%d'#192'f'#3#4#252'!'#232'p'#5 - +#192#235'q'#131#163'ne'#138#3'P'#163#140'vT'#219#236'4'#187#190#129#132#159 - +'6'#165'RY'#135'2'#220'6h'#2#136'D"'#214#6#183#249'w'#238#144#238'!'#241#147 - +#180#166'b'#176#149#206'`y'#0'&'#139#142'M'#7'b'#29#129'2'#252#217#172#251 - +#250#31#240#243#127'_'#200#222#151#209'O'#20#148'O'#135'%'#199#222'<,B'#134 - +'^\'#217'7'#174#252#23#218#241#223#131#223#211'.Y'#145#13#249'T'#166#237'~$' - +#139#178#12#29'qX'#243#201'3Hd'#255'e'#205'C'#134#2#133#146#146#202#166#163 - +#224'_'#206#18'}r'#1'T'#13#24#141#198'P'#245#15#129#219#229#7#175#219#1#206 - +#134#31'S'#8'@'#167#140#216#171#172#246#143#128#215#0#168'"'#16#247#140#0#240 - +#182#183#187#138#192'~'#17'@'#179#199#184#175'3hxZ'#252'$'#141#161#0#242#198 - +#237#12'F'#163#14#205#0#29'k'#14#154#169'^'#0'b'#208'D'#222'7'#239#203#205 - ,#194#16#25#170#138';-8'#22'v^'#156#190#198#144#233'BG{'#29#252#244#233#211 - +#208#142'*~$'#228#151#250'rR`-'#154#0#251#159'y'#127#218'j1(g`'#195'7'#175'C' - +#253#198#175#193#215'A'#3#173#251'&8r`'#22'V'#238#12'Sw;'#2#138#170'fI'#253 - +#145#236#0'z'#7#17'j'#7#230#9#162#9#224#199#247#213#14#206#198#212#238#200'z' - +'U'#184#165#210#226#248#12':}'#0#228#4#172#29#18#1#144#9#208#234#209#237#209 - +#230'7'#254'#'#229#3#211'Z!'#191'b'#14#24'P'#253#183#152#245#172''''#0'u'#4 - +#202'F3'#208#127#221'w'#18#251#146's'#21'Z'#163#13#22#163'z'#155'?n'#154#212 - +#151#2#174#214#26#248#238#223#247#129#179')w'#204#166#238'@'#159#217'!'#231 - +#254#13#212#250#244#14':!'#19#193#217#188#21':Z'#183#129#27'I'#208#227'jfu"F' - +'['#25'X'#11'+Y'#178#151#165#184':'#183#11#193'X'#166#31#215#11#192#235#13 - +#176'('#128#199#209#12#238#150'u)O3'#170'C'#141#21#22#215#127#249'N@d'#2'l' - +#29#148#9'@'#155#216#9#232#244#171'f6z'#172')'#241'7'#133'J'#7#5'U'#187#131 - +#193#160#1'3'#154#0':'#150#11' '#239#182#31'X'#186')'#225#203#127#222#153'u' - +#15#240'`0e'#215#195'a'#222#129#210#12#177#8#251#221#240#217#203'7'#131#163 - +'i'#147#212#31'C'#191'A'#5'Y'#135#156#255'(k'#135'>'#154#209#157#190'B'#9'pa' - +'>'#9#168#3'M'#0'w'#251'v'#240#218'S'#167'#Y'#180#193#154'2S'#7'y'#6#27#248 - +'$ F'#0#209'ht@N@BJ'#24'P'#169'R'#149'nh-'#250#2'_'#165'I>'#3#5#189'p'#194'"' - +'$'#0#29'X'#172'z'#208#27'5'#172'5x'#159'y'#0'i`'#131#230'mk'#224#211#23#174 - +#207#202#151'1T'#152#11'*'#224#128#179#238#205#170'o`'#235#154#255#192#202'w' - +#31#206#154'C/'#157#160'<'#130#163#174'x!mSv'#135#5#250#180'P'#184#28#128'`0' - +#2#30'w'#0#220#168#1#184'Z6@'#160'#5)'#174#208#224']W'#160#247#253'D'#137'@d' - +#2#240#142#192#186'A'#135#1#137#0#240#133#164#147#21'ov'#20#191#30'K'#200'''' - +'$'#159#129#4#144'W1'#15'L'#22#27'j'#0#6'V'#19#160#226'C'#129']'#223'O&'#140 - +#130'W'#238'8l@'#241'h)A'#177#240#189'N'#184'%+'#145#130'O'#158'_'#14'-5'#185 - +'99'#167#191#176#20#141#135'C'#207#127'T'#234#203#144#4'='#5#209'('#2#16#12 - +#132'Q'#248#253#168#5#4#192'Q'#207#149#2#139'Qnv'#174'D3`'#19'%'#255#8#26#128 - +#144#8#132#154#128'o'#192#4' '#164#2#227#193#138#183'8'#10#30#12#199#20#139 - +#196#151'E]'#129','#249'e`'#178#234#192'd'#212#129'ZC~'#128#236#204#5'x'#239 - +#209#11#192#217#178'-+'#231'J'#23#166#237'q$'#204';(}'#195'#S'#128'6'#226'{' - +#127#191'h'#216'}&=a'#194#236'}a'#193#145#185'7'#1'X'#10'P'#18#16'E'#0'('#4 - +#200#17'@'#16#218#183'}'#3#177'h0'#229'y'#19#243#218'>U+'#226#164#254#215#163 - +#224'3'' j'#2#245#129'@'#192#142'f'#128'w'#208#181#0#248'wQ'#141#211'v'#173 - +'?'#162'Jq'#191#27#242#171#217#20#27#179'Y'#159#12#5#210'x'#176#158'k'#12#211 - +#247#161#172#253#244'yX'#251#249#138#236#127#27'C'#196'n'#135']'#12'Sv;<'#189 - +#7'E'#251#240#237#135#207'cN'#174#145#3#25#28'~'#201'c`)'#172#146#250'B'#178 - +#131'^'#204#0'j'#6#18#165'n'#192'>'#206#254#247'z'#252#208#182#245#139#148#16 - +#160'\'#150#136'N'#201'o'#249#8#5#159#194#30'uB'#30#0'nD'#8#246#129#214#2'$' - +#203#129#241#128'fd'#143#194'F'#143#229#20'wH'#151'B'#201'ZS'#9#228#143#155#1 - +'&'#179#14#204'V=h'#132#178#224',('#1'>W'#11#188'q'#239#169#153'?Q'#154'AYeG' - +']'#189#2't'#166#244#21#21#189#247#247'K'#192#222#176'q'#232#7#202'1'#152#242 - +#199#193#17#151'?#'#245'eH'#10'a&'#0#245#1#240'y'#3','#7#192#237'p'#160#9#240 - +'Cj'#18#144'"'#234#169#206#179#127#129#247#181#161#204#210'J'#192'f'#3#12#182 - +#28'8'#165#31#0#218#15#133#142#128'ai'#139#215#248#160#248'Ij'#141#5#10#198 - +#207#3'#O'#0','#18#160'R'#176#142'A'#137','#12#7'}'#233#214'Cr"-x'#160'`?' - +#236'+'#158'K'#203#177'H'#19#250#9#183#145#138'='#143#184#10'&'#205#31#157 - +#163#208'9$ '#30#163#8#0#239#0't'#250#193#213#214#0#238#214#245')'#4#128#182 - +#127'K'#133#197#245#3#222'l%'#199#31#240#229#192#168#193#147#167'pp'#13'A' - +#168'%'#152#223#239'7!'#131#20'D'#19#170#201'['#157#133'o'#136'_'#163'P*'#161 - +#176'z1K'#6#162'H'#128#206#168'ERP'#246'/'#23' '#13#252#240#206#131#231#177 - +#24#239'p'#196#188#131#207#131#25#139#143#27#210'1'#236#13#191#193'{'#127#187 - +'(g{'#229#165#3'r'#133#18#142#185#246#21#208#26#173'R_J'#250#209#143#175#141 - +'u'#2'B'#251#159#28#128#140#0'P'#3'p6o'#1#175'c[J'#6'g'#158#206#191#173#200 - +#224#166#196#128'VJ'#254#17'z'#2#146#6'0'#232#150'`BO@T'#31#10#240'GV'#190 - +#201'Q'#242'J}'#246'F)'#191#167'A'#129'j'#227#207#184 - +#251#179'A'#189'6'#28#244#195#138#27'G'#167'c'#172#176'r''8'#248#194#7'Xr' - +#213#136'@'#143#250'?O'#0#188#253'O+'#191#199#229'C'#18'p'#130#189'v%'#211#12 - +#4'('#229#177#224#228#252#246#175#240#249#2#1#212#0#231#4#164#209'`-h'#198 - +#187#131#136#1'M'#6#18#15#7#141'F'#163'6'#180'%J'#28'~'#221#190'->'#243#29 - +#226''''#170#212'z('#172#222#19#140'&'#29#152'mD'#0'\B'#144#208'&<'#27'j'#192 - +#11#215#31#8#145'P'#250#26'Wd'#3#244#3'>'#253#174#143#7#245#218'_'#254#251'*' - +#172'|{'#244#14'DUi'#13#176#223#153#127'd~'#148#145#138#4'_'#0'D'#241#255#160 - +'?'#4#30#180#255#189#184'9[j'#192#221#250'['#138#227#215#160#14#219'+'#204 - +#142#213'('#252#14#138#251#211'<'#0'>'#19#144'*'#1'['#7'3'#28#148' G'#155#129 - +'U'#4#250'|>'#139'F'#163')'#142#199'a'#194'F{'#225#243#137#132','#217#29#129 - +#170#168#24#1'X,'#204#15'`'#160#210'`'#230#7'P$'#29#129';'#156'-'#205'N'#235 - +'_'#191'z'#19#190#249#231'_%'#249#162#6#11's'#193'88'#230#250#193#141#147#254 - +#247#131#23'@k'#141#180#141'1s'#1'TA8m'#193#239'a'#206#1#167'g'#181'G_Z'#209 - +#131#134'L+<'#133#255#200#254#15#160#253'/'#16'@{'#221'Z'#8#186'[S'#8#160#208 - +#224#221'R'#160#247'Q'#185'g;'#17'@'#127#235#0#196#167#239#14';d'#3#226'V' - +#185#197#158#255#167'PL1#'#249'$'#20'rK'#241'N`-'#174#0#147'U'#143#4'`'#0#173 - +'A'#13'*%'#154#1#138#204#205#10#236#138'Wn;'#10'|'#206#214#236#156','#13#152 - +'0go'#216#231#140#255#27#212'k'#159'_~'#0'D'#130#185'U'#211'/%'#168#15'C'#233 - +#164']'#160'z'#151'}'#161'j'#230#226'a'#31'2dFz'#156'S'#255'#A'#222#254#167 - +#30#0#184'o'#222#252#5#196'#'#225#20#2#24'o'#181#175#210#169#162'-x'#179#29#6 - +#144#5#200'>'#187#222'>W'#241't d'#146'B4'#5'*'#154#188#182#179#221'!'#237 - +#209#201'''Q'#131'PK)'#228'W'#206'dQ'#0#163#197#0':'#147#150#21#6#201#149#217 - +#233#15'@h'#217#250#19#252#251#129#225#227'%^t'#194'r'#152#186#231#224'R'#130 - +#159#185'b'#201#176')'#132#146#2#148';'#160'3'#231#225#162'4'#30'J'#170'g' - +#195#196'y'#251#131#9'5'#174'a'#131#4'7'#9#184#211#254#199#213#159'e'#0#182 - +#131#189#230#7'6"L'#144'c'#133'<'#30#153#146#223#246'5'#10#186#7'e'#141'V@' - +#178#251#5#2'h'#196#197#219#217'S'#18#16#161'W'#2#16'&'#4#163#253'o'#212#233 - +'t'#249#241'x'#188#188'#'#168']'#220#232#177#220#156'|'#18#10#184'R'#163#131 - +#226#137#11#153#31#192'h3'#128#158#18#130#180#252#184#176#12'N'#12#238#138 - +#183#239#251#3#180'n'#27#218'l'#192'l'#225#212'?'#127#0#154'A6'#191'x'#242 - +#210#133#144'v;j'#132#131'HAo)'#128#252#242')P>mw'#152#186#224#240#156'4'#27 - +#216#234#159#224#212#255'('#170#255'd'#255#147#240'3'#251#191'y+'#218#255#155 - +'Xn'#128#0#163':'#212'^aq'#145'='#216#129#178#216#140#143#17#1#176#8#0'.'#220 - +#212';'#189#199#193#160#132'>'#9'@'#28#10#196#251#202#240#160#213#155#28'%' - +#143#196#19'2'#29'{'#18'k'#5'.'#135#194#9'{'#128#201'f'#227#205#0#174'.@AZ'#0 - +#171#14#236'>)'#168#219#147#14#225#195#11#184#29#240#210#141#135#231'|^@~' - +#197'T8r'#217#179#131'z-E'#0#158#191'f_'#169#223#194#176#135'J'#171#135#165 - +#167#222#2'U'#179#150'd'#252'\'#253#253#221#211#243'h'#177#140#199'x'#245'?' - +#20#129#128'7'#136#194#239#227#226#255#219#127#132#128#167'-%'#2'Pd'#240'l' - +#201#211#249#182#163#28#186#144'8'#154#132'$ '#218#227#202#223'b0'#24'X'#8'p' - +#221#186'u'#20'7'#140'ww'#222#30#175#137'"'#1#223'}'#247#157'*'#16#8#232#208 - +#20#176#161#9'P'#138'D0~'#155'3'#255#250'`T9C8'#4#249#1#172#165#211'Q'#229 - +#170#2#163'@'#0'z'#13#168#132'h@'#182'T'#0#196#202#127'='#12'k?z1k'#231#27'(' - +#232#179'8'#254#246'7'#192#152'W:'#168#215#7#189'Nx'#241#218#209#25#2#204#4 - +#138#170'g'#194#129#23#220';hm,'#221'`'#222#127'Z'#253#163'Q'#8#163#250'O' - +#246#191#151'%'#0#249#161#5#237#255'h'#23#251#191#218#214#190'J'#173#136'R' - +#248#207#129#127'6R'#8#144#239#7'H'#154'@k$'#18'q{<'#158'Pw!@B'#175#4'@'#155 - +#16#9#160#230#160#212#23#0#239#171'j'#246'ZNv'#5'uG'#8'O$'#2#208'['#202' ' - +#175'b&'#18#0#154#1'f'#3'W'#23'@'#141'B'#217#200'0'#25'd'#205#14'@'#188#255 - +#224'%'#208#176'ae'#214#206'7'#16'L'#156#191'?'#236'}'#214#29'C:'#198#147#23 - +#238'.'#245#219#24'Q '#243'`'#223's'#239#204#138'6'#208#27'HB'#168#244'7'#30 - +'E'#2#8#161#250#31#8#129#223#205#169#255'n{+'#180'o_'#197'Z'#131'u'#14#2#137 - +#133'&'#229#181'}'#143#194#239#195'?'#237'|'#8#144#217#255#168#181#215#247 - +#214#12'T|'#206'^?'#27#161'3'#144'^'#175'7'#1#31#9#240#132#212'{'#214'uX'#151 - +''''#15'"''?'#128#22#138'''.b'#171'?e'#4#234'L|8'#144#175#13'`'#166'B'#22'?' - ,#204'Wo>'#10#220'm'#245'Y'#3'p;'#202#27#253#221#209'S'#17#144#128'~'#17#0#213#4'x<'#30 - +#180#2#244'Vr'#4'"'#17'T5{'#244'G8'#2#198'dA;'#9#184'Zg'#132#162#137'{2'#2' ' - +#13'@'#199#178#2'5'#172'6@'#208#2#178#146#27',B'#243#230'5'#240#254'}'#23'B4' - +#18#202#234'y'#197#216#237#168'K`'#246'Ag'#164#237'x/\'#181#31#174#6'C'#155 - +'~3'#134#238'A'#157#154'N'#185#247#163#172#159#151#171#252#227#212#255'p0'#12 - +'Ao'#144#9'?'#173#254'T'#244#229'j'#222#200#156#131#130#253#175'VD'#253#19 - +#243#236'?'#226#223#148#17#230'@'#18'`'#14'@'#222#254#167#134' }:'#0#9#253 - +#145'F9'#146#128#18'I'#128#210#127#205'h'#10#20'#'#9'T'#198#19#138')'#155#157 - +#133#183''''#18'2V'#149'A'#194'M'#13'B'#10'*'#231#161#25'P'#8#6#19#18#0#211#2 - +#136#0'T'#160#16'*'#4'3gK'#198#223#195'h'#197#180'%G'#193#226#211'o'#202#206 - +#201#184#170#31#142#0#248#216#127#208#23'd'#130#207#212#127#167#19#9#224';' - +#212#12'"b'#251'?1)'#191'}'#21#170#255#228#8'"'#251#159#26#129#214'R'#248#15 - +#23'h'#234#1#208#136#194#239#232#203#254''''#244'G'#10#153'#'#16#15#166'"?'#0 - +#10'p>'#158#168#140#252#0#206#128'vi'#179#215#194#21'h'#147'#PFf'#128#14#205 - +#128#5#140#0'H'#3#224#162#1#252#244'`j'#24'*'#151'u'#27#17#200#240'P'#225'$' - +#26#127']'#9#31'>|%D'#130#190'L|'#157'L'#203#153#186#232#8'Xr'#234#13'd'#23 - +'e'#228#28'O'#253'a7'#246#131#24'Cf`*('#131#19#239'zw'#200#199#233#235'7-<' - +#206#21#254#196#208'LE'#2' '#231#31#18'@'#160#131'['#253#157'M'#155#192'M' - +#222#255'h4'#169#254#235'U'#225#142'J'#139'c'#29#202'Q'#0#239's'#1#215#4#164 - +'V'#176#255'qk'#17#154#128#160#240'G'#249'S'#13#158#0#186#250#1#144'eJ'#240 - +'~'#234#215'\'#189#201'Q'#180'<'#22#151'S'#136#144#17#0'e'#255#217#202'g'#130 - +#185#176#140'#'#1'3o'#6'h'#133#204#192#206'nA;'#148'Bw'#185#154'L'#182#186 - +#219#248#191'7'#224#199'w'#159#2'O['#250'Zj'#149'M'#155#15#251'^xOF'#139'Q' - +#234#214'~'#9#31#220'?z:'#1'I'#1'J_?'#231#137#31#134'D'#224#221')'#184']'#127 - +#207','#251'/'#193'y'#254#185#213'?'#138#230'j'#136'y'#255'I'#253#15'P'#243 - +#143'-'#223'@'#200#239'I'#137#255#151#24#221'[l'#186#0#165#249#250#241'>'#150 - +#0'$'#148#0#227#177#234'PKo'#235#143#253'/\C'#127#192#252#0#168#5'h'#220'n' - +#183#5#217#165#8'OXIf@'#131#219'r'#130';'#164#221#141#29#140#198#131'+'#20 - +#172'8('#175'j&o'#6#232#144#0't'#160#210#169#147'Z'#128#16#17#200#5'8'#27#182 - +#194#183'/'#255#5#26'~]'#201#134'F'#14#4'T'#133'f-'#29#15#19#230#239#15';' - +#239#127'2h'#12#153#207'&{'#239#238'?@'#195#250'o'#165#250#184'F'#13#246#189 - +#240'n'#168#222#245#128#140#158'#!'#168#255#148#249#23#137'B4'#200#169#255'd' - +#255#7#220'T'#252#211#10#142#237#171'!'#134#143#197#249#231#202'e'#137#216 - +#228#252#182#213'2'#136#7#248#248'?9'#131'X'#252#31#229#170#6'o7'#160#156#182 - +'['#173'V__'#246'?'#161#223#4#128'f'#128'\'#156#15#128#251'rd'#155#9#193#152 - +'v'#238'v'#151#237'\v02'#3'P'#184#149#26'5'#20#146#25'`6'#161#9#192#145#128 - +'Z'#199#229#4#144'/@&'#242#5#236#176#234#15#225'"'#135#2'R'#177#234'~'#254#10 - +#26#214'}'#11'm'#219#214'1'#205#128'&'#203#138#175#130'VvKq'#5's'#16#149'M' - +#159#15'e;e?#'#239#233'sw'#131'hX'#186#136#198'hA'#213'.K'#225#192#203#31#24 - +#212'k'#251'j'#132#155'L'#250#137'sC?c'#164#254#211#234#31#8'A'#136#188#255 - ,'l'#245'G'#245#191'a=x'#237#245')'#225'?'#179'&'#216'^fr'#209#196'W'#26#11 - +#228#22'*'#0#137#0#132#30#128#129'@'#192#137#230'z'#159#246#127'w'#215#214 - +#227#243#132'|'#0#178#1#168'0('#26#141#150'Q8'#16#31#155#176#197#145#127'a8' - +#166','#226#252#0'\4'#192'R6'#13#204'EU,$H~'#0#202#9' -@'#201#198#135')'#144 - +#4#184#196#160#28'Q'#4#134#5'>z'#248'*'#216#246'}'#246'CT'#163#17#182#242'Ip' - +#236#31#223#200#216#241')'#233''''#17#3'V'#214'M+'#249'C'#250#15#156#224#226#254'@'#158#255'8'#231#249#143#6#195','#243 - +#143#169#255#168#250#19#9#216'kV'#163#25'`gY'#172#130#250'o'#211#249#27'K' - +#140#30'R'#247#131'|'#250'/'#27#3'F'#241#127'R'#255#169#1#8#154#19#142#190 - +#242#255#197#24#136#228'%'#195#129'V'#171#213#24#12#6#169'Sp'#25#17#0#238#171 - +'j'#156'yg'#4#162#170'*'#193#12#160#162#10#163#173#4'l'#21#179#144#0#180'<'#9 - +'hy_'#128#154'9'#3#169'T'#24'dBX'#176#135#14#194#144'$'#205'~^e'#250#191'3)A' - +'~'#136#215#151#31#1#174#198#209#212#2'\zP'#133#224'9'#207#241'c'#214#135#26 - +#141#226#139#253#19#252#129#216#234#207'l'#127#170#250#139#176#208#31'9'#255 - +'H'#240#131'H'#0'>G'#27'8jWC$'#28'I'#241#254'O'#176#182#175#213#170'b'#30'R' - +#255#241'O'#23'5'#0#1#222#254''''#239'?'#223#16#164#163#183#6' '#221']Z'#191 - +#223#134#16#14#164#254#0#248#183#21'U'#13#150#21'H='#2':'#130#186#5#141#30'3' - +'+'#17'f'#177'~'#185#2'Tj5'#20'T'#239#10'z'#139#141'E'#2#136#0'4d'#10#176'f!' - +'*'#166#5'0_'#128#140#159'(<'#194#132'w'#168#160#130#159#215#151#253#14#127 - +#16'cI?'#217#134'B'#165#129#179#158']'#157#222#131#242#131'>'#133#142'?'#204 - +#246'G'#2#8'3'#225#231#9#0#247#142#186#159#192#239'la'#142'iA'#253#215#169'"' - +#238#241'V'#199#175#188#250'O'#9'@'#164#254#179#240#31'%'#255#144#250'O'#225 - +'?\'#160'='#253#9#255#9#24#16#1#208'&'#152#1#8#19#153#1#148#21'H'#4#128#143 - +'Umu'#22#156#25#142')'#11#133'.A'#20#247'7'#228#149#129'm'#220#206'I-@C$@CDY' - +#179#16'!/'#128'F'#137'e?E8'#151'AQ'#136'7'#174';r'#172#234'O"'#168'tF8'#227 - +#201#244#246#148#16#135#253'('#238'O'#158#255'H'#16'U'#127'"'#0#15'n>'#170 - +#254#179#163#250#191#10#205#189'0'#243#15#8#234#127#185#217#185#193#168#14 - +#145#211#143#169#255#192#13#1#173#23#17'@'#147#160#254#163'lF'#250#10#255#9 - +#24#168#196'13'#160#176#176'PE#'#195#168':'#144#6#134#224#133'T'#145')'#224 - +#10#234#23'4{'#205#7#2#175#210'S'#21' '#211#2#198#239#14':'#139#5'4F'#29's' - +#10#170#13'|'#207'@'#181#138'=G!'#231'g'#9#202#248'K'#234'O'#154#224'`'#223 - +#193'0@'#235#166#159#224#223#183#159'6,'''#31#143#20'h'#205'yp'#234'c_u'#255 - +'`_b'#213#205#239#151#21#251#240#163#190'H'#176#227#201#213#191#211#249'G' - +#171#191#179#254'g\'#253#155'8'#231#31#175#254'k'#149#17#239'x'#171'}='#10'{' - +#132#138#127#200#251'O'#237#191#240#200#181'|'#2#16#169#255#164'&v'#168'T' - +#170'`w3'#0#251'{'#169'}>_0'#3'('#26#128#127'['#168'K'#16#158#188#130#8#0#168 - +'m'#184#179#240#244'HLa'#21'j'#3#148#168#234#27#243#202#193':n:'#168'Q'#11 - +#160#193'!D'#4'j'#22#18'$'#18'P'#240'aA9?V|'#16'W5'#130#176#229#235#247#224 - +#243'G'#174'a'#182#223#24#164#3#133#1#143#190#251#157#244#28#140#15#252'S.' - +#127'"'#202#175#254'h'#223'G'#130'a^'#253#15#176#172#191'@'#135#19'W'#255#239 - +#185#213'?'#130'$'#193'1'#7#140'3w'#252'f'#214#4')'#244#23'F'#185#242#240#201 - +'?'#228#253#167#240'_'#13#202'"'#205#4'l'#31#136#247'_'#192'`D-'#165'8'#8#184 - +#193#161#204#25'H'#154#128'#`X'#208#234'3-'#21'F'#131#145'3P'#169#209'@'#225 - +#132#221'@k'#178'0'#19#128#242#2'Th'#6#8'Z'#0#171#20'Lv'#16#150'%'#157'&'#253 - +'m$:R'#176#254'?+'#224#235'g'#239#200'l'#14#244#24#250#133#233#251#159#8#11 - +#207#186'eP'#175'M'#249#221#242'!?'#230#253#143'q'#5'?'#156#237#31#134#8#31 - +#250#163#212'_'#218';'#27#214#129#223#209#8#209'H$'#25#251#215'('#162#254#9 - +#182'v'#234#250'K1}'#10#3'Q'#247#223#22'~'#213#175#193#191'k)'#249#167#175 - +#246#223#189']'#235#128#223#159#208'-'#24'm'#13'='#178#143#141#204#0#188#191 - +#146'i'#1'2Y'#229#22'{'#193'I'#145#184#194#196'r'#2#228#10'P'#170#149'`'#200 - +#175#2'k'#233'T\'#253#181'H'#2#168#5#232#185#196' V)H'#179#4'),'#168#232#140 - +#10#176#19#245#148'" zk'#178#228'?'#195#27#171'^{'#8'V'#191#254#176#212#151 - +'1'#6#30#135#223#186#2'J'#166#207#239#246#177#148#223'_/'#191#189#4#223#232 - ,'#E'#245#167#213'?'#24'a5'#255#17'?'#231#252#11#177#216#127#7#180'o['#9'Q$'#6 - +'z'#14#181#6#163#215#149#153':'#182'X'#180'A'#154#248#19#225'{'#255#145'&@+>' - +#9'>'#133#255#234'q'#223#170#211#233#220'='#13#0#237#13#131'"'#0'J'#10'B'#150 - +'a'#205'B'#3#129#128#153'J'#132'c'#177'X'#5'e'#6'rZ'#128#17#181#0#227#158#130 - +'3'#144'T|'#138#255#231'O'#216#3'W'#127#19'G'#2#212'4T'#207#151#10#147'CP' - +#221#233#16#148#241#166#128'l'#7#233#30#204#202#152#251#236#240#213#147#183 - +#192#175#31#189','#245'e'#140#129#7#253#6#207'~'#249#215#129#190'Jt;'#145#12 - +']'''#189#254'd'#207'Gx'#199#31#173#254#254'P'#210#251'O{W'#227#175#224'u' - +#212#177'~'#0#148#31'@i'#194'jE4Pmk'#251#5#229'!'#138#199#160#252'o'#15'nT' - +#250'['#207''''#255'lG'#217'#2p'#244#167#246#191#175#171#30#208#187'%g'#160 - +#201'dR'#163#218'a'#196#191'Yj0'#229#3#224#237'*|'#175#228#11'8>'#154'P'#232 - +#153'3'#16'Ww'#188'P0'#20#146#22'0'#133'9'#1'Y8'#144'6=_)H)'#194'h'#6'P'#18 - +#145'L('#22#202#206'lQIa'#175#217#0'o.'#251#157#212#151'1'#6#17'J'#166#205 - +#135#195'n'#127'iH'#199#232'n'#245#143#161#240#179#184#127'0'#196'9'#255'|A' - +#206#1#232'qC{'#205'w'#168#25#132'x'#207'?'#183#250#151#24#221#219#172'Z'#127 - +#155#200#249#151','#253'%'#225'GY'#169'C'#185'k'#182'Z'#173'.'#148#195#192'@' - +#156#127#2#6'M'#0#130'3'#16#153'G'#231'r'#185#200#233'W'#140#23'T'#1'\'#153 - +'pe'#155#207#184#208#30'0'#206'Kj'#1'H'#2'*'#141#22#242'(='#216'bE'#2#208'$' - +#137#128#180#3#133'P($T'#11#138#251#6#140'`'#22'x'#251#250'c'#161'u'#211#26 - +#169'/c'#12'"'#28'q'#215#155'PP'#189#243#160'_'#207#249#252'D'#141'>H'#168'#' - +#188#227'/'#192#173#254'L'#248'}AF'#4#174'z'#180#253#157'h'#251'S'#211#15'z.' - +#190'T%'#139#134'&'#230#183#255','#227'l'#255#16#18#0#139#253#163'l4'#144#240 - +#227'mr'#0#178#206'?]b'#255#253'V'#255#9#131'&'#0#232#146#19#128#23'H'#163 - +#195'h'#0'[%nU1'#210#2#28#133#199#198'P'#180#217#160'p'#210#2'P'#192'u'#150 - +'"'#176'U'#204'fu'#1'I'#2'`'#14'A$'#1'V.'#204#153#2#192'L'#7#254#242'Fh'#170 - +#176#223#217#10'/'#159#183'p'#204#233#151'C0'#20#148#194#9#127#255'b'#208#175 - +#151#241#169#190#204#8#136'w'#198#252#185#130#31'A'#245#199#205#31'`'#197'?' - +#1#23'e'#253#173#225'<'#255#209#206#213#191#216#232#169#177'i}'#173#252#234 - +'O'#153#127#212#5#150'B}'#245'T'#246'KN@Z'#253#145#0#156'~D'#127'S'#127'w' - +#184#222'!|V'#201#10'A'#179#217#172'#g '#222#199'B'#130#184#175#162'=j'#1#11 - +#218#253#134#185#204#169'Ge'#194'D'#2'j'#13'X'#199#205#0'}~)S'#255#213#6#29 - +#211#6'Tz'#13#31#22#228'{'#6'$'#253#1#248#142'd'#217'm)'#158'-|'#244#231's' - +#161#246#135'O'#165#190#140'1'#136'p'#240#205#207'C'#217#172#133#131'|5'#159 - +#236#203#219#253'B'#177'O'#156#217#254#188#234'O'#4#224#193#149'?'#192#217 - +#254#142#237'?@'#200#211#193'&'#1'1'#2#192#255'T'#242'hp'#162#205#142#182#127 - +'"'#202#135#254#216#234'/'#196#254#129#235#250'['#143'2'#215'N'#206'?'#170 - +#252#235#173#243'oo'#24#18#1#144'3p'#221#186'u'#172'QH '#16'0'#161#6'P'#128 - +#23'Im'#195#153#22#128'W2n'#155#179#224#247#225#184#202'"h'#1#148#2#172#209 - +#27#208#20#216#13#212#148#19' '#242#5'(u'#184'Qr'#16#159#27' h'#2'2'#161#157 - +'xOq'#193#158#222'E'#142'/'#172#207#158#176#19#174#12'c'#181#253#185#130#202 - +#249#251#192#254#215'='#193#253'1'#136#223#148'X'#248'i'#229#135'8'#151#238 - +'K'#142'='#177#227'/B'#234'?'#222#246#180#214#128#167'e'#243#14#171#127#185 - +#197#181#209#168#10'R'#184#143#250#190#177#208#31'n'#173'(_'#245'|'#209#15'%' - +#0'5S'#230#31'j'#224#254#193'8'#255#4#12'uYMf'#6':'#28#14#189'R'#169#180#225 - +'E'#22#227'F'#137'AL'#11#240#133'5'#211#235#220#182'}'#4'-@'#193#180#0'5'#24 - +#11''''#128#185'x"'#175#5'p$'#192#180#0#161'u'#24#223'>'#172#147#4#248#203#29 - +'A'#138#192'sD'#0'c'#21'~9'#1#26#22'z'#242#243#171'Q'#251'T'#15#238#0#188#25 - +#215#185#242#243#170#127#152's'#252#145#131#143#179#253#3#16#246'"'#17'x=,' - +#233''''#18#12'B'#140#250#253'E'#185#196#31#20'|G'#133#197#181#5#15#21#19'V' - +#127#161#237#23#169#253#192#245#252'k'#224#203'~'#221'}'#245#253#239#11'C&'#0 - +'A'#11#160#182#225#168#9#144'/'#160#0#137#128#249#2#144#8'H'#19'(k'#240#216 - +#246#246#132#181#149'r'#150#29#168'`5'#0#10#10#11'V'#206#3#141#201#10#26'#g' - +#10#168#146#17#1'5'#243#7#176'b!'#218#152'#'#145'+'#27#30'I'#166#192#138#211 - +'v'#129#144#215'%'#245'e'#140'zP'#225#218#161'w'#188#10'E'#211#230#13#234#245 - +#9#174#212#143#247#250#199#217'l'#191#4#223#230'+'#30#140'$W'#127#138#251'3' - +#199#31#222'v5'#252#2'AWK'#202#234'/C'#218#168'F'#213'_)'#143#134'zZ'#253#5 - +#207'?n'#142#254#182#253#234#245#189#167#227#243#19#215#7'h4'#26#214'4'#148 - +'O'#15#166#188#128#242'h\^'#177#213'Yxp'#2#215'uA'#11'P'#168#212#160#181#20 - +#176'ra'#181#174'S'#3'P'#11'Z'#0#229#6#8'Q'#1#190#155'0'#136#202#134'G'#130 - +'_'#240#213's'#22#130#175#189'Q'#234#203#24#213#160#197'e'#191#27#158#132#10 - +'T'#255#7#140#132'x'#166#31#231#244'#Afv?'#173#252#225#8'K'#250#137#6'B'#172 - +#221'W'#132#247#250'S'#165#159#139#154'}'#160#240#211' '#16'a'#245'/'#212'{' - +#234#10#244'>'#10#243'u]'#253'i'#236'7'#181#253#222#142#130#223'@U'#127'H'#8 - +#238#129#230#253'w'#251#254#211#241#25'v'#213#2#240#194#10#132#136#128#160#5 - ,'8'#2#198'9'#173'~'#211'l'#210#2'@'#161'`'#14'A'#5#154#2#150#178#157'@'#159 - +'W'#202#146#130#152#240#147#22#160#227'H'#128#181#15'S'#241#237#196'EY'#130 - +'2y'#186'.]Z'#252#235#210#3#193'Y'#187'Q'#234#203#24#189#192#223#210#146#203 - +#255#10#19#247#26#194#236#6#22#231#7#214#224#143#229#250#243'N'#191'X'#132#19 - +#254#8#175#250'G|'#156#6#16#246#243#142'?'#159#155#21#4#9'q'#127#149'<'#26 - +#168#206'k_'#143#199#139#241#171'?y'#254'Y'#213#31#173#254#184#175'U('#20#181 - +#180#250'k'#181'Z'#7#146#192#144'W'#127#246#17#164#235#163#236'N'#11' _'#0'p' - +#17#1#26'$R'#180#213#153#191#127'8'#166#178#10#217#129'$'#220'j'#189#145#229 - +#6#168#13'z.)'#136'O'#17'V'#178#220#0#222#20'`'#141'D'#249#14'Bra'#196#24'$' - +#213#128#225'J'#5#31#222'r24'#174#249'R'#234#203#24#149' '#13't'#191#27#159 - +#134#178'9'#139#7#252'Za'#213#231#179'}x'#187#159#19'~Z'#209'i'#245#143#133 - +'"'#201#176#31#229#252'GI'#248'q'#239'i'#217#10#222#214'm'#140' '#152#237'O9' - +#255#248'_'#165#217#177#193#160#14'S'#166#31#9'4y'#134#133#145#223'Md'#251 - +#147#240#163'L'#213#167's'#245''''#164#141#0#186#243#5#0'7H'#180#146#15#13 - +#150#249'#'#234#9#181#238#252'%l'#29'Wt'#154#2#134#252'r0'#151'N'#229'j'#3 - +#152#6' r'#8'R'#247' '#149#146'+'#24#18#154#137#178','#193#225#239#24'l\'#243 - +#5#252#231#230#147#165#190#140'Q'#7'CA'#25#28'~'#223#187'h'#130#230#15#252 - +#197#157#195'y:'#139'|'#226#156#205'O'#182'?'#173#234'L'#245#167#132#31'a' - +#245#199'-'#26#8#254#127'{_'#22'kYv'#158#181#246'x'#230's'#238'XsWwW'#187#219 - +'v'#187#227')'#241#0'v'#136#193#145#8#194'F'#8#5#148#4')'#145#176'P'#132#132 - +#20#241#18'!9'#188#0'/H'#188'!'#224#1'x'#2#9#17#144#128'XHH$`x'#128#7#144#172 - +'$'#216#198#221#158#186'k'#174'[w:'#243#176#7#254#239'_'#255'Z{'#237'}'#207 - +#173#186#213']w'#170#190'K'#218'w'#15#247#12#251#236#189#191#239#159#255#165 - +#166#253'='#181#243#222'wT2'#155#209'k'#23'\'#25#8#159'A;'#158'n'#223#232#238 - +#161#229#19#192#159#152#184'?:'#254#162#230'_'#233'Y'#127'n/'#145#254#0#255#7 - +'*'#27'}'#158#208')E'#4#136#173'V'#137#165'.'#139#22#128#174'A'#215'Q:|o'#208 - +#251'b'#127#214'x'#153'+'#255'B"'#129' d'#144#247#174#146')'#176'zUH@'#8#160 - +#225#248#3#184'V@'#155#2'l'#14#248#158'T'#15#150#127'I'#158#23'?'#201#243#206 - +'x'#28#144#198#191#254#181'O'#169#217#197'D'#159'''3'#232'ay'#245#203'_S'#191 - +#240#219#255#248'H/_'#250','#229#198#225'/'#137'>'#22#252#186#208''''#227'2_' - +'m'#247'c'#129#218#191#24'C'#19#152'p'#155#175#249#184#207#182#191'Q'#253'=z' - +#247'k'#171'['#127#28'x)'#138'}JY'#127#180#127'_<'#255'h'#251'u'#239'yK'#127 - +#254']'#207#243#242'.'#203#11#160#31'q'#21'~'#0#163#5'dyp'#229'G{'#27#191#152 - +#229'~'#13#0#246'E'#11#136#234#13#181#242#210'gT'#173#211#213'&'#128#144#0 - +#182#131'Z'#173'0'#5#196#31'P'#174#28'<'#191'Z'#192'w'#254#229'?P'#127#244 - +#187#23'U'#128#199'=z/}D'#253#153'o'#254#11#213#189'~'#235#253#127#8'W'#248 - +#228',ssW'#242'['#187#159'l'#250#217'\K'#127'V'#253#167'"'#253#231'j'#255#222 - +#247#213'd'#239'>{'#253'a&(N'#249'e'#199#223'{'#235#205#17'z'#251'C'#250#163 - +#3#12#247#251#163#5'Y'#128','#253#197#7#240'p>'#159#239':'#158#255#15','#253 - +'1'#158'7ll'#227'Pd'#7#146#22#128'9'#178'.!'#18' Q'#1#172'/'#239'Oko'#220#31 - +#174'~'#206#19#135#160'1'#5#226#246#138'Z}'#233#211'l'#2'@'#250'G-q'#8'J'#243 - +#16'?'#150'Ta3'#211#176';'#229#184#167'='#186#207#214'A'#244#244'G'#150#204 - +#213#191#250'K'#175'?'#243#172'D'#23#227'h'#163#181'y]'#253#220'_'#251#166'z' - +#229#231#223'g'#193#149#17#252'z'#30#175#178#211#15#246#187#145#252'H'#248 - +#129#228'g'#2#152#217#176#31'r'#255'G'#219'w'#200#246#127#135'$'#255#140'I"O' - +'u'#185'o=\'#244'_'#233'm'#191#157#231#252#137'\'#239'o'#26'~@'#250#211#254 - +'m4'#251#132#244#199#12#192#181'Z'#13'>'#130#217'Q'#27'~'#30'e'#251#6'x' - +#138'/'#237#248#203'otw'#223'i'#199'3'#132#249#172#227#143#176#129#164#159'-' - +'H|'#241#252#179#227#143'0'#180'3'#164#177#183#183'7{'#214#134#31'O'#27#199 - ,'B'#0'J*'#5#209'6'#140#206#187#213'h4`'#10'\VZ'#250#223#148#245#165'E'#26'\!' - +#18#248'R'#166#194#136'I'#128#147'~"'#235#15#136#219#29#173#1#136'C'#16#25 - +#130'a='#226#181'o'#138#134'l'#142#128#152#3'b'#18#148#148#128'e'#191#242#164 - +#177#246#148'+'#253'?'#255#225'o'#169#31#253#193#191'='#225#147'z1'#6#188#249 - +#31#251#139#127']'#253#204'_'#254#155#207'>'#163#239#147#158#13#145#250#182 - +#194#207#218#252#162#250'/t'#184#143#19'z&s'#209#0'D'#253#167#237'>'#236#254 - +#253#251#252#154''#174 - +#230#163#254'i'#159#202#185#25'+/'#127'T}'#246#27#127'G]'#255#220'W'#223#215 - +#251#151#206'>g5'#254#188'P'#251#179'\l~'#29#235#207#165#188'W'#199#251#181 - +#218#159#10#248#19'&'#130#153#26'o'#223'S'#253#135'?`'#211' [,'#172#215#191 - +#17#206#251'/'#147#221'/'#223#4#213#31'&'#192#152#22#132#130#224#12#180#170 - +'?-'#152#231#15#14#193#145#211#236#243#185'I'#127#251#155#143'iX'#135' &'#20 - +'%'#192'cZ'#241'Mt'#14#130'/'#0#166#0#189#230#10'-k'#15'G'#189#183'v'''#205 - +#151#141'w_;'#250'b'#213'\'#135'?'#224'u'#21#213'$1'#168#17'["'#240'M[q'#19 - +#30#180'='#5'i'#9#138#217#134'r'#201#21'8'#15'n'#129'{'#255#231#191#169#255 - +#250';'#191'z'#218#167'q'#166'Gs'#253#138'z'#233#203'_S?'#243'+'#191#165#234 - +#171#155#207#245#179'M#'#15'//'#8#0#21'}'#153#16#0#219#253#146#230#11#149#30 - +'E> '#0#150#254#0#255'Tk'#1#179#193#158#218#187#253#135#244#191#194#238'W' - +#176#251#189'd'#241#234#202#246#247'B'#178#255#149#168#254#180'L'#137#4'0' - +#203'/:'#253#222#147'f'#159'w$'#1'h'#219'8'#254#158'W'#216#175':'#142#149#0 - +#224#16#252#214#183#190#197'MC'#136#201'Z'#244#195'`'#152']'#22'-'#0'$pM!J' - +#160#188#149'w'#247#214#190'0Kk=eH'#0#210#157'H'#160's'#249'5'#186#233'/IRP' - +#205'j'#1#8#13#194#28#240'b'#157'#'#160#195#131#18'"4'#25#131#158''''#10#192 - +#249#9#19#254#254#223#254'e'#245#240'";'#176'4'#26'kW'#212#205#159#255#154'z' - +#235#24'@_'#26#206#196#157'6'#209'G&'#241#204#165#161'g.'#177'~V'#253#167#218 - +#238'O'#5#252')'#183#249#30#178#211'o1'#30'j'#233#159'&'#186'4'#152#237#254 - +#189'w'#218#209#180'oT'#127'z>9'#230'Ok4'#250#228'f'#31' '#0#244#249#203#178 - +#12#190#128#253#227'p'#252#185#227#184'aa'#29#130#244#163'j'#164#1'tMn'#0'H@' - +#136#0#29#133#215#147'<'#218#248#233#222#250#23'3'#130#189'q'#10#194#31#0'{' - +#191's'#245#227#170#209#187','#192#143#181'?'#192'5'#7'b]>\'#20#14'A'#11#208 - +'D'#144#151#10#136#156#159#251#164'_~'#18#254#129'C'#190#31's'#1#254#222#175 - +#127'A'#141#30#221'9'#129#147'8'#187#163#177'vYK'#250'_'#251'['#31#12#244'O{' - +#194#141#202#159#231#142#237'o'#192#159#217#226#158'\'#178#252'8'#140'7[X' - +#192'C'#242#167'Sc'#255#143#9#252#127#164'f'#163'}Q'#253#19#235'7Xo'#142#238 - +'m6'#251#144#240#244'Hz'#166#216'g'#12#144'#'#227'O'#21#210#255'.'#225#4#181 - +#254#187#180' '#230'?'#251#250#215#191#158'>O'#199#223#179'\'#158#231#241#249 - +#236#16#188'v'#237'ZD?'#166'I?'#142'M'#1':~]'#242#2#224#16#132'V'#176#218#159 - +'7n'#222#31#174'|'#138#253#1#220#16'$'#212#243#6#196#177#234'^{K'#213'z'#235 - +'L'#0'69'#168')'#249#1'5m'#10#232'D'#161'P'#207'1`'#252#2#158'8'#6#13#1'x:' - +#195#235','#155#4#217'|'#170#254#227'o|^M'#182#31#156#246#169#156#232#208#160 - +#255#243#234#19#4'zl'#31#247'0A'#23#207#216#251#210#196#147#255'!'#192'5Y~' - +#185#128#31#146'?'#19#181#127'!$'#144'Ng'#236#245#239#223#253#174#154#13'w4' - +#248#209#223#15#170#127#134'x?'#236#254#157#183#229#27'!'#253#145#245'7'#161 - +#239#178'1'#127'I'#246'A'#143'?T'#254'm#'#227#143#204#229#217'q8'#254#220'q' - +#18'0`-'#128#214#193#189'{'#247'0'#181'x'#11#141'C'#148#6#189'!'#1#248#5'6i{' - +'e{'#210'}'#227#241#164#253#154'.'#24#242#25#208' '#129#176#214'P'#221#171'o' - +'q'#255#128'@'#204#129#192#248#3#140'S'#208'!'#1#27#29'p'#27#140'B#p'#253#1 - +'v6'#226#167'\'#134#147'L)'#150's'#193#148#224#223#250#245#159'S'#211#189#173 - +#147#251#238#19#30'A\S'#221#151'^W'#215#190#240#139#234#245#191#240#13#213'X' - +#127'N'#160'?'#202#253't<'#253'&'#191'7wm'#254#212'H'#254#2#252#25#131'_''' - +#251'X'#181#31#14#192#217'L'#245#31'|_M'#247#183#216''#239#186#170#127#179#217#156#16 - +'^'#22#199#225#248'+]'#138#227#248#208'e'#223'cL'#1#218#174#199'q'#220'Y,'#22 - +'k'#196'vp'#2#26#18#192#246#6#189#180#247'`'#216'{s'#127#214#188'a'#253#1'a' - +#164'g'#24#170#183'T'#239#198'[*nuu'#211#16'h'#2#13#153'h'#148#246#217#31'P3' - +#230'@A'#2'z'#242'Q_'#151#17'{^'#209'r'#253'e'#245#234'/'#253'U'#181#249#214#23#143#241#203#158#208 - +#198'/'#175#188#206'H{'''#179'O'#247#242'3'#224#207'X'#234'g'#21#201#207#241 - +'~'#2'}'#6'{_'#136#0#165#189#147#157#247#24#252#186#181#151#158#212#211#207 - +#210#228#229#149#237#31#212#130#197#196#181#251#149#14#249#193#238#223#18#213 - +#31's'#252'q'#200#143#182'w'#8#15#195#231'Y'#236's'#132#203'vb'#195#166#9'_' - +#191'~'#29#154'@'#11#181#2#240#7#208#15#191'*aA'#204'1'#8'=p5'#247#252#206 - +#157#254#234#167#198'I}'#213#23#167#160#23#232','#192#184#217'c'#18#8#26'uM' - +#0'l'#18'D'#146')'#136#16#161'4'#18'A'#152#208#180#21#243#29#18'0'#221#133'<' - +'!'#0#229#2#255'9D'#12#142'a6'#227#225#253#159#168#255#254#219#191#172#134 - +#247'~z'#130#183#236#217#6#8#186#190#178#169#214'>'#254#179#234#213'?'#251'+' - +#234#218#159#248#165#163#191#249#176'k'#246'<'#158'PG'#218'kG'#191#201#231 - +#207'm#'#143#194#230'/'#210'{y'#153#27#169#191#208#192#135#148#135#250'O'#132 - +'0'#217#190#163'F[?"'#146#152'Ks'#15']'#223#143'?7'#187'{o7'#194#217#208#177 - +#251#231#244'l'#163#197#23#18'='#182'%'#215#159#193'O8'#128#25#176#141#132 - +#159#157#157#157#169'x'#253#13#248'_'#24#2#224#239's'#19#132#8#248#173'$I' - +#216#31'@'#11'B'#130#208#4#216#31'@'#235#149'\'#249#157'w'#247#214'?='#205 - +#162#14#146#132#152#4#184'7'#0#145'@gMu'#174#189'%'#229#194#162#1#152#252#0 - +'h'#1#146'-X8'#6#203#154'@a'#18#248#197#228'#N1'#209'Y'#237'='#248#255#254 - +#205'?R?'#248'w'#255'DMw'#30#158#234'y'#4#245#166'jn\S+'#175'}'#130'$'#252 - +#159'R7'#190#244#231'T}'#253#202'i_'#158#202#200#203#210'_Rz='#227#236#147'r' - +'^'#6#191#163#246'['#240#139#202#15#224#179'z'#207'*'#191#246#1#204'v'#31#168 - +#193#195#183#233'usn'#238#193#239'Cyo'#154#229'W'#187'{?'#236#196#147#190#168 - +'l'#214#238#23#167#223'.'#236'~ZX'#245#135#211#143'0'#240#152#222#187'O'#166 - +#241#4#9'?'#199#233#245#175#142#211'x'#202'}'#152#2#180#6#9'X'#127#0#217'?' - +#151#29'S'#0#26#1#252#1#221'$'#243#187#239#246#215'?'#179#200#163#134'o'#204 - +#1#216#247'$'#233#153#4#174'|'#156'H'#160'nA'#207'f'#128'h'#4'L'#2#145'&'#1 - +#21#233#168#2#147'@h'#8'@r'#5'|'#129';'#214'2)'#225'Y'#159#166'|'#240#222#219 - +#234#143#255#249#223'W'#15#254#247#31#208'C99'#190'/'#162'k'#17#183'{'#170'u' - +#245'e'#181#250#209#207#168'+'#159#251#170#186#250#249#175#210#245#175#159 - +#246'%x'#250'03L'#219#130#30'c'#231#23#253#251#140#167#223'H~V'#225#231'I'#1 - +'x'#6#255#156#155'{'#178'&@'#255#155#238#222'U'#163'G'#210#206'{Q'#168#253' ' - +#146#203#173'}L'#231#181#131'/q'#156'~H'#245'E'#188#127#15#133'='#180#141'F' - +#144'P'#251#225#244'{D'#207#245#222'I'#218#253#238'8'#141'G|'#169'?@f'#22'b' - +#167#160#210'Z'#0#182#215#233#1#236#204#147'`'#229#189#254#250#167#19#21#198 - +''#28#234'#p'#231'R'#217#151'I' - +#184#15#142'>'#14#251#137#31'`'#188#253#30'-'#239'jR'#224'i'#188'S'#142#22#0 - +#252#27#205#193#237#245#198#240#145#11'~z'#182#140#221#15#240'o'#153'J?z'#230 - +#239#201'4'#223#232#240#131#6' '#199#150#237#247','#151#242#196#190#215#245#7 - +#208#197'h'#18#248'{'#164#10'm'#18#192#175'Hx'#144#179#4'iY'#3#9#204#210'x' - +#237#246#254#250'''3'#207#15'Yr#<'#24'j'#18#8#27'm'#213'!'#18#136#154#29#2'~' - +'h'#181#0#228#8'x'#236#20',H'#128#181#129'J'#152#208#212#17#24#18'`'#231' t' - +#148#220#153#144#164'`'#132#234#147#246#244'+y'#10#4'1'#219'{'#172#230#253#29 - +'5'#31#236#210'zO-'#134#251'\9'#217'}'#249#13#213#185#249#250#217#149#224'G' - +#189#142'K'#239'C'#17#222's[u'#219#16#159#11#254#170#212#151#220#254'L'#154 - +'z'#148#9'@K'#255#209#214#143#213'd'#239#30#189'n'#206#145#1'~'#159#228#248 - +#175#214'F'#15#174#180#251'w'#243#2#252#200#244#131#221#15#240#195#238#127',' - +'!'#191'{R'#223#15#27'n{:'#157#14#136#0#160#194'%''e'#247#31#245'r'#31#251'w' - +'W'#243#3#200#28'@3'#209'Md'#10'*'#237#16#196#26'$'#176'J m'#141#23#181#205 - +#187#253#213#183#136#4#2'm'#207#11#9'p'#4#160#201#230'@D'#234#170#213#4#156 - +#181#23#11#17#24'M'#128'L'#2#21'j'#191#130'2s'#17#26's'#192'M'#30'2UEn'#163 - +#145'3l'#26'|'#232'F^'#10#226#8#224'M'#21#159#210#158'}'#137#239#187'i'#189 - +#218#230#215#128#207#13#248#173#228'_0'#200#217#241'7'#211#161#190#225#163 - ,#183#213#172#255'H'#146'|'#140#218#175'k'#251#187#209'd'#235'zw'#239'=m]d' - +#153'x'#252#145#236#3#240'#'#151#127'['#233'y'#253#24#252#216'F'#178#207'I' - +#198#251#15#27#167#253'('#151'R'#133'I'#11'h#'#25#136#180#128'K'#208#4'h'#31 - +'Z'#0'H'#0#164#176'B@lM'#147'x'#237'N'#127#245#19#169#23#198#218#179'/>'#1 - +#174#12#172#17#9'|L'#197#157'uM'#10#198#15'`'#192'/m'#198'=!'#2'_z'#10'('#19 - +'%'#16#231#160'2'#230#128#239#21#4'`'#174#214#139'>]'#241'y'#25'.'#234']sGl|' - +'O'#202'wm'#3#143#170#179#207'8'#250#0'f'#212#243'/'#28#240#27#231#31#175#167 - +'j'#240#240#7#164'ImK'#140'?'#209#196#145'j'#240#175#213'F'#247'/'#183#145 - +#226'k'#193#159'I'#154'/g'#250')]'#226#251'H'#230#245#131#228#199#164#30#143 - +'1'#171#207'|>'#31#31'w'#170#239'Q.'#227'i'#223'F'#207'8'#5#209'@'#4']'#132 - +#208'P'#212#9#15'"O'#224#138#201#20#4#9'$y'#220#189#189#191#250#214'BE'#245 - +#18#9#136's'#176's'#249#13#21'w/'#177'/'#192'3'#181#2#177#244#16#176'&A'#164 - +#253#2'b'#14#168#208'/'#146#134#140'i '#13'F'#172'F`'#175#152#163#10#156#159 - +':'#163#23'f'#148#146'xl'#171'.}'#140#193#159'i'#201'oc'#251#169'n'#226#1#240 - +'+'''#204#151'K'#190'>'#171#244'3'#241#250#211#177'\B'#127#201't'#162#6#247 - +#191#175#18#228#246'''s'#157#21#232#128#127#163'1'#184#189#217#28'>'#210#138 - +'F'#150';'#146#31'*={'#252#149#238#237#7#240#223#151'p'#223'cH'#254#197'b1' - +#186'v'#237#26#156#131''''#234#244#171#142#179#240#236'Z'#18#232't:1'#177'b' - +#157'.T'#27#149#131#232'$'#4#2'0$ '#173#198'A'#2#205'L'#133#237#219#253#181 - +'7gY'#220#214'}'#0#196#174#143't)qk'#243#150'j'#172'^'#215#146#222#1#189#217 - +'f-'#160#166#147#139'8Dh'#219#142#7#133's0'#240#10#141#192'I rs'#137#205'f~' - +#224'''='#225#10'?'#211#173'>'#175']'#130#142#248'h='#245#250','#191#178#185 - +#211#151#223#5#191#246#238#235#248#190'J'#181#202#175#4#176#156#155#159':' - +#246#254'\'#131'?'#183'j'#191'd'#242#17#25'$'#147#161#234#223#255#158'Ji]H~' - +#157#225#167#210','#191#220#217#255#201'j<'#217#21#193'o'#193#175#138#190'~' - +#166#190#255#1#164#191#132#254#30#163#190#159#198#168#209'h'#204#143';'#207 - +#255'9'#222#165#227'?'#15'S:'#140#162#161#241'x'#140#134#162#29#169#25#184'd' - +'4'#1#165#251#7#160#177'H'#143#174'X'#147#16#218#188#211'_'#251#216'8'#173 - +#173'x2'#239#160#206#254#211#18#191#190'rU'#181#214'oiM'#192#250#1'B'#157',$' - +'d'#224'I%'#161#138#138#190#2#166#152'Hq'#132#192#244#23#240#203#145#2#167 - +#243'P.'#161#195#234#21#245#202#127#158'q'#228'O'#220'='#179#195'{'#234#129 - +#167#255#238'|'#201#207#21#144#27#129#175#14#11#237'9'#133'<*-b'#251#197#162 - +#129#207#210#127#190#144'p'#223'B'#180#129#5#255'o>'#216'a'#155'?'#157#142'u' - +''''#31'Z'#148#128#223'#'#241#127#181#187#247#163'n8'#27','#3#191#210#225'>' - +#128#31'-'#188#31#144'&'#203#14'?'#228#248'#'#220'G'#175#27#161#200'G'#157 - +#146#211#239#131#222#157'c='#23#248#3'~'#252#227#31#251'h%F'#154'@'#195#228#8 - +'`V!'#164#12#131#8'h'#141#164'!4'#26#237#210'Uk'#17#240#234#247#6'k'#175#15 - +#23#245#13'c'#14'0'#17'DP'#241#145':'#220'Sm2'#9'PG'#224'K?'#193#2#252#142'6' - +#192#254#0'c'#14#232'm'#155'8Ti9f'#195#134#158#201'(tr'#207#171#253#7#204#173 - +'=KW'#250','#143#202#245#202#157#166#156'%'#208#27#162#200#164'eW'#150#29'H' - +#231'Ui'#1'z'#227#237'O%'#212#151#207#231#142#195'O|'#0'D'#2#147#221#219'j' - +#178#253#158#222'w$?>'#223#167#15#184#222#219'{'#167#21#204#199'K'#192'ob' - +#253'h'#234#137'4_+'#249#233#153'}L'#160#223#165#231#23'5'#0' '#137'3'#1'~' - +#231'2'#159#153#193'$'#240#189#239'}/@x'#16'$@Z@W'#26#137#184#154#0'"'#3#235 - +'('#28#162#27#129#18#227#248#254#160'wko'#222#188#234'['#245']k'#2#200#26#244 - +#227#26#153#4#31'Q'#181#206#166#150#248#174#244#23#223#128#206#17'0'#249#2 - +#129#205#30'TN'#6#161#237'@'#236#251#5#1'8m'#201#221#26#3#235#164#170#22#27 - +#157#181'+~F'#134'Wr'#228#185#155#249#1#240'k'''#159'H'#251#180#144#250#165 - +'t^'#168#251#137#238#215#175#9'@<'#254#226#237'7'#26#0#19#0#166#233#154'N' - +#213#136#164#254'|'#180#171#227#251'IR'#2#127#160#146#217'K'#221#221#31#214 - +#131#197'T'#192'o'#28'~F'#242's'#129#15'r'#252#209#220#3#146#31#26#0#212#254 - +'('#138'v'#7#131#193#136#180#218#19'M'#243'='#210'u?'#237#19'XvN&<'#184#181 - +#181#21#211'Ek'#208#5'4$'#128'lA'#180#24#135')'#192'$@'#251']'#248#4#232'X' - +#237#209#168#243#210#246#180'}SO8bH@2'#0#137#8#234#189#171#170#185#241'*'#131 - +#222's'#181#129'H'#147#129'''-'#199#149'q'#14'F'#21'm'#192'u'#16#154'z'#2'&' - +#3'eg)'#202#29'2p'#181#255#220'!'#133#15'f'#26#188'(C'#210'u\'#137#159#23#181 - +#249#202'sT}'#199#201'W'#168#249'"'#245#197#214#231'2'#222#180'p'#242'1'#232 - +#165#148#215'z'#252#141#234'/'#170'>'#219#254#201'B-'#250#187'j'#184#245#14 - +#29#27#219#200#128#174#229#151#137';'#189#249#228#165#238#222#15#185#170#143 - +#235#8'l'#168#143'S|'#149'd'#249')'#237#224'C'#184#15'R'#255#1#212'~'#178#249 - +'w'#233#249#29'6'#155#205')i'#183#201'iz'#252#151#141#179#250#4#150'H'#160'A' - +'c2'#153#160#145#8#155#3'B'#2' '#3#209#4'T'#151#128#136#190#131#181#253'Yc' - +#243#225#168#251'Z'#166#194'PKn'#169'!'#8'C1'#9#186#164#13#188#193#213#132#0 - +'>'#28#129#158'D'#4#220#16#161#155'9'#168#156'Z'#2#229#18#129#231#23#179#22 - ,#251#198'I'#232'j'#3'E'#30'a'#238#148#25'z'#213#146#195#3#153'mg'#245#182#188 - +#223#187#249#4#127#134#233#191#167#156#198#28'|'#188#2'zP'#168#3'~'#211#173 - +#135'U}'#9#239')'#167'O?'#188#245#249#28#251#11'+'#249's)'#238#201'%'#207'?' - +''''#240#143'wn'#171')-'#153'y]*R_f'#238'iG'#147#237#171#173#253#219#129#151 - +'&:'#151'(3e'#189#240#246'3'#248#149#206#242'CO?'#246#248#195#230'G'#168#15 - +#224#167'eH'#166#236#20#177#254#179#6'~}'#205#207#238#176#133'C'#4#254#136'.' - +'b'#147'L'#130'.H@:'#10']6'#225'A%$'#128#16'!H`'#158#133#237#187#131#222#235 - +#179#172#214#230'y'#3#140'o'#192#132#10#163#186'j_zM'#197#221#205#2#248'f1'#4 - +#16'W'#142#7#186#211#144#178#243#19#6'em@'#26#143#148'#'#6#158#149#244#172#29 - +','#137#30#152#249#11#142'zG'#206#204#147#227#222#168#167#189' ?'#252#128'i' - +#197#229'y'#14#248'3'''#150#175#28#27#223'Q'#247'y'#31#182#190#27#222'K'#11 - +#137#159#27#208''':'#181'7/'#145'@'#194#245#19'#'#146#250#243#225#142'h'#11 - +':'#188#167#138#30'~'#217#165'F'#255#246'Zc'#244#152'S{%'#212#167'tz/O'#223 - +'-s'#248'A'#237'7'#137'>'#15#207#19#248#143't'#239'N'#251#252#12#9#244#251 - +#253#184#213'j5'#232#226#162#197#248#154#132#4#225#16#188#12#173'@i'#18#232 - +'1'#9'('#175#158#7'~'#252'p'#208#189#185'?o]-'#146'|t'#184#15'&'#129'oL'#130 - +#245'W'#8#236#177#205#9#240'L'#5'a'#172'5'#6#171#9'p'#10'qPT'#21#210':'#15 - +#220')'#202#140'V'#224#21'D'#160#138#237'"JP'#172'K%'#200#206'f^9'#236'='#235 - +#173'z'#158'w'#245#153#31#215#188#152'>'#219'='#149#188#188#145';/'#178#245 - +#249'n'#18#143#177#243'MG^'#145#250'*u$'#191'c'#235#27'/?'#219#237#12#244'E' - +#161#254#207#11'R'#192#255#23#240#242'?'#254'!i'#1#19#177#247'u|'#223'|n'#228 - +'/&'#215#218'{?i'#132's'#174#229#23'G'#4#236'}'#147#222';'#145'P'#31#171#253 - +'J'#194'}'#178'F'#169#239#222'y'#0#127#233#254#156#209#193#231'W%'#1'd'#12'"' - +'Y'#136'.'#178'!'#1#152#5#151'0'#247#128#210'y'#2'm'#186#212'u'#146#184#241 - +'p'#222'X{0^'#185#149#145#236#215'@-'#155#4'H!'#6#9#196#157#13#201#7#144#136 - +#128#1#191')$'#10'+$ '#11#147#138'h'#6#156'N,'#145#130'\'#162#6'V'#27'x'#26 - +#17'8'#221#137'rG;'#240#202'^'#196''''#220#177#147#184#149#249#225#135'+'#167 - +'i'#140'{'#175#244'6'#167'<'#23#0'WO'#0'~^'#150#248#202#22#239'8N>c'#239#187 - +'v'#191#149#252#139#18#240'Y'#19#152'N'#213'd'#251#167'j6'#220'b'#130'@'#179 - +#15'+'#241'3=__'''#154'<'#190#210#234#223'!'#149'?'#205'm'#147'@]'#210#235'd' - +#248#245#165#178#15#222#254'G'#146#215#255'H4'#129'}8'#252'666'#206'<'#248 - +#237#253'9'#227#195#146#128#18#159#128#146'2b"'#130#21'h'#2#146'%h'#178#5'9Y' - +#136'$r'#155#192#211#160';'#23'''Y'#212#184';'#236#189'6Kk'#29'S'#0'd'#27#140 - +#8#184#163#214#26#19'APo'#21#17#1#167#138#208's'#251#10'<'#137#8#220#148'b' - +#153#194#220#134#14#205#196'%'#165')'#204#202'k7'#132'h'#230'4'#176#135#14 - +#132#20#143'n:<'#151'q'#152'*o'#156'v'#246#144#145#236#230#127#249#146#216 - +#189'~'#157#14#227'I'#230#158'!'#2'k'#227'/Q'#247'S'#145#248#2'|'#181#208#149 - +'|J'#236'w'#215#222'7'#206'?E'#251#147#254'=5'#221#189#173#19#127#210'%*?}' - +#209#229#198#224#189#149#198'h'#199#203'MI'#143#14#243')'#1'?'#173#199#180 - +#223#151#154'~4k'#132#196'GE'#31#182#183'I('#161#145'''{'#251#201'\=s'#14#191 - +'e'#227'<'#16#128'=OC'#2#251#251#251#17']'#228':]x'#174#29#136#162'h'#157#246 - +'a'#6'\'#18''''#225#134#212#14'th'#27'}'#4'b'#210#0#162'G'#195#206'K{U'#147 - +' '#212#201'C'#138#171#11'#U'#235']S'#245#181#27#156'M'#200#14'@'#199#4#0#1 - +'(''Dh'#136#192#148#24'+'#153#181'X'#249#229#198'#'#182#21'Y%'#179'P'#231#15 - +'-'''#3#207#209#255#139#222#4#166#151#161'{UN'#136#4#170#143#176#19#182'+m' - +#229#5'Y'#149'CxN'#165#158#27#198'3N='''#150'oA'#159#154'm'#0'>#b'#0#160'u' - +#17#143'Z'#20#13';'#173#199'?IJ>'#0#132#0#147#209#158#154#236#252'D-&'#131'B' - +#213#135#169#128#207'pU'#254#238#238'O'#234'^2'#245't'#229'@'#213#211'?'#147 - +#22#222#168#234#219'q'#193#15'O'#127#24#134#232#235#223'_,'#22#227#25#141#243 - +#2'~'#140#243'B'#0#246'\'#221'<'#1'8'#252#232#194#183#232'p'#143'.'#254#186 - +'8'#7'A'#4#156','#132'V'#227'$'#129';$u'#27#180'_#'#240'E'#131'i}'#237#193 - +#164#247'j'#150#235#249#7#180#147'0`'#21#222#244#16#132'Y'#208'X{'#133#139 - +#138#188#208#137#6#200#220#3#134#8'4q'#4#162#29#136'&`{'#13'8]'#137#131#138 - +#163'P'#8#161'hF"'#19#152#28'H76'#161#195#162','#185#240#15'T='#3'G'#200'1' - +#248#160'%'#203'y^yi'#25#240'z'#229'4'#218'TE|'#159'%'#189#153'l'#195#190#230 - +#160#154#207#246'~'#154#149#218'r+'#150#250#153#6#173#0'_'#137'='#175#164#131 - +#143'2'#4#144'h'#239#127':''u'#127#231']5'#239'?'#210#173#186'L'#26'p'#146#10 - +#209'h'#149#31#149'|'#151'['#253#187'P'#249'9'#188#143#254'}'#160'!m'#239#219 - +#24#191#1#191#210'e'#189#15'e'#198#222#199'R'#207'? '#1'4>K'#25'~G'#29#231 - +#137#0#236'9'#155#180'a'#218#142#26#141'F'#13#17#2#164#7#27#231#160'8'#5'/' - +#217#218#1#29'&'#132's'#176#6#147' Sa'#252'h'#220'~'#169'?onz@'#166#137#20 - +#216'f!Z'#226#195',h'#192', B'#176'R'#223#1#188'Bd '#22'B'#16'M@9'#25#132#214 - +'I'#24'>A+8'#204'GP'#154#242#188#186'v:'#26'['#13#193#161#130#165#190#130'CB' - +#143'O'#200#187#183#160'.%'#224#23#26'H.'#234'})Q'#199'%'#0#215#147'/'#158'}' - ,#163#226#219'p'#158'q'#240'Y'#208#167'b'#231';'#158'}l'#11#192#181#202#175 - +#215':'#175#223'8'#2'%vO'#235#217#222'}5'#222#131#186'?'#211#199#229'3y'#157 - +#167'"'#245#147#201#149#230#254#237'f<'#27'z'#26#247'8'#15#146#250'%{'#223'&' - +#248#208#178'C'#210#254'1'#9#153'G'#210#213'g'#155#128#191'K'#160#31#160#149 - +#23#13#152#8#231#10#252'K'#158#138's3,'#9#208#197#15'k4'#200#12'h"B'#16#4#193 - +#170#227#23#128'F'#0#18'X'#5'A B &A'#148#19#196''''#139#176#253'p'#178#242 - +#202','#141'ZE'#235#240#162'('#200#147'9'#10'k'#221'+'#170#182'rM'#5'h'#162 - +#17#154'y'#8#3#199#28'pM'#3#9#17#134'RK`'#10#140'l'#14'A Z'#129#201'$t'#218 - +#146'U'#137#160'j*'#148#202#146'+'#21#137#21'G'#162';'#242''''#146'A'#165#216 - +'f'#217'c'#235'Jw'#222#168#172'e;7'#137'<'#153#27#190'3'#137'<'#142#164'wc' - +#249#2'|'#29#203'/'#192#175#137#192#9#241#217't^'#13'r'#237#3'H'#10''' -'#139 - +#225#14#219#249#9#171#251#186'I'#167#146'L>'#179#246#232#207'j}t'#127#189'1x' - +#228#177#180#207'3'#147#214#171'$'#190'O'#203'\j'#249#135#226#233#135's'#15 - +#210#30#249#252'['#178#191'O'#207#220#160#223#239'O'#187#221#238#156#8' =o' - +#224#175'>'#9#231'm'#148'J'#137'I'#19#136'%u'#152#157#131't'#140#181#1#144#0 - +#250#11#210'z'#141#253#2#202'k#}'#152#182'czDc rw'#218#186#180'=m_'#207'H' - +#164#235#226#31#237'$'#132'fP'#168#249#145#170#181'/'#169#6#17#129#31'7'#180 - +#244'7j'#191'k'#14#24#127'@'#224#164#17#187#166#129#201'!p'#29#133#198'<'#176 - +#4#224'W'#18#139#180'G'#192#246'.'#180'='#11#141'iP'#152#3'n'#194'Q'#217';' - +#239#29'XU"s'#202'Az'#217#181#144#187#161'='#137#215#231'y'#197#214#151'B'#29 - +#163#226'gy'#145#167'oSu'#139')'#183'\'#201'_H'#253#20'M5'#197'VO-'#9#184'a' - +#190#220#170#251#198'!H'#18#127#184#173#166'{wU:'#27#22'f'#129#11'~'#241')' - +#180#162#217'.I'#253';'#152#156#211'C/`}n'#172#242'+'#221#187#207#228#244#143 - +#140#167#159#182#183#197#219#191'Ej'#254'6'#9#24'h'#2'}'#147#215#239#244#241 - +'3'#192'?7'#224'w'#30#135's;,'#9#16#1#4#8#19#18#27#195'9'#216#154#205'f=h'#3 - +#244#127#244#26'D'#171'1h'#2#240#11#160'r'#144#211#135#17'% '#192'D'#244#17 - +'A'#146#249#241#163'I'#247#230'`'#214'X'#247'l'#241'O'#1'^?0 '#142#184#166#0 - +#206'B'#244#211'3'#166#0#167#13'['#208#23#161'A'#27'!'#136#180#244#207#131 - +#224'@wb'#235'#p*'#15#11'"P:'#164'h'#211#139#165']'#153'*L'#4#151#24#150'^"' - +#175'r'#197#170#26#192'!'#14#190#18#15#184#245#246#216#204#242#146#189'o5'#0 - +'7W'#223#128#221'z'#244#141#202'/'#246'~'#166#167#219'V'#226#228#179#128#183 - +#29'{'#202#224#183#197'='#236#253'_'#168#217'`K'#205#246#239#17#240#199#146 - +#16#148'X'#147#1#251'J:'#246'D^2'#187#212#26#220'n'#215#166'}'#248#28'<'#143 - +'U~V'#252#233#146#177#163'Oz'#247'Me'#178'Nk'#239'C'#237#151#153'{9'#190#15 - +#149#159#20#206'1b'#252#245'z'#29#164'a'#234#249#237'U:O'#227#188#19#128#249 - +#13'H'#24#194#154'#'#4'p'#14#18#1'4E'#27'X5'#190#1'!'#1'6'#9'h'#191#7#191#0 - +'m'#195'A'#8'm'#128#222#231#251#163'$'#238'>'#28'uo.'#178#168#233#154#5#202 - +'I+V'#226''''#136#219#27#170#222#187#174#130'F'#235#160#212'7'#170#191'C'#4 - +#134'L'#148'K'#2#2'z'#229'U'#157#133#14')x'#166#10'Q9~'#130'J7cq$'#30#152#241 - +#232#176#154#3'[m'#231#188#196'm'#180'a6'#189'B+'#240#158#2'zW'#213#247'*' - +#222'|'#29#215#207#172'Df'#7'`R'#168#251#158#1'}'#226'H~'#163#13'd'#134#8'2' - +#142#223#207#6#143#24#248#217'bb'#237'~'#227#216#203'\u'#159#132#252'J}'#252 - +'p'#179'9x'#224#209#142#199#165#130#224#29#218'f%'#198':'#250'f'#210#187#207 - +'t'#238#133#167#223#130#31#19'v'#160#137#7#254#143#254'}'#163#209'h^'#241#244 - +'+u'#14#193#127#200#147'q.'#135#141#16#160#156#248#214#173'['#225#214#214'V' - +#141#14#213#137#173#17'*'#236#145#250#134'b'#162'u''u'#24#251#200'#hC'#27#160 - +#237#26#251#6''#199#245'3'#201#231#183'R'#159#22 - +#19#226'c'#149#31#160#199#2#149'_'#8#1#29'|'#198#244#182')'#217#253' '#140 - +#132#180#206#236'<'#132#249#142#4#156#23'h'#176's'#240#219#223#254'6'#251#5 - +#232#166'E'#4#234':'#28#132'259'#155#4'XD'#27'0$'#208#165#183#146'>'#175#26#4 - +#167#24'f'#1#129'='#160#199'%'#220#157#183'6'#247'&'#173#203#137#10#226#3'D' - +#224#23#246'>4'#130#176#209'!'#173'`'#147#8'a]'#249'a,m'#198#140#3#240'0'#167 - +#224'!'#5'F'#146'3'#224#149'|'#3#166#23'A1'#169#137'%'#2#153#224#196'LuV'#10 - +#18#10'7'#148#156#132#14#3'xF'#210'Wd'#153#145#246#7#28'{N'#252#222#149#252 - +#182'B'#207#237#200'c'#192'/'#132#160'\'#167#159#149#242#142#211#207#233#224 - +#131#255'-'#166#251'j1'#220#162'e'#155'I w'#205#128','#147#150'_'#236#220#195 - +'~'#222#138'g'#187#27#141#193#131'Z'#184#152#150#212'}'#199#214#151#182']' - +#166'c/l'#249'}i'#226#193#158'~Z?Fl'#159#164#252'>='''#3'2/'#199#244','#205 - ,'{'#189#30#192#127'n'#237#253#165#128'9'#237#19'8'#166#223'T2'#9'h N'#211'di' - +'O'#128#167#155'j'#137'@'#204#3#236#19#9#168#14#1#174'A'#251'u:'#30#25#179 - +#128'@'#21#236#205'Z'#27#187#227#230#229#133#10#235#218'F'#247#203#211#141#17 - +#1'('#223#183'ZA'#173#177#170'""'#131#176#185#162#163#4#230#181#142'3'#208'H' - +'~'#255'0-'#192#152#8'&'#147#208#248#7#248#23'V2'#12#221#28#130#220#137#12#8 - +#27#152#196#220#131#209#130'Jz'#174#167#172'j/'#255'V'#226#245'+Iyc'#227#27 - +'{'#223'4'#227#176'Z'#128#1#186#172#165#192#166't'#220'M'#237'u'#215'('#203 - +#157#13#31'3'#240'S'#132#242'2'']W'#166#220#206'e'#209#192'O'#243'vm'#182#189 - +#217#24'>'#140'|H|'#28#23#191'>'#171#251#220'%'#208#205#232#227#240#30#242 - +#249'i'#189'/'#237#187#182#205'"'#206'?'#28#199'k'#166'F'#229''''#205'2;'#207 - +#246#254'a`y'#17'G'#201'$@'#168#176#213'j'#197#2'lT'#12'v'#197#25#184'J'#140 - +#143#232#0#22#248#5'D'#27'P-!'#2#152#5'a'#206'd'#128#174#225#190#191'7k'#174 - +#237#142'[W'#230'y'#216#176#206':'#3'|'#207'H'#242#162#2#17#154'@'#212#222' ' - +#173'`C'#5#141#142#227#252#11#184#231#160#231'8'#2#139#168'@u'#10'3'#207#2 - +#222'F'#5#2#209#4'\'#237#192#151#144#161#149#252'U'#7'`%'#159#192#12#183#149 - +'6'#239'+'#235#28#176#213'zF'#229'O'#171#234'~&fA'#230'T'#234#21#206'?~'#189 - +#209#0'*a'#191#18#9','#230'j6'#218'f'#208''''#211'A'#161'!'#152'L@'#199'l0}' - +#0#16#210#235#198#147#199#27#4'|x'#246'M'#190#241#19#212'}k'#235#211#210#151 - +#238'='#12'~'#186#207#144#254#216#222#15#130#128#19'{h'#153#145#244'_ '#196 - +#247#162#168#252'K'#129#242#2#15'k'#18' J'#128#178'b'#186#185'54'#25'!R@'#227 - +'Q'#152#5'+ '#1#133'Y'#137'5'#9'@'#27#232#209#210#17#179#160#238'{~Lk'#16'A' - +#8'"'#240#9'}'#251#179#250#234#206#164'ue'#150'!'#135#192#128#177#144#218#5 - +#176#3'K'#10'a'#212'Tq'#7'Z'#193#154#10'j'#141'2'#184#157#210'bo'#9'!'#184#9 - +'C'#133#25#224#21'~'#2'''R`o'#173'u'#11'H'#180#192'M$'#146'W'#185'~'#128#210 - +#172#185#178'*'#194'}'#174#244#207#156#233#180#225#240#203'd'#178#205#138#183 - +#191'*'#245#179#188#18#1'H'#212'b'#178#175#230'P'#241#199#187#156#216#147';6' - +#189#251'~K '#244'}>1B'#183'6f'#224#7#200#15'6'#192#231#138#221'2'#240#149#6 - +'?'#128#143'N'#189'#'#201#229#223#23#240#195#185#135#25'y'#25#248#240#240'+M' - +#14#211'N'#167'3G'#3#143'7'#223'|'#243#133'R'#249#15#0#228#180'O'#224#132'~#' - +#155#4#208#6'h;Z]]'#141#160#13#200#140'D0'#11'z'#162#17#172#233#244'aM'#4#180 - +'&'#18'Pm'#186#235#220'l'#4'&'#129'o'#136' '#131'F'#224'y'#195#164#209#219 - +#153'4/O'#211'Z'#7#200#180#192'tH'#160'4'#231#128#152#0#232'I'#16#212'z*jt' - +#201#168#232#210'~'#173#210'[`I'#231'!G'#213'/'#171#254'x'#173#18#159#128#241 - +#234'{'#182#152#168#8#4'x'#149#181'*7'#222'PE'#218#190#178#13'8'#157#146#221 - +#204#13#241#21#234#190'w'#192#23'P'#201#233'7'#145#0#2'v2'#27#170#20'v'#253 - +#164'O'#219#131'"'#219#207'x'#239#197#137#231#153#254'~v;'#231'p^'#167'6'#217 - +'^'#175#143#182'|'#143'sy'#213'2'#224';'#237#185#173#147'O'#233#9':'#160#214 - +#239#25#240#3#248'$'#12#246#200#222#135#3#16'z'#254#132'l'#253#217#139#230 - +#232'{'#26'8>,'#227#128'6P'#171#213'bz^0G'#22#166'*G'#159#129#30#28#133#240 - +#17#28#212#6'T'#211#152#5#4#180#18#17'(.'#25#11#163#253'yc}0k'#172#205#210 - +#168'Y'#0#180#172#198#27#245'>'#247#202#196#0'B'#8#27'+*'#170'wT'#0'B'#128#19 - +#209'!'#0#27#14#148#162#162'jc'#210#146#9#224'4"'#177'w'#185#218#140'D'#194 - +'~n'#233'n)'#12#232'j'#2#198#9#232#168#251'n'#184'/'#207'+I?yA'#0'H'#206'I' - +#166'}'#150#244#201'tH'#255'J'#10''' '#155#20'i)4'#200'Q'#0'K&'#184#184'Y' - +#138#4#158#149#218'x'#167#25#209#135'i'#204#231#154#160#24#248#0'<'#235#252 - +'b'#231'/*'#234#254'H'#226#250#198#214'G'#136'oW'#188#251'}'#186#215'C'#168 - +#251#176#245'www'#23'd'#231'sl'#255#19#159#248'D'#254#162#131#223'yB>4'#163 - +#164#13#192'7'#176#178#178#18#17#25#208'f'#204'}'#6'h'#1#216#225'(\1'#218#128 - +#210#26#2#250#18'"'#164'h'#136#0'Y'#132'1a.'#160'g=dg!'#20'r'#210#11#166'i' - +#220#216#155'5'#215'G'#179#218'Z'#162#130#200'S'#5#25#20#146#220#169#7#240 - +#141#243#207#28#15#148#31'7Y;'#8#226#22'}B'#131#9#130#29#141#202'5'#3#156#181 - +#141#18#136#170#159#171#194'$'#200#171#209#1'U'#16#130#155#244#227'6'#222'4' - +#7#149#201#4#212'$'#192' u'#18'}'#12#232#177'dp'#188#211#146'/'#198'l'#199'c' - +#201#200'4/'#1#190#186'm'#181#137#204#250#20'`'#195'7'#195'y'#191'S'#159#236 - +'t'#163#233#158#199'I'#5'b'#143#232#188#131'Ll|l'#1#244#236#224's'#128#143 - +#134#29'#'#153#153#135#195'{'#198#222'7'#14'>'#216#249't'#175#199't'#159#167 - +'('#224'[b'#235';W'#224#197#29#31'6'#2#176#191#217'h'#3#155#155#155#254't:' - +#13'1S1'#252#3'0'#11#232#223'-'#178#7#225#12'D6'#225#138'8'#7'W'#196'y'#168 - +#157#132#158#215#164#199#177'A'#159'V;@'#4#30#224#166'Q:'#152#215#187#253'Yc' - +'}'#148#196'+'#185#22#233'V'#133'7)'#191'E'#135#225#162#243#176'K'#8#185#152 - +#0#164'x'#16#25#212#153#28#130#176#206')'#201'>'#214'd>'#148#10#139'J'#191 - +#244'`'#219#242'"G'#160#236#237#247'Jf@^$'#7#25'3'#1#248'K'#209'H'#19'@'#159 - +'p'#197']'#150#152#245#212#206#198#163#242#195#0#15#252'f%'#147#1#239'1'#251 - +#181'`1&'#21#127#167'GK'#232#193'!'#160'L'#237'0'#147'B'#154'iu'#223#177#241 - ,#171#18#223#216#249#3#1'?'#146'w'#0'~^'#144#194'K'#210#30#197';'#172#238'w' - +#187#221#217#214#214'V'#226'x'#248'_X['#255#176#241'a$'#128#210'o_f'#22#208 - +#225#26#217#130#28'6$'#2#128'F'#208's'#23#209#6#208'k'#160'm'#136#128#128#140 - +'(CL'#251#16#211'Rc'#204#157#238'|'#180'*O'#9#206#251#179#198#234'h^'#235'M' - +#211#168#157#230#162#25#24#199#158'r'#10#131'J'#132'`'#156#127#190'>ig'#187 - +#152#199#16']'#144#27'*'#8'"q:'#134'tX"'#17#158#164'"'#243#233#232#181'/Z' - +#134#150#190#137#216#218'R)'#151'9'#139's'#28#146#28#18#158'_'#207#225'7'#7 - +#196#182#196#183#240#1#184#0'W'#165#130' 1#8T'#167#242#154#191#24#213#163#249 - +#176'G*>Zn'#23#17#8#145#246'8'#3#2'>x'#18#206'}''o'#223#134#244#164'K'#207 - +#184#2'|'#187#208'=d'#224'#'#172#135'L>"'#2#246#238'#'#149#151#8' '#251#176 - +'I}w|'#152#9#192#140#3'f'#1'B'#127#244'p'#196#198'QH'#255'o'#9#216#187#244' ' - +#245#184#150#128#136'@4'#2'v'#20'*'#204'T'#164#188':4'#2')4'#10#173'V'#224'#' - +#29'E'#251#10#176#13#208#18#9#212#137#12#186#147'E'#220#157'$q'#139#224#16#26 - +'S'#161#232''''#232';'#205'D+'#246#190#152#2#150','#148#155'*l~'#150#252'@.' - +#30':$$'#232#216#255#182'EW'#169'1'#191#201#250'S'#165'\'#0'['#221#167#138 - +#148'`'#6'u'#166'T'#158'/'#7'<'#214#181' '#25#215#131#249#176#25#207#251#237 - +'h6'#242#149'8'#243'<61'#140'moA'#175't'#202'.'#24#133#213'|Y'#230#198#179'o' - +'T}'#19#211#151#5#158#254'>'#128'OD>'#140#162'h'#12#137'O'#199#167't'#127#23 - +'t<'#249'0'#170#251#203#198#5#1#20#195's'#205#130';w'#238#4#198'?'#128'9'#7 - +#232'!B'#205'@'#203#241#19#244'$'#140#200'k'#248#7#20'"'#6'9W'#26#214#161#209 - +#18#216#17'm@BQ'#24#248#30#200' '#160'c>'#180'^F'#165'/'#229'<'#244'wL$@'#132 - +#208#153'.'#162#206'4'#141#219#153#14#8#138#237'^T'#4#22'e'#194#170#168#10'T' - +#254'R'#240#219#191'U'#207#127#241#207'J'#246'_'#197#7'`Gn'#205#0#3'z'#183 - +#145'g'#225'G(^g'#0#31#251#201#164#22#206#135#173'h>h'#147#164#15#252'4)^c' - +#153#197#128'^Y'#21#255#160#180'/'#169#250#144#248'p'#224')'#1#187#164#242 - +#150#164#189#1'~'#171#213#154#141'F#'#246#236#147#169#151'~X'#213#253'e'#227 - +#130#0#202#227#128#127#192#16#1'=H'#28':'#164#127's2'#17#173'['#244#0#162#216 - +#168'+'#26#129#171#13#176#143#0#175#229#228'#'#223#135'Ya'#200' 8@'#6#128#174 - +#158'`'#132'a'#142'|<"'#132#246'x'#17#183#146'4'#168#207#179#176#190'H'#131 - +'Z'#170#160#219'k'#251#221'8'#245#140'K'#191'T'#13#184'$'#239#223#141#8#228 - +#203'~t5'#20'h'#134'['#251#239#185#210#221#253#191#6'n'#228#167#211#208#207 - +'fQ'#144#204#234#225'bL'#18'~'#16'.'#3#188#233#18'"'#182'C'#174#127#145#168 - +#248'E'#214#30'-'#11'g'#218'-'#171#234'+'#157#190#203#224#167'{'#224#18#192 - +#144'#'#179'I'#194#210#254#2#248'O'#31#23#4#176'|,%'#2'Z'#135#244'@'#177'F'#0 - +'`'#211#186'I*f'#139#236'J'#214#10#132#16#12#9'X"@'#19#18#218#6'y'#212'@'#6 - +' '#2#218#14#133#12'|'#218#151#194#2#206#177#169#16#130#178#128'N'#179' '#154 - +'fQm'#158#16')'#164'!'#19'C'#146#250#181'E'#22#214'r'#195#2'y'#17#247#207#221 - +#219#235#29#248'y2'#242#165#155#252#170'R'#11'0'#253'7'#240#178'E'#236#167 - +#179#200'O'#166'Q'#152#206#226' '#153#214'BZ'#252'd^'#10#31#28#4#188#212#222 - +#235#20']Ro'#178#220#168#19#185'JM'''#30'U'#150#246'('#207#157'J?>'#11'|'#168 - +#251't'#157#135#0#191#0#30'j>&'#221#132'I0E'#6#159#249#172'%'#192'_'#242'K?' - +#188#227#130#0#158'<'#150#18#1'|'#4#237'6'#201#183#217#140';'#20#19#1#160#203 - +#144#169'5h'#201#186'm'#246#141#198#0#243'@i'#13#2#4#2'2`"'#144#133#181#2'!' - +#4#175'B'#8#162#229#235'F'#0'E*'#191#201#243#247#2'"'#129'('#205#252' '#205 - +#149#159#229'~'#0#19'"'#203#184#160')'#160#181#143#207'&'#158#241#233'8'#142 - +#249'x'#15' '#233'{y'#202#139#162'Wy'#10#219#153'g'#142'y'#244#137'~'#158#6#4 - +'N'#218'N#?K0C'#14#127#181#237#249#167#247#204'1}Z'#185#20#11'j'#213#222#145 - +#240#12'B'#237#197#183'q{+'#237'Mi'#174#210#192#159'HW'#158#145'*'#128#15#169 - +#143#184'='#239#147#186#143#10#189'1'#173'!'#241#209#140'snl'#252'G'#143#30 - +'e'#23#192#127#250#184' '#128#163#13'K'#4#223#253#238'w=4%'#5#25#208#161#144 - +#164'N'#212'l6'#1'd'#214#10#232#129'lxz'#174'B'#180'('#3#240#153#4'h'#223#144 - +'C'#211#209#10'jB'#6#136#30'DJG'#16't'#20'A'#19#2#242#10#8#139#220#2'Dr'#130 - +#217'y^'#164#249#225#143#239#219'm'#140#220'sN'#250#224#207#240#14#252'#?' - +#176#225#202#240#138#242' '#249#0'z;/'#210#133'9'#25#152#147'!3'#237'P'#212 - +#21'x'#158#199#217#3'.'#224#233'X"'#221'vy'#150#29#167'@'#7#224#7#152'a'#223 - +#143' '#229#165' '#135#215't|'#4#208'C'#210#3#244#240#230'c!'#2'^'#192#171'O' - +#199#211#11#224'?'#219#184' '#128'g'#27'%"@'#212#224#210#165'K>I'#164#144#30 - +'D&'#3#180''''#4#168#145'a'#8'2'#192#2'2P'#152#202#220'Y'#132#8#140'i'#192 - +#230#1'k'#5#30';'#14']B`2'#160'c'#1'b'#8#162#29'0'#17#152#22' '#24'y'#145#223 - +#167'r'#183#11'`'#165#17#192#129'y'#9#151#254'J'#227#225'We'#253'_)'#227#164 - +#211'h'#215'L$'#130']'#25#231#157#150#242#136#238#231'6Vo='#248#6#240'R'#142 - +'k'#194'x'#0#255'd'#137#212#231'E'#18'vX'#189#23#21#127#14#208'c'#166']'#196 - +#241'WVV2x'#245#137#148#243#11#224'?'#219#184' '#128#247'7l^-'#194#135#244#16 - +'z'#198'<'#160#135#18#128'E'#143'B6'#17#224'/'#160'}'#16'B'#131#164#22#8#129 - ,'5'#0#172'}'#157'Q'#216#144'F'#165'L'#4'R'#177#200#239#177'D'#160#29#136#161 - +#199'A}'#144#129'v '#210#182#246#31'(]'#151' '#219#170#152'}'#132#165's'#209 - +'4'#200#156#244'!, '#160'Vy^v'#3'j'#183#164'W'#184#253#10'U>7'#157't'#217#129 - +''''#222'{'#165#165#188#5#190'S'#127#207'^|'#165#165'=/p'#236#161#209#6#253 - +'~'#168#243#19#172'%'#166'?!'#160'c'#31#196'0C=>'#169#247' '#142#132#142'!y' - +#7#128#207#156'8'#190#156#253#5#232#159'e\'#16#192#7#27#150#8#240#0#186'Z'#1 - +'I'#168'`gg'#7'R;'#132#137#0#243#20'd'#0'p'#139#218'_'#23#240'#'#215#192#128 - +#159'5'#2'G30D`4'#3#215'g`'#9'Ai'#13#1'$'#16'pI?'#231#28's'#242#156'''`'#247 - +#12#17'('#19';8D'#19'p'#192#207#0'/'#8'AK~'#165'{'#230#27#213'>'#173#0#222 - +#196#233#141#138'o'#156'y'#0#191#241#228'O'#5#220'v'#27#199#1'~'#243#127#168 - +#245'x}'#20'Es'#0#31#210#30#234'='#17'jz'#227#198#141#20#160#135#180'w'#242 - +#245#249'|O'#251'a8'#143#227#130#0#158#223'8'#160#21#12#6#3#175#211#233#4#180 - +#248#244#0#179#153#0'I'#14'S'#129#30#234#152#30'n'#164#31'C'#202#215#232'X' - +#141#142#25'S'#192#152#5#150#4#232#189#186'eY'#161#21#132'UBP'#154#20'x'#246 - +'$!'#4#156#147'/'#224#247'DK'#176#219#149#243#182#170#188'2'#210#221#181#225 - +'s''>/'#210']z'#234#25#208'/'#28#208'W'#213'|+'#245'E'#221#231#181#144#194#12 - +'*=IwH'#249#5'@O@_'#200'g&'#0'=T|c'#219#11#232#205'y'#186#235#139#241'>'#198 - +#5#1#28#207'Xj"'#208#218#7#25'@3'#160#7#157'M'#5','#4'nL'#127#142#233#206'"' - +#151#16'|'#157'?`4'#6#248#22'P'#189#24#11#17'D'#134#16'@*'#244#186'RD'#1'D@' - +#175'E'#196#194#19'2`"'#192#182#28#243#212#146'x`'#201#142'/'#0#159#27#21'_' - +#21'j=7'#212#196'B'#223#195#192#167#207#157#211#246#1#2#192'B'#191'k'#230#2 - +#158#200#14#210#29#239'Y@'#194#131'H'#232'xj$'#189#1'=]'#175#188#162#226#187 - +#235#139#241#1#199#5#1#28#239#176#215#215'8'#14#141'f'#0'3aoo'#143#9'!@i'#218 - +'`'#16#192'l'#160#151#134' '#3#172'A'#8' '#7':'#206'k'#128#158'^'#202'k9'#30 - +#154#227'J'#252#4#202'1'#13#180'I'#192'f'#128'oH'#0#231#148'!.X'#144'@q'#178 - +#5#208'sQ'#237'-'#240#177#166#247'X'#201#175#196#161''''#4#176'0'#251#134#0 - +'d!<'''#6#228#144#236#176#223#23'Fk'#0#224#137#3#210#181#181#181#148'~?'#212 - +#250#140'L'#168#28#160#191'p'#232#157#204#184' '#128#147#27#165'D\'#233'Y' - +#168'@'#8#208#12'n'#222#188#233'-#'#4#12#2'M '#160#14#5#212'au'#219#172#149 - +'&'#14#214#0'0'#0'v'#1'k6'#155#217't:'#205#232#156#243'e'#18'~'#9#224#171#219#23#227#152 - +#199#5#1#156#141'Q'#186#15#198'\'#192#182'1'#25#8'H'#30'H'#129'H'#192'#py' - +#134#24#8#148#30#200#129#128#232#25'r'#160'}'#143'@j'#23':'#206#128#199'6>' - +#19#219#4'V'#187#141#181#207#253'L'#148'"'#0#27#192#243'>}/o'#155#133#190'?' - +#7#208#137'Dr'#128#156#190'+'#235#247#251'9'#129#222#2#29#146#189#221'n'#231 - +#6#236#248#156#11#192#159#205'qA'#0'gsT'#239#139''''#192'Q.1`'#13'r'#184'u' - +#235#150'7'#28#14'-9'#224'8'#8#2'k'#179'O'#192#230'5'#8#3#235#245#245'u'#187 - +'m'#6#128#140'5Iy'#11'J'#2';o'#3#220'X?~'#252'8'#199'6@'#142#253'e@'#199#250 - +#16#176'/'#219#191#24#167'8.'#8#224'|'#141'e'#247#235#0'9`'#24#130'0'#3'D' - +#177#236#3#161'Y`]'#175#215#15#0#211#128#218#29#6#224#24#0'9'#214#135#0#253 - +#176'c'#23#227#12#141#11#2'x1'#198#179#220#199#163#190#246#168#224#189#0#249 - +'9'#30#23#4'p1.'#198#135'x'#252#127'p'#251'ut'#3#215#244'"'#0#0#0#0'IEND'#174 - +'B`'#130'('#0#0#0#128#0#0#0#0#1#0#0#1#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#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#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#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#0#0#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0 - +#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#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#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#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#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#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#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#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#1#0#0#0#1#0#0#0#2#128#128#128#2'UUU'#3'@@@'#4'333'#5'III'#7'@@@'#8 - +'999'#9'999'#9'MMM'#10'FFF'#11'FFF'#11'FFF'#11'MMM'#10'999'#9'@@@'#8'@@@'#8 - +'UUU'#6'333'#5'UUU'#3#128#128#128#2#0#0#0#2#0#0#0#1#0#0#0#1#0#0#0#1#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#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#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#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#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#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#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#1#0#0#0#1#128#128#128#2'UUU'#3'UUU'#6'@@@'#8'FFF'#11'III'#14'<<' - +'<'#17'III'#21'EEE'#26'DDD'#30'DDD"EEE%AAA''DDD)AAA+AAA+AAA+DDD)AAA''GGG$FFF' - +'!DDD'#30'==='#25'@@@'#20'@@@'#16';;;'#13'FFF'#11'@@@'#8'333'#5'UUU'#3#128 - +#128#128#2#0#0#0#1#0#0#0#1#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 - +#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#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#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#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#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#1#0#0#0 - +#2'UUU'#3'+++'#6'999'#9'NNN'#13'CCC'#19'BBB'#27'GGG$DDD-CCC5DDD'#211'SC6'#219'W@0'#227'[>+'#235']<('#238'^<'''#240 - +'_<%'#243'`<#'#245'a;"'#247'a:!'#248'a;"'#246'`<$'#245'_<%'#242'^='''#240'\=' - +')'#237'Z=,'#233'V@1'#225'RD8'#217'NG?'#210'JHD'#204'IHC'#204'HHD'#204'GEC' - +#203'FEC'#202'EED'#198'EED'#195'DDC'#190'DDC'#183'DDD'#172'DDD'#157'DDD'#138 - +'DDDtCCC\DDDDCCC.@@@'#28'DDD'#15'III'#7'UUU'#3#0#0#0#1#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#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#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'UUU'#3'@@' - +'@'#8'KKK'#17'HHH CCC5CCCPDDDlCCC'#134'DDC'#156'EED'#172'FEC'#185'GFD'#193'G' - +'FC'#198'HFC'#202'IGD'#203'PE;'#213'VA0'#227']<('#239'a;#'#246'd9'#30#254'g:' - +#29#255'g:'#30#255'i<'#30#255'j='#31#255'j>'#30#255'k>'#30#255'l?'#31#255'l@' - +#31#255'mA'#31#255'nA'#31#255'm@'#31#255'l@'#31#255'l?'#31#255'k>'#30#255'j>' - +#30#255'j='#31#255'i<'#30#255'g:'#30#255'f:'#29#255'd9'#31#252'`<#'#245'[=*' - +#236'UA3'#223'MF?'#210'IHC'#204'HFD'#204'FFC'#203'FFE'#200'DDC'#197'EED'#191 - +'DCC'#182'DDD'#170'CCC'#152'CCC'#129'DDDfDDDKDDD1FFF'#29'@@@'#16'III'#7'UUU' - +#3#0#0#0#1#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#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#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#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#0#0#0#1'UUU'#3'II' - +'I'#7'@@@'#16'@@@ FFF7DDDRCCCoCCC'#140'DDC'#163'EED'#180'EED'#191'FFC'#198'I' - +'GD'#201'ME?'#208'UA2'#224'\<('#238'b9 '#250'f:'#29#255'h;'#30#255'j>'#30#255 - +'m@'#31#255'oB '#255'qD '#255'sF '#255'uH!'#255'|L#'#255#128'O$'#255#133'Q%' - +#255#136'S&'#255#139'V'''#255#143'X('#255#145'Y)'#255#142'W('#255#139'U''' - +#255#135'S&'#255#131'Q%'#255#128'O$'#255'yK"'#255'tG!'#255'rE '#255'pD '#255 - +'nA '#255'l@'#31#255'j='#31#255'g;'#30#255'e9'#29#255'a;!'#247'Z=+'#234'RB5' - +#221'JGC'#207'HFD'#204'FEC'#203'FFE'#200'EED'#196'DDC'#189'DDD'#177'CCC'#159 - +'DDD'#135'CCCjBBBMBBB2FFF'#29'III'#14'UUU'#6#128#128#128#2#0#0#0#1#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#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#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#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#2'333'#5';;;'#13'BBB'#27'AAA3BBBQDDDqDDD'#142'EED'#165 - +'EDB'#183'FEC'#194'HFD'#200'IFB'#205'SA3'#223'^;&'#242'e8'#29#255'g;'#30#255 - +'j>'#31#255'mA'#31#255'pD!'#255'tG!'#255'~M#'#255#141'W('#255#151']*'#255#160 - +'c-'#255#169'i0'#255#178'n1'#255#181'q2'#255#182's3'#255#183't3'#255#184't3' - +#255#184'v3'#255#185'v4'#255#186'w3'#255#185'v3'#255#184'u3'#255#184't3'#255 - +#183't3'#255#182'r3'#255#181'q2'#255#175'l1'#255#166'h/'#255#158'a,'#255#149 - ,'\*'#255#138'U('#255'zK"'#255'sF '#255'pC '#255'l@'#31#255'i='#31#255'g;'#30 - +#255'c8'#31#252'[<*'#237'RC8'#218'IGD'#205'HFD'#204'EED'#201'DDC'#198'EED' - +#191'DDD'#179'CCC'#161'DDD'#136'CCCkEEEJDDD-@@@'#24'FFF'#11'@@@'#4#0#0#0#1#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#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#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#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#1'UUU'#3'999'#9'FFF'#22'CCC*DDDGDDDiCCC'#138'EED'#165'FEC'#184'FEC'#194 - +'HHD'#200'QC9'#216'[<*'#237'c8'#31#253'g;'#30#255'j>'#31#255'nA '#255'sF!' - +#255'|M#'#255#141'W('#255#158'a,'#255#173'k1'#255#181'r3'#255#185'v4'#255#187 - +'y4'#255#189'{4'#255#191'~5'#255#193#129'5'#255#195#131'5'#255#196#132'6'#255 - +#197#134'6'#255#198#134'6'#255#199#136'6'#255#200#136'6'#255#200#137'6'#255 - +#199#136'6'#255#198#135'6'#255#198#134'6'#255#197#133'5'#255#196#132'6'#255 - +#195#131'5'#255#193#128'5'#255#191'~4'#255#188'z4'#255#186'x4'#255#184'u3' - +#255#181'q2'#255#168'i/'#255#153'_+'#255#137'T'''#255'yJ"'#255'rE '#255'm@' - +#31#255'i<'#31#255'f:'#30#255'b9!'#249'X>.'#232'MD>'#212'HFD'#204'EED'#202'E' - +'ED'#198'EED'#192'CCC'#180'CCC'#160'DDD'#132'DDDbCCCACCC&CCC'#19'@@@'#8'UUU' - +#3#0#0#0#1#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#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#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#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#1'333'#5 - +'III'#14'>>>!DDD'#255 - +#232#177'>'#255#234#179'?'#255#236#181'>'#255#236#182'?'#255#237#183'?'#255 - ,#237#183'?'#255#238#183'@'#255#238#184'?'#255#238#185'?'#255#238#184'?'#255 - +#238#183'@'#255#237#182'?'#255#237#183'?'#255#236#182'?'#255#236#181'>'#255 - +#234#179'>'#255#232#176'>'#255#230#175'>'#255#229#172'='#255#227#169'='#255 - +#224#167'='#255#220#161'<'#255#217#157'<'#255#213#153';'#255#209#148':'#255 - +#204#142'9'#255#198#135'8'#255#193#129'7'#255#188'{6'#255#183't5'#255#171'k2' - +#255#142'W)'#255'tH"'#255'nA '#255'h<'#31#255'd7'#30#255'[:('#240'KD?'#211'G' - +'FD'#204'DDC'#201'EDD'#195'CCC'#182'CCC'#159'CCC}EEEUBBB2@@@'#24'999'#9'UUU' - +#3#0#0#0#1#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#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#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#1'333'#5'III'#14'BBB#EEECCCCkEEE'#145'DDC'#174'FFE'#192'KE@'#206'Z;)' - +#238'c8'#30#255'i<'#31#255'oB!'#255'|M%'#255#153'_-'#255#178'o4'#255#186'x6' - +#255#192#128'7'#255#198#135'9'#255#204#142':'#255#209#149';'#255#214#155'=' - +#255#219#161'>'#255#223#167'>'#255#227#170'>'#255#230#174'?'#255#232#177'@' - +#255#235#181'A'#255#237#183'A'#255#238#185'A'#255#240#187'A'#255#241#188'A' - +#255#242#189'B'#255#243#190'A'#255#244#191'B'#255#244#192'B'#255#244#191'B' - +#255#244#192'B'#255#244#192'B'#255#245#193'A'#255#244#192'B'#255#244#192'B' - +#255#244#191'B'#255#244#192'B'#255#244#191'B'#255#243#190'A'#255#242#189'B' - +#255#240#187'A'#255#239#186'A'#255#238#184'@'#255#237#183'A'#255#235#179'@' - +#255#232#176'?'#255#229#173'?'#255#226#169'?'#255#223#165'>'#255#218#160'=' - +#255#213#153'<'#255#208#147';'#255#202#140':'#255#196#133'9'#255#190'~7'#255 - +#184'v6'#255#173'l3'#255#145'Y+'#255'uH$'#255'm@ '#255'g;'#31#255'b7'#31#253 - +'U>/'#230'IEC'#206'FFE'#202'EED'#199'CCC'#189'DDD'#170'DDD'#139'BBBdCCC=BBB' - +#31'@@@'#12'UUU'#3#0#0#0#1#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 - +#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#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#1'UUU'#6'KKK'#17'DDD)EEENDDDxDCC'#157'DDC'#182'GGC'#197'T=1'#225'a7 ' - +#252'g;'#31#255'l@ '#255'wI$'#255#154'^.'#255#179'o6'#255#186'x7'#255#193#128 - +'9'#255#200#137':'#255#207#146'<'#255#212#153'>'#255#217#159'>'#255#222#166 - +'?'#255#227#170'@'#255#231#175'A'#255#234#180'B'#255#236#182'B'#255#238#185 - +'B'#255#240#187'B'#255#242#190'D'#255#243#191'C'#255#244#192'D'#255#245#193 - +'C'#255#246#194'D'#255#247#194'D'#255#247#196'E'#255#247#196'D'#255#247#196 - +'D'#255#248#197'D'#255#248#197'D'#255#248#197'D'#255#248#197'D'#255#248#197 - +'D'#255#248#197'D'#255#248#196'D'#255#247#196'D'#255#247#196'D'#255#247#195 - +'E'#255#246#195'D'#255#245#193'D'#255#245#193'C'#255#244#192'D'#255#243#191 - +'C'#255#242#189'C'#255#240#186'C'#255#238#184'C'#255#236#182'B'#255#233#179 - +'B'#255#230#174'A'#255#226#169'@'#255#221#164'?'#255#216#157'>'#255#211#151 - +'='#255#205#143'<'#255#198#135':'#255#191#127'8'#255#184'w7'#255#174'l4'#255 - +#144'X+'#255'rE"'#255'j> '#255'e9'#30#255'_8"'#247'O@8'#219'GFD'#204'DDC'#201 - +'CCC'#194'CCC'#178'DDD'#151'DDDqDDDGGGG$III'#14'@@@'#4#0#0#0#1#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#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#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#2'III'#7'@@@'#20'CCC.DDDVCCC'#130'EED'#165'DDC'#189 - +'LB='#207']7$'#244'd7'#31#255'j> '#255'qE"'#255#140'W+'#255#174'l5'#255#186 - +'x8'#255#193#129':'#255#200#138'<'#255#207#146'>'#255#213#155'?'#255#220#163 - +'@'#255#225#169'A'#255#229#174'B'#255#233#179'D'#255#236#182'D'#255#239#185 - +'D'#255#241#189'E'#255#242#190'E'#255#244#192'E'#255#245#194'E'#255#246#195 - +'F'#255#247#195'F'#255#247#196'G'#255#247#197'F'#255#248#197'F'#255#248#197 - +'F'#255#249#198'F'#255#249#198'G'#255#249#198'G'#255#249#198'G'#255#249#198 - +'G'#255#249#198'G'#255#249#198'G'#255#249#198'G'#255#249#198'G'#255#249#198 - +'G'#255#249#198'G'#255#249#198'G'#255#249#198'F'#255#248#197'F'#255#248#197 - +'F'#255#247#196'F'#255#247#196'F'#255#247#195'F'#255#246#194'F'#255#244#193 - +'F'#255#243#191'E'#255#242#190'E'#255#240#188'E'#255#238#185'D'#255#235#181 - +'D'#255#232#178'C'#255#228#172'C'#255#223#167'B'#255#218#161'@'#255#212#153 - +'?'#255#205#144'='#255#198#135';'#255#191#127'9'#255#183'u7'#255#167'g3'#255 - +#130'P('#255'oB"'#255'h< '#255'c7'#30#255'X:*'#237'HFB'#207'EEE'#202'DCC'#197 - +'DDD'#184'CCC'#160'CCCzEEENFFF(@@@'#16'333'#5#0#0#0#1#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#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 - +#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#2 - +'III'#7'FFF'#22'BBB2CCC\DDD'#136'DDC'#171'EED'#192'Q?5'#219'a6'#31#252'f:'#31 - +#255'mA!'#255#127'N'''#255#164'f3'#255#182'u8'#255#190#127':'#255#199#138'=' - +#255#207#147'?'#255#213#155'A'#255#220#163'B'#255#225#170'D'#255#230#177'E' - +#255#234#181'E'#255#237#184'F'#255#240#188'G'#255#242#189'G'#255#243#192'G' - +#255#244#193'H'#255#245#194'H'#255#246#195'H'#255#247#196'H'#255#247#197'H' - +#255#247#197'H'#255#248#198'H'#255#248#198'H'#255#248#197'H'#255#248#198'H' - +#255#248#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I' - +#255#249#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I' - +#255#249#198'I'#255#249#198'I'#255#248#198'I'#255#248#198'H'#255#248#198'H' - +#255#248#198'H'#255#248#198'H'#255#247#197'H'#255#247#196'I'#255#247#195'H' - +#255#246#195'H'#255#245#195'H'#255#244#193'H'#255#243#191'G'#255#241#189'G' - +#255#239#186'G'#255#236#183'F'#255#233#180'F'#255#229#175'D'#255#224#168'D' - +#255#218#161'B'#255#211#153'@'#255#205#144'?'#255#196#134'='#255#188'{:'#255 - +#180'r8'#255#155'_/'#255'wJ$'#255'j? '#255'e8'#30#255']8#'#246'LB<'#213'FEE' - +#203'EED'#199'DDD'#188'DDD'#165'DDD'#128'DDDSFFF,GGG'#18'+++'#6#0#0#0#1#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#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#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 - +#2'III'#7'CCC'#23'BBB6DDDaCCC'#141'DDC'#174'GDB'#196'V:+'#233'c7'#30#255'h; ' - +#255'pC#'#255#146'Z-'#255#179'p7'#255#187'{;'#255#196#133'='#255#204#144'?' - +#255#212#154'B'#255#219#163'E'#255#225#170'E'#255#230#176'G'#255#234#181'H' - +#255#238#185'I'#255#240#189'I'#255#242#190'J'#255#243#192'J'#255#244#193'J' - +#255#245#195'J'#255#246#195'J'#255#246#196'J'#255#247#196'K'#255#247#196'K' - +#255#247#197'K'#255#247#197'K'#255#247#197'K'#255#247#197'J'#255#247#197'J' - +#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J' - +#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J' - +#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#197'J' - +#255#247#197'J'#255#247#197'J'#255#247#197'K'#255#247#197'K'#255#247#197'K' - +#255#247#196'K'#255#246#196'K'#255#246#196'J'#255#246#195'J'#255#245#195'J' - +#255#244#194'J'#255#243#191'I'#255#241#189'I'#255#239#188'I'#255#236#184'H' - +#255#233#180'H'#255#228#174'G'#255#223#168'E'#255#217#160'C'#255#210#151'B' - +#255#202#141'?'#255#193#130'<'#255#185'x:'#255#174'm6'#255#134'S*'#255'mA"' - +#255'f:'#31#255'a6'#30#253'R>4'#224'FFE'#203'EED'#200'CCC'#190'DDD'#169'CCC' - +#133'CCCXAAA/CCC'#19'+++'#6#0#0#0#1#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#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#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'CCC'#23'BBB6CCCcCCC'#144'EED'#177'JC>'#202 - +'[6"'#244'c8'#31#255'j?!'#255'xI&'#255#162'd2'#255#183'u:'#255#192#129'='#255 - +#200#140'@'#255#209#150'B'#255#217#160'E'#255#223#169'G'#255#229#176'H'#255 - +#233#181'J'#255#236#185'J'#255#239#188'K'#255#241#190'K'#255#242#192'K'#255 - +#243#193'L'#255#244#194'L'#255#245#195'L'#255#245#195'L'#255#245#195'L'#255 - +#246#196'L'#255#246#196'L'#255#246#196'L'#255#246#196'L'#255#246#196'M'#255 - +#246#196'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255 - +#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255 - +#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255 - +#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#196'M'#255 - +#246#196'M'#255#246#196'M'#255#246#196'L'#255#246#196'L'#255#246#196'L'#255 - +#246#196'L'#255#245#195'L'#255#245#196'L'#255#244#195'M'#255#244#194'L'#255 - +#243#193'L'#255#242#192'L'#255#241#190'K'#255#238#188'K'#255#236#184'J'#255 - +#232#179'I'#255#228#173'H'#255#222#166'F'#255#215#158'E'#255#207#148'B'#255 - +#198#137'?'#255#190'~<'#255#180'r9'#255#150']/'#255'qE$'#255'h< '#255'b6'#30 - +#255'W9*'#235'GED'#204'DDC'#201'DDD'#192'CCC'#172'CCC'#137'DDDZAAA/GGG'#18'3' - +'33'#5#0#0#0#1#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#1'+++'#6'II' - +'I'#21'CCC5DDDbCCC'#145'DDC'#178'LB;'#206'^6 '#249'd8'#31#255'l@!'#255#131'Q' - +'*'#255#172'k7'#255#186'z;'#255#196#133'?'#255#205#146'C'#255#213#156'E'#255 - +#220#165'G'#255#227#173'I'#255#232#180'K'#255#236#184'L'#255#238#187'L'#255 - ,#240#189'N'#255#241#191'N'#255#242#192'N'#255#243#193'N'#255#244#194'N'#255 - +#244#194'N'#255#244#194'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255 - +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255 - +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255 - +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255 - +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255 - +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255 - +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255 - +#244#195'O'#255#244#195'O'#255#244#194'O'#255#244#195'N'#255#244#194'N'#255 - +#243#193'N'#255#242#192'M'#255#241#190'N'#255#240#189'M'#255#237#186'M'#255 - +#235#182'L'#255#230#178'K'#255#225#171'I'#255#219#163'G'#255#211#153'D'#255 - +#202#143'B'#255#192#130'>'#255#183'u:'#255#164'f4'#255'yK&'#255'i=!'#255'c7' - +#30#255'Z8%'#241'GEC'#205'DDC'#201'CCC'#193'DDD'#173'DDD'#136'BBBYDDD-KKK'#17 - +'333'#5#0#0#0#1#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#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#0#0#0#0#0#1'333'#5'CCC'#19'BBB2CCC_DD' - +'D'#143'DDC'#178'M@8'#211'_5'#31#251'e9'#31#255'lA"'#255#144'Y/'#255#179'r9' - +#255#188'}='#255#198#138'B'#255#208#149'D'#255#217#161'H'#255#223#170'K'#255 - +#229#177'L'#255#234#181'M'#255#236#186'N'#255#239#188'O'#255#240#190'P'#255 - +#241#191'P'#255#242#192'P'#255#242#192'P'#255#242#193'P'#255#243#193'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255 - +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#193'P'#255 - +#242#193'P'#255#242#192'O'#255#242#192'P'#255#241#192'P'#255#240#190'P'#255 - +#238#188'O'#255#236#185'N'#255#232#180'M'#255#228#175'L'#255#222#167'I'#255 - +#215#159'H'#255#205#147'D'#255#196#134'@'#255#186'y<'#255#173'm7'#255#130'O*' - +#255'j?!'#255'c8'#31#255'[7#'#245'HDA'#208'DDC'#201'CCC'#193'CCC'#172'CCC' - +#134'AAAVAAA+@@@'#16'@@@'#4#0#0#0#1#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#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#1'@@@'#4'<<<'#17'CCC.CC' - +'C[CCC'#140'EED'#176'O>5'#213'_5'#30#253'e9'#31#255'nB#'#255#151'\1'#255#181 - +'s:'#255#191#129'@'#255#201#142'C'#255#211#154'G'#255#219#164'K'#255#226#173 - +'M'#255#231#179'O'#255#234#184'P'#255#237#187'Q'#255#239#189'Q'#255#240#190 - +'R'#255#240#191'Q'#255#241#192'R'#255#241#192'R'#255#241#192'R'#255#242#192 - +'R'#255#242#192'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193 - +'R'#255#242#192'R'#255#242#192'R'#255#241#192'R'#255#241#192'R'#255#241#192 - +'R'#255#240#191'Q'#255#240#190'R'#255#238#189'Q'#255#236#186'P'#255#234#182 - +'O'#255#230#177'N'#255#224#171'L'#255#217#162'J'#255#208#150'F'#255#198#138 - +'C'#255#188'}>'#255#177'o:'#255#136'S,'#255'k?"'#255'c8'#31#255'\6!'#248'JC?' - +#211'DCC'#201'CCC'#193'CCC'#171'BBB'#131'DDDRAAA''777'#14'UUU'#3#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#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 - +'UUU'#3';;;'#13'AAA''CCCTBBB'#135'DDC'#174'N=5'#213'`4'#29#254'e9'#31#255'oC' - +'$'#255#156'`3'#255#181'u<'#255#193#131'A'#255#204#146'E'#255#213#157'I'#255 - +#221#167'M'#255#227#175'O'#255#232#180'Q'#255#235#184'R'#255#237#187'S'#255 - +#238#189'S'#255#239#190'S'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - ,#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#234#187'R'#255#202#161'G'#255#232#185'R'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255 - +#239#189'S'#255#238#188'R'#255#236#186'R'#255#234#184'Q'#255#231#179'Q'#255 - +#226#173'O'#255#219#165'L'#255#211#154'H'#255#201#142'E'#255#190#128'@'#255 - +#179'q:'#255#140'V.'#255'l@"'#255'c8'#31#255'\4'#31#250'JC>'#211'CCC'#201'DD' - +'D'#192'CCC'#168'CCC~DDDKFFF!MMM'#10#128#128#128#2#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#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#128#128#128#2'333'#10'@@@ EEE' - +'JCCC~EDD'#169'L?8'#208'^4'#30#253'd8 '#255'pD%'#255#159'b4'#255#182'v='#255 - +#194#132'C'#255#205#147'H'#255#215#160'L'#255#222#169'O'#255#228#176'Q'#255 - +#232#181'S'#255#235#185'T'#255#236#187'T'#255#237#188'U'#255#238#189'U'#255 - +#238#190'U'#255#238#190'U'#255#238#191'U'#255#239#190'U'#255#239#190'U'#255 - +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255 - +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255 - +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#181#144'@'#255 - +';/'#21#255#21#16#7#255#9#7#3#255#2#2#1#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1 - +#1#255#7#6#3#255#17#14#6#255#31#25#11#255'2'''#18#255'SB'#29#255#157'}8'#255 - +#233#186'S'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255 - +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255 - +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255 - +#239#190'U'#255#239#190'U'#255#239#190'U'#255#238#190'U'#255#238#190'U'#255 - +#238#190'U'#255#238#189'U'#255#237#188'U'#255#236#186'T'#255#234#184'T'#255 - +#231#180'S'#255#226#175'Q'#255#220#166'N'#255#212#156'K'#255#202#143'F'#255 - +#190#129'A'#255#179'r<'#255#145'Y0'#255'k?"'#255'c7'#31#255'[4 '#248'IC@'#209 - +'DDD'#200'CCC'#190'CCC'#163'DDDtCCCAEEE'#26'III'#7#0#0#0#1#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#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#1'III'#7'==='#25'AAA?CCCsBBB' - +#162'K?;'#202'^4'#30#252'c8 '#255'oB%'#255#160'b5'#255#183'v>'#255#194#134'D' - +#255#205#148'J'#255#215#161'M'#255#223#171'Q'#255#228#177'T'#255#232#182'U' - +#255#234#185'V'#255#236#187'V'#255#236#187'V'#255#237#188'W'#255#237#189'W' - +#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W' - +#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W' - +#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W' - +#255#237#188'W'#255#237#188'W'#255#159'~:'#255#16#13#6#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#16#13#6 - +#255'9-'#21#255'y`,'#255#208#165'M'#255#237#188'W'#255#237#188'W'#255#237#188 - +'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188 - +'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188 - +'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#189'W'#255#237#188 - +'W'#255#236#187'V'#255#235#186'V'#255#234#184'U'#255#231#180'U'#255#227#175 - +'R'#255#221#169'Q'#255#213#157'L'#255#202#144'H'#255#191#129'C'#255#180's=' - +#255#145'X0'#255'j>#'#255'b6'#31#255'Z5#'#245'GDB'#206'DDD'#200'CCC'#186'DDD' - +#154'EEEhBBB6@@@'#20'333'#5#0#0#0#1#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#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#1'@@@'#4'GGG'#18'AAA3DDDfCCC'#152'IA>'#195'\4 '#250'c7'#31#255'm@#'#255 - +#156'_5'#255#182'v?'#255#194#134'E'#255#206#148'K'#255#215#161'O'#255#223#171 - +'S'#255#228#178'V'#255#232#182'V'#255#233#185'X'#255#234#186'X'#255#235#187 - +'X'#255#236#187'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188 - +'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188 - +'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188 - +'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255'9-'#21 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#6 - +#5#2#255'$'#29#14#255'ZH"'#255#169#135'@'#255#234#186'X'#255#236#188'X'#255 - ,#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255 - +#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255 - +#236#188'X'#255#236#187'X'#255#235#187'Y'#255#235#186'X'#255#234#186'X'#255 - +#233#184'W'#255#231#180'W'#255#227#176'T'#255#221#169'R'#255#213#158'N'#255 - +#203#145'J'#255#192#130'D'#255#179's='#255#139'U/'#255'i="'#255'a5'#30#255'X' - +'7%'#242'FDC'#204'CCC'#198'DDD'#180'CCC'#144'CCC[AAA+III'#14'UUU'#3#0#0#0#1#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#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#128#128#128#2'@@@'#12'AAA''CCCWCCC'#140'GB?' - +#185'Z4!'#247'a6'#30#255'j?"'#255#151']2'#255#181't>'#255#194#133'F'#255#206 - +#149'M'#255#215#161'Q'#255#223#170'T'#255#228#178'W'#255#231#181'Y'#255#232 - +#183'Y'#255#233#185'Z'#255#234#185'Y'#255#234#186'Y'#255#234#186'Y'#255#234 - +#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234 - +#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234 - +#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234 - +#186'Z'#255#234#186'Z'#255'C5'#26#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#1#1#1#255#20#16#8#255'K;'#29#255#189#150'I'#255#234#186'Z'#255#234#186 - +'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186 - +'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Y'#255#234#186 - +'Y'#255#234#185'Y'#255#233#185'Z'#255#232#183'Y'#255#230#181'X'#255#226#176 - +'W'#255#221#169'T'#255#213#159'O'#255#203#145'K'#255#190#129'D'#255#178'p=' - +#255#134'Q-'#255'g;"'#255'`4'#29#255'U7('#238'CCC'#202'DDD'#195'DDD'#173'BBB' - +#131'CCCL@@@ 999'#9#0#0#0#2#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 - +#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#1'III'#7'BBB'#27'CC' - +'CEDDD|DDD'#170'V6%'#238'`5'#30#255'h<"'#255#145'Y1'#255#179's?'#255#192#132 - +'F'#255#205#148'M'#255#215#161'R'#255#222#171'U'#255#227#176'X'#255#230#181 - +'Z'#255#231#183'Z'#255#232#183'['#255#232#184'['#255#233#185'['#255#233#185 - +'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185 - +'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185 - +'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185 - +'['#255#233#185'['#255#233#185'['#255#127'd1'#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#13#11#5 - +#255'N>'#31#255#193#153'L'#255#233#185'['#255#233#185'['#255#233#185'['#255 - +#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255 - +#233#185'['#255#233#184'['#255#232#184'['#255#232#183'Z'#255#231#182'Z'#255 - +#229#180'Y'#255#226#175'X'#255#220#168'U'#255#213#158'R'#255#201#144'K'#255 - +#189#127'D'#255#175'n<'#255#128'N+'#255'e9 '#255'_3'#29#255'Q;1'#227'CCC'#201 - +'CCC'#191'CCC'#163'CCCrAAA;FFF'#22'333'#5#0#0#0#1#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'@@@'#4'<<<' - +#17'AAA3EEEhCCC'#156'R:/'#220'_3'#29#255'e: '#255#134'Q-'#255#178'p>'#255#190 - +#130'F'#255#203#145'M'#255#213#161'S'#255#221#170'W'#255#226#176'Z'#255#229 - +#180'Z'#255#230#182'\'#255#231#182'\'#255#231#183'\'#255#231#183'\'#255#231 - +#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231 - +#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231 - +#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231 - +#183'\'#255#231#183'\'#255#231#183'\'#255#180#142'G'#255#1#1#1#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#15#12#6#255'VE"'#255#215#171'V'#255 - +#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255 - +#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#182'\'#255 - +#230#181'['#255#228#178'['#255#225#175'Y'#255#219#168'W'#255#211#156'Q'#255 - +#200#142'K'#255#187'|D'#255#172'k<'#255'wF('#255'c7 '#255'^1'#30#254'K@:'#214 - +'DDD'#199'CCC'#184'CCC'#148'AAA^GGG+NNN'#13'UUU'#3#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'MMM'#10'@' - +'@@$DDDSDDD'#139'L?8'#197'^1'#29#254'c7 '#255'wG)'#255#173'l<'#255#188#127'E' - +#255#201#144'N'#255#212#158'T'#255#220#169'X'#255#225#175'['#255#228#179'\' - +#255#229#180'\'#255#230#181']'#255#230#181']'#255#230#182']'#255#230#182']' - +#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']' - +#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']' - +#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']' - +#255#230#182']'#255#230#182']'#255#221#175'Y'#255#10#8#4#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255'4' - +')'#21#255#184#146'J'#255#230#182']'#255#230#182']'#255#230#182']'#255#230 - +#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#181']'#255#229 - +#182']'#255#228#180']'#255#227#178'\'#255#224#174'['#255#218#166'W'#255#209 - +#155'R'#255#198#139'K'#255#184'zC'#255#162'd8'#255'l@$'#255'a5'#30#255'Z3 ' - +#249'FBA'#206'DDD'#196'CCC'#174'CCC'#129'BBBIFFF'#29'@@@'#8#0#0#0#1#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#0#0#0#0#0#0#0#0#0#0#0#0#1'333'#5'FF' - +'F'#22'BBB>CCCvFA?'#174'Z3'#31#248'`5'#30#255'l@$'#255#163'd9'#255#184'{D' - +#255#199#142'N'#255#210#156'T'#255#218#167'Y'#255#223#174'\'#255#226#177'^' - +#255#228#179'^'#255#228#179'^'#255#228#180'_'#255#228#180'_'#255#228#180'_' - +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_' - +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_' - +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_' - +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255'bM)'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#27#21#11#255#140'o;'#255#228#180'_'#255#228#180 - +'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180 - +'_'#255#228#179'^'#255#227#179'^'#255#226#176']'#255#222#172'['#255#216#164 - +'X'#255#207#152'R'#255#195#137'K'#255#181'tA'#255#149'Z3'#255'g<"'#255'_3'#29 - +#255'V6'''#239'CCC'#201'CCC'#190'CCC'#159'CCCkCCC5GGG'#18'@@@'#4#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#0#0#0#0#0#0#0#0#0#0#0#0#2'@@@'#12'CCC' - +'*DDD^DDD'#150'U6('#230'^2'#28#255'f:!'#255#149'Z3'#255#181'uB'#255#195#137 - +'K'#255#208#154'T'#255#216#165'Y'#255#221#172']'#255#225#176'^'#255#226#178 - +'_'#255#227#178'_'#255#227#178'_'#255#227#179'_'#255#227#179'_'#255#227#179 - +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179 - +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179 - +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179 - +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#13#10#6#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'&'#30#16#255#208#164 - +'W'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#178 - +'_'#255#227#178'_'#255#226#179'`'#255#226#177'_'#255#224#176'^'#255#220#170 - +'\'#255#214#162'X'#255#205#149'R'#255#191#131'I'#255#177'p?'#255#131'O.'#255 - +'c7 '#255']1'#29#255'N;3'#222'DDD'#199'DDD'#181'CCC'#140'DDDSDDD"999'#9#0#0#0 - +#1#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#0#0#0#0#1'+++'#6'@@@'#24 - +'EEECCCC~K=7'#193']0'#28#255'b6'#31#255#129'M,'#255#177'o@'#255#191#131'J' - +#255#204#149'S'#255#214#163'Z'#255#220#171']'#255#223#174'_'#255#225#176'`' - +#255#225#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`' - +#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`' - +#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`' - ,#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`' - +#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#161'~D'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#2 - +#255#134'i9'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255 - +#226#177'`'#255#225#178'`'#255#225#177'`'#255#224#176'_'#255#222#174'^'#255 - +#219#169']'#255#212#159'X'#255#200#144'Q'#255#187'~G'#255#170'j<'#255'qB%' - +#255'`5'#30#255'Z2'#31#250'FBA'#205'CCC'#193'DDD'#166'CCCsCCC9CCC'#19'@@@'#4 - +#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#0#0#0#0#2'@@@'#12'AAA+BBB' - +'aDBB'#155'Y3!'#244'_3'#29#255'l?$'#255#167'f;'#255#186'}H'#255#200#144'R' - +#255#211#158'Y'#255#218#168']'#255#221#172'`'#255#223#174'a'#255#223#176'a' - +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b' - +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b' - +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b' - +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b' - +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255'hR.'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255'qY2'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176 - +'b'#255#224#176'b'#255#224#176'b'#255#223#176'a'#255#223#174'`'#255#221#172 - +'_'#255#217#166']'#255#208#155'W'#255#196#139'O'#255#182'wE'#255#152'\5'#255 - +'e9!'#255'^2'#29#255'S7*'#233'DDD'#200'CCC'#183'DDD'#143'EEEUDDD"UUU'#9#0#0#0 - +#1#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#1'333'#5'@@@'#24'DDDDCCC~P8-' - +#211']0'#29#255'c8!'#255#144'V2'#255#180'uD'#255#196#138'P'#255#207#155'X' - +#255#215#165']'#255#220#171'`'#255#221#173'b'#255#222#174'a'#255#222#175'b' - +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b' - +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b' - +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b' - +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b' - +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255'VD&'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#1#1#0#255#166#132'J'#255#222#175'b'#255#222#175'b'#255#222#175 - +'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#174'a'#255#221#173 - +'a'#255#219#170'`'#255#213#163'\'#255#205#150'V'#255#192#132'M'#255#176'oA' - +#255'}K,'#255'a5'#31#255'\0'#28#254'I?;'#212'CCC'#194'DDD'#166'CCCrDDD8GGG' - +#18'@@@'#4#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#2'FFF'#11'DDD)BBB`G@<' - +#164'[1'#29#252'_3'#29#255'uD)'#255#174'l?'#255#189#130'L'#255#204#150'V'#255 - +#213#162'^'#255#217#168'`'#255#220#172'b'#255#221#173'b'#255#221#173'c'#255 - +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255 - +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255 - +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255 - +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255 - +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255'gQ.'#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - ,#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#8#6#4#255#207#163']'#255#221#173'c'#255 - +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255 - +#221#172'b'#255#219#171'b'#255#217#167'`'#255#211#159'['#255#200#145'T'#255 - +#185'{H'#255#164'd;'#255'h<#'#255'^1'#29#255'X3#'#244'DDD'#200'CCC'#183'DDD' - +#142'DDDSFFF!@@@'#8#0#0#0#1#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'@@@'#4'III'#21'EEE?DD' - +'D|S5'''#222'\1'#28#255'c8!'#255#158'_8'#255#183'yH'#255#198#142'S'#255#209 - +#158'\'#255#215#166'`'#255#218#170'b'#255#219#171'c'#255#219#171'd'#255#219 - +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219 - +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219 - +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219 - +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219 - +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#213 - +#168'b'#255#3#3#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'M<#'#255#219#172 - +'d'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172 - +'d'#255#219#171'd'#255#219#170'c'#255#217#168'b'#255#214#164'`'#255#207#153 - +'Z'#255#194#136'P'#255#178'rD'#255#139'R1'#255'a4'#31#255'\0'#28#255'L<5'#219 - +'CCC'#193'DDD'#164'CCCoCCC5@@@'#16'UUU'#3#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#1'@@@'#8 - +'BBB#CCCWHA='#158'\0'#28#253'_3'#29#255'~I+'#255#175'nB'#255#191#133'O'#255 - +#205#151'Z'#255#213#163'a'#255#216#167'c'#255#217#169'c'#255#218#170'd'#255 - +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255 - +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255 - +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255 - +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255 - +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255 - +#218#170'd'#255#218#170'd'#255'YF)'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#15#12#7#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255 - +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#169'c'#255#217#168'c'#255 - +#215#166'b'#255#211#160'_'#255#201#147'W'#255#187#127'L'#255#169'h>'#255'l=$' - +#255'^1'#29#255'W3"'#244'DDD'#199'DDD'#180'DDD'#136'DDDKBBB'#27'UUU'#6#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'UUU'#3'DDD'#15'EEE4BBBpS6)'#215'\1'#28#255'b7!'#255#158'_9' - +#255#184'{J'#255#199#144'W'#255#209#158'_'#255#214#165'c'#255#216#168'd'#255 - +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255 - +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255 - +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255 - +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255 - +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255 - +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255 - +'YD)'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#189#147'W'#255#217#168'd' - +#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd' - +#255#217#168'd'#255#216#168'd'#255#215#167'c'#255#213#164'a'#255#207#154']' - +#255#195#138'S'#255#179'tF'#255#139'R1'#255'`5'#30#255'\0'#28#255'K=7'#216'D' - +'DD'#191'DDD'#157'CCCcAAA+FFF'#11#0#0#0#1#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'+++'#6'EEE'#26'BBBIE?=' - +#144'Z0'#28#252'^2'#29#255'zF*'#255#174'mB'#255#192#135'R'#255#205#152'\'#255 - +#211#161'b'#255#214#165'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255 - +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255 - +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255 - +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255 - +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255 - +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255 - +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255'jR1'#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255'fN/'#255#215#166'd'#255#215#166'd'#255#215#166'd' - +#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd' - +#255#215#167'e'#255#214#164'c'#255#210#159'a'#255#202#148'Z'#255#187#128'N' - +#255#168'f='#255'i;#'#255'\1'#28#255'V3#'#242'CCC'#197'DDD'#173'BBB{FFF>@@@' - +#20'@@@'#4#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#1'MMM'#10'FFF(CCC_R6*'#206'\0'#28#255'`5'#31#255#154'\8' - +#255#182'yJ'#255#199#144'Y'#255#208#156'`'#255#212#163'd'#255#213#165'd'#255 - +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255 - +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255 - +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255 - +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255 - +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255 - +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255 - +#214#165'e'#255#214#165'e'#255#214#165'e'#255#135'h@'#255#2#1#1#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'b' - +'L/'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165 - +'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#213#165'e'#255#213#164 - +'d'#255#211#161'c'#255#206#154'^'#255#194#139'U'#255#177'sF'#255#135'P/'#255 - +'^3'#29#255'[/'#27#255'J>9'#213'DDD'#185'CCC'#144'DDDSHHH III'#7#0#0#0#1#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'UUU'#3 - +'<<<'#17'DDD8DBAyZ0'#29#248'\1'#28#255'uB'''#255#172'lA'#255#190#132'Q'#255 - +#203#151'^'#255#209#160'c'#255#211#162'e'#255#212#163'e'#255#212#163'e'#255 - +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255 - +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255 - +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255 - +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255 - +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255 - +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255 - +#212#163'e'#255#212#163'e'#255#212#163'e'#255#156'xK'#255#1#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'jQ2'#255#212 - +#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212 - +#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#162'e'#255#211 - +#162'd'#255#208#158'b'#255#200#147'['#255#186'~M'#255#165'd<'#255'd8!'#255'\' - +'0'#28#255'T5'''#237'CCC'#193'DDD'#162'CCCjCCC.@@@'#12#0#0#0#2#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'333'#5'GGG'#25'BB' - +'BIN:1'#174'[/'#27#255'^2'#29#255#145'T3'#255#180'vI'#255#196#142'Y'#255#206 - +#155'a'#255#209#161'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - ,#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255'O=&'#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'sX7'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#210 - +#161'f'#255#209#159'd'#255#204#153'`'#255#192#135'U'#255#175'pE'#255'~H+'#255 - +']0'#29#255'Z0'#28#253'FBA'#201'DDD'#176'CCC~FFF>CCC'#19'@@@'#4#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#1'999'#9'EEE%CCC[V3' - +'$'#222'\0'#27#255'f7!'#255#167'd>'#255#187#128'Q'#255#200#148'^'#255#207#156 - +'d'#255#209#159'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160 - +'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160 - +'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160 - +'e'#255#209#160'e'#255#209#160'e'#255#151'tI'#255'2&'#25#255#27#21#13#255#15 - +#12#7#255#7#5#3#255#7#5#3#255' '#25#16#255'P='''#255#151'tI'#255#209#160'e' - +#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e' - +#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e' - +#255#209#160'e'#255#209#160'e'#255#6#5#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#146'pF'#255#209#160'e'#255#209#160'e'#255 - +#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255 - +#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#159'e'#255 - +#206#155'c'#255#198#143'['#255#182'zM'#255#151'Y6'#255'^3'#29#255'[/'#27#255 - +'N:1'#222'DDD'#185'DDD'#142'DDDOIII'#28'+++'#6#0#0#0#1#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#2';;;'#13'DDD1F@=x[/'#28#253'\1'#28 - +#255'~G+'#255#174'oE'#255#193#137'X'#255#203#151'b'#255#207#156'e'#255#207 - +#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208 - +#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208 - +#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255'x[;' - +#255#15#12#8#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#4#3#2#255'bJ0'#255#208#158'f'#255#208#158'f' - +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f' - +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255'3'''#25#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1#255#208#158'f' - +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f' - +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f' - +#255#208#158'f'#255#207#158'e'#255#206#156'd'#255#201#149'_'#255#189#131'T' - +#255#169'h@'#255'j:#'#255'\0'#28#255'V3#'#242'DDD'#191'CCC'#156'BBB`AAA''333' - +#10#0#0#0#1#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'@@@'#4'C' - +'CC'#19'EEE?Q7+'#179'[/'#27#255'^1'#29#255#152'X6'#255#181'yM'#255#197#144']' - +#255#204#153'c'#255#206#155'f'#255#206#156'e'#255#206#156'e'#255#206#156'e' - +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e' - +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e' - +#255#202#154'c'#255'6)'#27#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#14#10#7#255#178#135'W'#255#206#156'e'#255#206#156'e'#255#206#156'e' - +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e' - +#255#206#156'e'#255'WB+'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - ,#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#29#22#14#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e' - +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e' - +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#205#156'e' - +#255#203#151'c'#255#194#139'Z'#255#176'qH'#255#131'K-'#255'\1'#28#255'[/'#27 - +#255'HA='#204'DDD'#169'DDDqEEE4III'#14#128#128#128#2#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#1'+++'#6'BBB'#27'EEENW2!'#228'[/'#27#255'i9!' - +#255#168'e?'#255#187#130'T'#255#200#147'`'#255#203#153'e'#255#205#154'e'#255 - +#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255 - +#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255 - +#205#154'e'#255#205#154'e'#255#199#150'a'#255#19#14#9#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#6#4#255#178#133'W' - +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e' - +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255'S>)'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#128'a?'#255#205#154'e'#255#205#154'e' - +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e' - +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e' - +#255#205#154'e'#255#204#154'e'#255#203#152'd'#255#197#145'^'#255#182'zO'#255 - +#157'Z8'#255']1'#29#255'[/'#27#255'P9.'#226'CCC'#179'CCC'#129'CCCA@@@'#20'@@' - +'@'#4#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#1'999'#9'EEE%EA?' - +'b[/'#27#253'\0'#27#255#127'F*'#255#173'nG'#255#191#136'Z'#255#200#149'c'#255 - +#202#152'e'#255#202#152'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255 - +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255 - +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#31#24#16#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#11#8#6#255#200#151'e'#255#202#153'e'#255#202#153'e'#255#202 - +#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255'O;''' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255''''#29#19#255#202#153'e'#255 - +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255 - +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255 - +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#152'e'#255#202#151'd'#255 - +#199#147'b'#255#188#130'U'#255#168'e@'#255'k:"'#255'[/'#27#255'V3$'#241'CCC' - +#186'BBB'#142'EEENBBB'#27'+++'#6#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#2'@@@'#12'DDD-O:0'#146'[/'#27#255'\0'#28#255#145'R2'#255#179'wM' - +#255#194#141'^'#255#200#148'c'#255#201#150'e'#255#201#150'e'#255#201#150'e' - +#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e' - +#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e' - +#255';,'#30#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'S>*'#255#201#150'e' - +#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e' - +#255#201#150'e'#255'K8&'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#29#22#14#255 - +#184#138']'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255 - ,#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255 - +#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255 - +#201#150'e'#255#200#149'd'#255#199#148'c'#255#191#136'['#255#173'mG'#255'}D(' - +#255'\0'#27#255'Z0'#28#253'DBB'#192'CCC'#152'DDDZBBB#@@@'#8#0#0#0#1#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#128#128#2'III'#14'CCC5T5'''#190'[/'#27#255 - +'_2'#29#255#162'^:'#255#184'}S'#255#195#142'`'#255#198#147'd'#255#199#148'd' - +#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd' - +#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd' - +#255#199#148'd'#255#147'mJ'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#3#2#1#255#195#144'b'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255 - +#199#148'd'#255#199#148'd'#255#199#148'd'#255'H6$'#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#3#2#1#255#23#17#12 - +#255'qT8'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199 - +#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199 - +#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199 - +#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#198#146'c'#255#193 - +#140'^'#255#178'uN'#255#143'O1'#255'\0'#28#255'[/'#27#255'J=7'#208'CCC'#161 - +'DDDfAAA+FFF'#11#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'<<<' - +#17'CCC=X1 '#227'[/'#27#255'm:"'#255#167'eA'#255#187#130'X'#255#195#143'a' - +#255#196#144'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c' - +#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c' - +#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#19#14#10#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#135'cD'#255#197#145'c'#255#197 - +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255'I5$' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#19#14#10#255'4&'#26#255'cI2'#255 - +#161'vP'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197 - +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197 - +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197 - +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197 - +#145'c'#255#197#145'b'#255#196#144'c'#255#194#140'`'#255#182'|S'#255#159'\:' - +#255']2'#28#255'[/'#27#255'Q8-'#226'DDD'#168'DDDqAAA3NNN'#13#128#128#128#2#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#4':::'#22'G@/[/'#27 - +#254'[/'#27#255'}A&'#255#167'gD'#255#180'zW'#255#181'|Y'#255#181'|Y'#255#181 - +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y' - +#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#136']C'#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#19#13#9#255#151'gJ'#255#181'|Y'#255#181'|Y'#255#181 - +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y' - +#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#171'vU'#255'1"'#24#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'}V>'#255 - +#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181 - +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y' - +#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255 - +#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181 - +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y' - +#255#181'|Y'#255#181'|Y'#255#178'wT'#255#161'];'#255'k8 '#255'[/'#27#255'V3#' - +#238'DDD'#151'CCCWFFF!@@@'#8#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'FFF'#11 - +'K:3?[/'#27#255'[/'#27#255#131'F*'#255#169'iH'#255#179'xV'#255#180'zW'#255 - +#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180 - +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255'<)'#29#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#1#1#1#255'O6&'#255#180'{W'#255#180'{W'#255#180'{W'#255#180 - +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W' - +#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255 - +#180'{W'#255#142'aE'#255#27#19#13#255#2#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255 - ,#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#5#4#255 - +#135']A'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180 - +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255'pL6'#255'+'#29#20#255'('#28#19 - +#255'*'#28#20#255'+'#29#21#255'-'#30#21#255'fF2'#255#180'{W'#255#180'{W'#255 - +#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180 - +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W' - +#255#180'{W'#255#180'{W'#255#180'{W'#255#180'zX'#255#178'vU'#255#163'_>'#255 - +'r<"'#255'[/'#27#255'X2!'#243'CCC'#152'BBBYDDD"@@@'#8#0#0#0#1#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#2'FFF'#11'N8.J[/'#27#255'[/'#27#255#135'H,'#255#170'kI'#255 - +#178'wV'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179 - +'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX' - +#255#16#11#8#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#19#13#10#255#150'fJ'#255#179'yX'#255#179 - +'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX' - +#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255 - +#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179 - +'yX'#255'~V>'#255'=)'#30#255#19#13#9#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255'$'#24#17#255#172'uT'#255#179'yX'#255#179'yX'#255#179'yX' - +#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#158'kN'#255'=)'#30#255#6 - +#4#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#6#4#3#255'?+'#31#255#164'oP'#255#179'yX'#255#179'yX'#255#179'yX'#255#179 - +'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX' - +#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255 - +#177'uU'#255#164'b@'#255'v?%'#255'[/'#27#255'Y1'#31#246'CCC'#152'BBBYDDD"@@@' - +#8#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'FFF'#11'Q7+U[/'#27#255'\0'#28#255 - +#139'J-'#255#171'lL'#255#177'wW'#255#178'wV'#255#178'wV'#255#178'wV'#255#178 - +'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV' - +#255#178'wV'#255#172'sT'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255'O5&'#255#178'wV'#255#178'wV' - +#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255 - +#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178 - +'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV' - +#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#176'wV'#255 - +'vO9'#255'7%'#27#255#16#10#8#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#11#8#6#255'9&'#28#255#137'\C'#255#178'wV'#255#178'wV'#255 - +#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255'M3%' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'4"'#25#255#178'wV' - +#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255 - +#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178 - +'wV'#255#178'wV'#255#176'tT'#255#165'cC'#255'yA'''#255'[/'#27#255'Z0'#29#250 - +'DDD'#150'CCCWFFF!III'#7#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'MMM'#10'R4' - +'''^[/'#27#255'\0'#28#255#142'M.'#255#171'nN'#255#177'uV'#255#177'wX'#255#177 - +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX' - +#255#177'wX'#255#177'wX'#255#177'wX'#255'gF3'#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#23#16#12#255#152'fK'#255#177 - +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX' - +#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255 - +#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177 - +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX' - +#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#173'uV'#255 - +#136'\D'#255#133'YB'#255#131'XA'#255#128'V@'#255#153'gL'#255#177'wX'#255#177 - +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX' - +#255#177'wX'#255#177'wX'#255'S8)'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255'"'#23#17#255#175'wX'#255#177'wX'#255#177 - +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX' - +#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#175'tU'#255 - +#166'eE'#255'}B)'#255'\0'#28#255'[/'#28#253'CCC'#148'CCCTBBB'#31'III'#7#0#0#0 - ,#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'999'#9'V4%h[/'#27#255'\0'#28#255#145'O0' - +#255#171'mN'#255#175'sU'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255 - +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175 - +'uW'#255'*'#29#21#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2 - +#1#1#255'X;,'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255 - +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175 - +'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW' - +#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255 - +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175 - +'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW' - +#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255 - +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255'^?/'#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255'$'#24#18#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255 - +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175 - +'uW'#255#175'uW'#255#175'uW'#255#175'sT'#255#166'eE'#255#128'D*'#255'\0'#28 - +#255'[/'#27#255'ECB'#149'CCCP@@@'#28'UUU'#6#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#1'@@@'#8'W3#q[/'#27#255'\1'#29#255#150'Q1'#255#171'mN'#255#174'sU'#255 - +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175 - +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#15#10#8#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#4#3#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#29#19#14#255#156'iM'#255#175'uV'#255 - +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175 - +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV' - +#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255 - +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175 - +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV' - +#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255 - +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175 - +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#11#7#6#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255'sM9'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255 - +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175 - +'tV'#255#174'rS'#255#167'fG'#255#131'G,'#255'\0'#28#255'[/'#27#255'GA?'#150 - +'CCCLGGG'#25'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'W3#k[/'#27 - +#255'\1'#29#255#149'P2'#255#169'lM'#255#174'qT'#255#175'tV'#255#175'tV'#255 - +#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175 - +'tV'#255#175'tV'#255#175'tV'#255#9#6#4#255#0#0#0#255#0#0#0#255#0#0#0#255#136 - +'ZC'#255'T8*'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#5#3#255 - +'bA0'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV' - +#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255 - +#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175 - +'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV' - +#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255 - +#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175 - +'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV' - +#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255 - +#165'nR'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#10#7#5#255#175'tV'#255#175 - +'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV' - +#255#175'tV'#255#175'tV'#255#175'tV'#255#174'sU'#255#173'qR'#255#166'eG'#255 - +#131'F,'#255'\0'#28#255'[/'#27#255'EA?'#145'DDDGFFF'#22'@@@'#4#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#1'333'#5'W3#\[/'#27#255'\1'#29#255#146'P3'#255#168 - +'jM'#255#173'pT'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU' - +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255 - +#4#3#2#255#0#0#0#255#0#0#0#255#21#14#10#255#173'rU'#255#173'rU'#255#152'dK' - +#255'dB1'#255'A+ '#255'D-!'#255#141']E'#255#173'rU'#255#173'rU'#255#173'rU' - +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255 - +#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173 - +'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU' - ,#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255 - +#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173 - +'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU' - +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255 - +#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#169'pS'#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#139'\D'#255#173'rU'#255#173'rU' - +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255 - +#173'rU'#255#173'rU'#255#173'qT'#255#172'oR'#255#165'cF'#255#128'E+'#255'\0' - +#28#255'[/'#27#255'CBA'#132'DDD@CCC'#19'UUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0'@@@'#4'U2"L[/'#27#255'\1'#29#255#143'N3'#255#168'hK'#255#172'oT' - +#255#173'qU'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255 - +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#1#1#1#255#0#0#0 - +#255#0#0#0#255'nI7'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173 - +'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV' - +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255 - +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173 - +'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV' - +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255 - +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173 - +'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV' - +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255 - +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#2#1#1#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255'H0$'#255#173'rV'#255#173'rV'#255#173'rV' - +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255 - +#173'rV'#255#173'qU'#255#171'nQ'#255#165'dF'#255'~D+'#255'\1'#29#255'Z0'#28 - +#252'CCCzCCC9@@@'#16#128#128#128#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U' - +'UU'#3'T2#=[/'#27#255'\1'#29#255#140'N1'#255#166'gI'#255#171'oR'#255#173'qU' - +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255 - +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#1#1#1#255#27#18#13#255'a@0' - +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255 - +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173 - +'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU' - +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255 - +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173 - +'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU' - +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255 - +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173 - +'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU' - +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255'$'#24#18#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#31#20#15#255#173'qU'#255#173'qU'#255#173'qU'#255 - +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173 - +'qU'#255#172'pT'#255#169'lP'#255#164'aD'#255'{C*'#255'\1'#29#255'Y0'#30#247 - +'CCCoBBB2;;;'#13#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#128#128 - +#2'V6''-[/'#27#255'\1'#29#255#137'L0'#255#165'fH'#255#170'mQ'#255#172'pT'#255 - +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172 - +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#166'lS'#255#172'pU'#255#172'pU' - +#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255 - +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172 - +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU' - +#255#172'pU'#255#172'pU'#255#172'pU'#255#168'nS'#255#134'WB'#255'b@0'#255'tK' - +'9'#255#166'lS'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU' - +#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255 - +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172 - +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU' - +#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255 - +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#129'T@'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - ,#255#0#0#0#255#0#0#0#255#22#14#11#255#172'pU'#255#172'pU'#255#172'pU'#255#172 - +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU' - +#255#172'oT'#255#170'mP'#255#163'`C'#255'xB*'#255'\1'#29#255'Y1'#31#241'BBBd' - +'CCC*MMM'#10#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'T7*'#29 - +'[/'#27#255'\1'#29#255#134'J0'#255#165'dG'#255#169'lQ'#255#171'pU'#255#172'q' - +'W'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW' - +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255 - +#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172 - +'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW' - +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255 - +#135'YD'#255'$'#24#18#255#3#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#8#5#4#255#30#20#16#255'xO='#255#172'qW'#255#172'qW'#255#172'qW'#255 - +#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172 - +'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW' - +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255 - +#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172 - +'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#14#9#7#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#20#13#10#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW' - +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#171'oT'#255 - +#169'jM'#255#162'_A'#255's>'''#255'\1'#29#255'X2 '#234'CCCXDDD"@@@'#8#0#0#0#1 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'C><'#9'[/'#27#247'\1'#29#255 - +'}F-'#255#164'bE'#255#169'lO'#255#171'pT'#255#172'qV'#255#172'qV'#255#172'qV' - +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255 - +#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172 - +'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV' - +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255 - +#172'qV'#255#172'qV'#255#154'eM'#255#22#15#11#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#25#17#13#255#136'ZE'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV' - +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255 - +#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172 - +'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV' - +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255 - +#172'qV'#255'U7*'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#17#11#9#255#172'qV'#255#172 - +'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV' - +#255#172'qV'#255#172'qV'#255#171'oT'#255#168'jM'#255#161'^@'#255'k;%'#255'\0' - +#28#255'V3#'#220'CCCLEEE'#26'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0'+++'#6'[/'#28#214'\1'#29#255't@)'#255#162'`B'#255#168'jO'#255 - +#172'pV'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173 - +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX' - +#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255 - +#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173 - +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#144'_I'#255#6#4#3 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'Z;-'#255 - +#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173 - +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX' - +#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255 - +#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173 - +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#171'pV'#255#3#2#1#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255'!'#22#17#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX' - +#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#172'qX'#255#171'oU'#255 - +#167'hM'#255#160'[>'#255'b5!'#255'\0'#28#255'S5'''#196'EEE?CCC'#19'@@@'#4#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'UUU'#3'Z0'#29#176'\1'#29 - +#255'k:%'#255#162'^A'#255#169'jN'#255#173'qV'#255#174'sY'#255#174'sY'#255#174 - +'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY' - +#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255 - +#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174 - ,'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY' - +#255#151'dM'#255#4#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#1#1#1#255#136'YF'#255#174'sY'#255#174'sY'#255#174's' - +'Y'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY' - +#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255 - +#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174 - +'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY' - +#255#174'sY'#255'5#'#27#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'G.$'#255#174'sY'#255#174'sY'#255 - +#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174 - +'sY'#255#174'sY'#255#172'pV'#255#167'gK'#255#153'X:'#255'^3'#31#255'\0'#28 - +#255'Q7+'#166'BBB2777'#14#0#0#0#2#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#2'Z0'#29#137'\0'#28#255'a5!'#255#160']>'#255#168'jN'#255 - +#173'sY'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175 - +'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\' - +#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255 - +#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175 - +'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#29#20#15#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8 - +#5#4#255#169'rX'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\' - +#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255 - +#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175 - +'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\' - +#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#156'jR'#255#1#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255'yQ?'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255 - +#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#174'u['#255#172'qV'#255#166 - +'gJ'#255#143'S6'#255'^2'#31#255'[/'#27#255'O;2'#130'CCC&999'#9#0#0#0#1#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#1'Z0'#29'a\0'#28#255 - +'^3'#31#255#153'W;'#255#168'jN'#255#174'tZ'#255#176'x_'#255#176'y_'#255#176 - +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_' - +#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255 - +#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176 - +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255'oL='#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255']@2'#255#176'y_'#255#176'y_'#255#176 - +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255'Z=1'#255')'#28#22#255#26#18#14 - +#255#14#10#8#255#10#7#5#255#23#16#12#255'+'#30#23#255'E0&'#255#138'_J'#255 - +#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176 - +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_' - +#255#176'y_'#255'#'#24#19#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#172'w]'#255#176'y_'#255#176'y_'#255 - +#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176 - +'y_'#255#175'w^'#255#172'rW'#255#165'fI'#255#134'K2'#255']1'#30#255'[/'#27 - +#255'H?:ZBBB'#27'+++'#6#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'X/'#29'7[/'#27#255'^2'#31#255#141'P5'#255#167'hK'#255#174 - +'sY'#255#177'x_'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za' - +#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255 - +#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177 - +'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za' - +#255#177'za'#255#177'za'#255#9#6#5#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255'%'#25#20#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255'bD6'#255#8 - +#6#4#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255'>+"'#255#175'za'#255#177'za'#255#177'za'#255#177'za' - +#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255 - +#177'za'#255#177'za'#255#177'za'#255#136'^K'#255#0#0#0#255#0#0#0#255#0#0#0 - ,#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#16#11#9#255#177'za'#255#177 - +'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za' - +#255#177'za'#255#177'za'#255#176'x^'#255#172'qV'#255#164'cF'#255'{E,'#255']1' - +#30#255'Z0'#29#245'DDD'#255 - +'`5!'#255'\0'#28#255'T5'''#155'DDD'#30'III'#7#0#0#0#1#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'Z/'#28'w\0'#28#255 - +'`5!'#255#157'\?'#255#172'pU'#255#179'}d'#255#181#129'i'#255#182#129'j'#255 - +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255 - +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255 - +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255 - +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255 - +#182#129'j'#255#182#129'j'#255#182#129'j'#255'.!'#27#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#2#1#1#255#166'va'#255#182#129'j'#255#182#129'j'#255'A.&' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#9#6#5#255#170'yd'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182 - +#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182 - +#129'j'#255#182#129'j'#255#182#129'j'#255#8#6#5#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#135'`O'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255 - +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255 - +#182#129'j'#255#182#129'j'#255#181#128'h'#255#177'za'#255#169'kP'#255#139'Q7' - +#255'^3'#31#255'\0'#28#255'N9/\GGG'#18'UUU'#3#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'X.'#26'4\0'#28#255 - ,'^3'#31#255#141'S8'#255#170'mQ'#255#179'|c'#255#182#130'k'#255#184#132'm'#255 - +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255 - +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255 - +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255 - +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255 - +#184#132'm'#255#184#132'm'#255#184#132'm'#255#20#15#12#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255'N8.'#255#184#132'm'#255#184#132'm'#255#184#132'm' - +#255#22#16#13#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#21#15#13#255#182#130'm'#255#184#132'm'#255#184#132 - +'m'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132 - +'m'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255'N8.'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#23#17#13#255#184#132'm'#255#184#132'm'#255#184#132'm'#255 - +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255 - +#184#132'm'#255#184#132'm'#255#183#131'l'#255#182#129'j'#255#177'x_'#255#167 - +'hK'#255'zG/'#255']1'#30#255'Z0'#28#241'@@@(MMM'#10#0#0#0#1#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'='#31 - +#18#3'[/'#27#238']1'#30#255'{G/'#255#167'hL'#255#177'za'#255#183#131'l'#255 - +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255 - +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255 - +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255 - +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255 - +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#26#19#16#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#12#9#7#255#185#134'p'#255#185#134'p'#255#185#134'p' - +#255#185#134'p'#255#3#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'U>4'#255#185#134'p'#255#185 - +#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185 - +#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#25#18 - +#15#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255'xWI'#255#185#134'p'#255#185#134'p'#255#185#134 - +'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134 - +'p'#255#185#134'p'#255#185#134'p'#255#184#134'o'#255#182#129'j'#255#175'v\' - +#255#165'dG'#255'h;&'#255'\1'#29#255'X2 '#193'==='#25'+++'#6#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'[/'#27#170'\1'#29#255'f9%'#255#164'bG'#255#175'v]'#255#183#131 - +'l'#255#186#135'r'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137 - +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137 - +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137 - +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137 - +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255'$'#27#23 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#129'_P'#255#186#137's'#255#186#137's'#255 - +#186#137's'#255#186#137's'#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255' '#23#19#255#186 - +#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186 - +#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186 - +#137's'#255#172#127'j'#255#7#5#4#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#12#9#7#255#186#137's'#255#186#137's' - +#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's' - +#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#185#135'q' - +#255#181#129'i'#255#173'qW'#255#149'X='#255'`5!'#255'\0'#28#255'V4%'#127'333' - +#15#0#0#0#3#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'Z/'#27'O\0'#28#255'_4 '#255#144'U:' - +#255#172'qV'#255#182#130'k'#255#187#137't'#255#188#139'u'#255#188#140'v'#255 - +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - ,#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - +#188#140'v'#255'1$'#31#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255':+$'#255#188#140'v'#255#188#140 - +'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#1#1#1#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#4#3#3#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255'}]N'#255'6("' - +#255#14#11#9#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'S>5'#255 - +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255 - +#188#139'u'#255#186#136'r'#255#180'~f'#255#169'kP'#255'|H1'#255'^2'#31#255'[' - +'/'#27#249'L=6+III'#7#0#0#0#1#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'[/'#27#5'[/'#27#235 - +']1'#30#255'wD/'#255#169'jO'#255#180#127'g'#255#187#137'u'#255#189#141'x'#255 - +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255 - +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255 - +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255 - +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255 - +#189#142'y'#255#189#142'y'#255'J7/'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#16#12#11#255#187#140'y'#255 - +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#1 - +#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#181#136'u'#255#189#142'y'#255#189#142 - +'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142 - +'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142 - +'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#11#8#7#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#1#1#1#255#181#136's'#255#189#142'y'#255#189#142'y'#255#189 - +#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189 - +#142'y'#255#189#142'y'#255#189#142'y'#255#189#141'x'#255#186#136'q'#255#177 - +'za'#255#164'dG'#255'f:&'#255'\1'#29#255'Y1'#31#186'@@@'#16'UUU'#3#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'Z/'#27#147'\1'#29#255'b8$'#255#160'bF'#255 - +#177'y`'#255#186#137's'#255#190#143'z'#255#191#145'|'#255#191#145'|'#255#191 - +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191 - +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191 - +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191 - +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#162 - +'{i'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#1#1#1#255#162'{i'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255 - +#191#145'|'#255#191#145'|'#255#191#145'|'#255#2#1#1#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1 - +#1#1#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145 - +'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145 - +'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145 - +'|'#255#191#145'|'#255#5#4#3#255#0#0#0#255#0#0#0#255#0#0#0#255'&'#29#25#255 - +#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255 - +#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255 - +#191#145'|'#255#189#142'y'#255#184#134'o'#255#174'sY'#255#143'U;'#255'`5!' - +#255'\0'#28#255'U3$`@@@'#8#0#0#0#1#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'Z.'#27'5\0'#28#255'_4 '#255#137'Q8'#255#173'rX'#255#184#134'o'#255#190#144 - +'{'#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192 - +#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255 - +#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127 - +#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147 - +#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#14 - ,#11#9#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255' ' - +#24#21#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255 - +#192#147#127#255#192#147#127#255#192#147#127#255#4#3#3#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#8#6#5#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127 - +#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147 - +#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192 - +#147#127#255#192#147#127#255#192#147#127#255#1#1#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#137'iZ'#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147 - +#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192 - +#147#127#255#192#147#127#255#192#146'~'#255#189#142'y'#255#182#129'j'#255#169 - +'lP'#255'uD.'#255'^2'#31#255'[/'#28#237'NFB'#21'UUU'#3#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#0#0#0#0#0'[/'#27#211']1'#30#255'l>)'#255#167'iM' - +#255#181#127'g'#255#190#143'z'#255#193#148#128#255#194#149#130#255#194#149 - +#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194 - +#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255 - +#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130 - +#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149 - +#130#255#194#149#130#255'G60'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255'ZE<'#255#194#149#130#255#194#149#130#255#194#149#130#255 - +#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#7#6#5#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#23#17#15#255#194#149#130#255#194#149#130#255#194#149#130 - +#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149 - +#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194 - +#149#130#255#194#149#130#255#194#149#130#255#179#137'x'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255'-#'#30#255#194#149#130#255#194#149#130#255#194#149#130#255#194 - +#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255 - +#194#149#130#255#194#149#130#255#194#149#130#255#192#147#127#255#188#140'v' - +#255#177'za'#255#156'_D'#255'a6#'#255'\1'#29#255'Y1'#31#153'@@@'#8#0#0#0#1#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#0#0#0#0#0'Z/'#27']\0'#28#255 - +'`5!'#255#143'V='#255#175'v]'#255#187#138'u'#255#193#149#129#255#195#152#132 - +#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152 - +#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195 - +#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255 - +#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133 - +#255#195#152#133#255#195#152#133#255#170#133't'#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#172#133'u'#255#195#152#133#255#195#152 - +#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#146 - +'rd'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'_JA'#255#195#152#133#255#195#152#133 - +#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152 - +#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195 - +#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#140'm`'#255#0#0 - +#0#255#0#0#0#255#6#5#4#255#186#145#127#255#195#152#133#255#195#152#133#255 - +#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133 - +#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#132#255#192#147 - +#127#255#185#134'p'#255#172'pU'#255'|I2'#255'^3'#31#255'\0'#28#250'R5()UUU'#3 - +#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#0#0#0#0#0#0#0#0#0'[/'#27#3 - +'[/'#27#221']1'#30#255'oA,'#255#169'lP'#255#183#131'l'#255#192#147#127#255 - +#196#154#135#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136 - +#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155 - +#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197 - +#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255 - +#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#26#20#18#255 - ,#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#6#5#255#197#155#136#255#197 - +#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255 - +#197#155#136#255#28#22#19#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#3#255#193#153#134#255 - +#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136 - +#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155 - +#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197 - +#155#136#255#182#143'~'#255'=0*'#255#7#5#5#255#130'fY'#255#197#155#136#255 - +#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136 - +#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#196#154 - +#136#255#195#152#133#255#190#144'{'#255#180'~f'#255#159'bG'#255'c8%'#255'\1' - +#29#255'Z0'#30#163'III'#7#0#0#0#1#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#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27'g\0'#28#255'a6#'#255#147'Y@'#255#177 - +'za'#255#190#143'z'#255#196#154#135#255#198#157#139#255#198#157#139#255#198 - +#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255 - +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139 - +#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157 - +#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198 - +#157#139#255'<0+'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'*!'#29#255 - +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139 - +#255#198#157#139#255#164#130's'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'?2,'#255#198 - +#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255 - +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139 - +#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157 - +#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198 - +#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255 - +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139 - +#255#198#157#139#255#198#156#138#255#195#152#132#255#187#138't'#255#173'sY' - +#255#127'L5'#255'^3'#31#255'\0'#28#252'U3$,'#128#128#128#2#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#7 - +'[/'#27#229'^2'#31#255'qB.'#255#171'nS'#255#185#134'p'#255#194#151#131#255 - +#198#158#140#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142 - +#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160 - +#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200 - +#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255 - +#200#160#142#255#200#160#142#255#200#160#142#255'9.)'#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255'hSJ'#255#200#160#142#255#200#160#142#255#200#160#142 - +#255#200#160#142#255#200#160#142#255#200#160#142#255'6+'''#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#6#5#5#255#184#148#131#255#200#160#142#255#200#160#142#255#200#160#142 - +#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160 - +#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200 - +#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255 - +#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142 - +#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160 - +#142#255#200#160#142#255#200#160#142#255#199#159#141#255#198#157#139#255#192 - +#147#127#255#181#127'g'#255#161'dI'#255'd:&'#255'\1'#29#255'Z0'#29#171'@@@'#4 - +#0#0#0#1#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#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27'q\1'#29#255'a6#'#255#143'W?'#255#177'za'#255 - +#191#144'|'#255#198#157#139#255#200#161#144#255#201#162#145#255#201#163#145 - +#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163 - +#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201 - +#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255 - +#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255'=2,'#255#0#0 - ,#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255'!'#27#24#255#197#161#143#255#201#163#145#255 - +#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#197#161#143 - +#255#3#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#1#1#1#255#149'zl'#255#201#163#145#255#201#163#145 - +#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163 - +#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201 - +#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255 - +#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145 - +#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163 - +#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#162#145#255#200 - +#161#143#255#197#155#136#255#187#138'u'#255#173'rX'#255'|I3'#255'_4 '#255'\0' - +#28#253'W1 2'#0#0#0#1#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#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'[/'#27#6'\0'#28#216'^2'#31#255 - +'i=)'#255#165'jP'#255#184#133'n'#255#196#152#134#255#201#162#145#255#202#164 - +#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202 - +#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255 - +#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148 - +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165 - +#148#255'E82'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#2#255#1#1#1#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'.&"'#255#202#165#148#255#202#165#148 - +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165 - +#148#255#146'wk'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'eRI'#255#202#165#148#255#202#165#148 - +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165 - +#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202 - +#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255 - +#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148 - +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165 - +#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202 - +#164#147#255#200#160#143#255#193#148#128#255#180'~f'#255#151'^D'#255'a7$'#255 - +'\1'#29#255'Z0'#28#156'UUU'#3#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#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'[/'#27 - +'D\0'#28#255'`5!'#255#128'N8'#255#175'v]'#255#190#143'{'#255#200#159#142#255 - +#203#165#150#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151 - +#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167 - +#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204 - +#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255 - +#204#167#151#255'N?9'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'vaW'#255 - +#204#167#151#255#160#131'w'#255'cRI'#255'WG@'#255#168#137'|'#255#204#167#151 - +#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167 - +#151#255#204#167#151#255#204#167#151#255#145'wk'#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'G:4'#255#204#167 - +#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204 - +#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255 - +#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151 - +#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167 - +#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204 - +#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255 - +#204#167#151#255#204#167#150#255#202#165#148#255#198#155#138#255#186#137's' - +#255#171'nU'#255'oB.'#255'^2'#31#255'\0'#28#235'V2"'#21#0#0#0#1#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#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'[/'#27#169'\1'#29#255'c9&'#255#155'aH'#255 - +#182#128'j'#255#195#152#133#255#202#164#148#255#205#169#154#255#206#169#155 - +#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169 - +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206 - +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255 - +#206#169#155#255#206#169#155#255#206#169#155#255'VGA'#255#0#0#0#255#0#0#0#255 - ,#0#0#0#255#5#4#4#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169 - +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206 - +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255 - +#206#169#155#255#152'}r'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#2#1#1#255'vaY'#255#206#169#155#255#206#169#155#255#206#169 - +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206 - +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255 - +#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155 - +#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169 - +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206 - +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255 - +#205#167#152#255#201#162#145#255#192#147#127#255#177'za'#255#138'T='#255'`6"' - +#255'\1'#29#255'[0'#29'e'#0#0#0#1#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#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'[/'#27#27'\0'#28#243'^3'#31#255'pC/'#255#171'oU'#255#188#138'u' - +#255#199#158#141#255#205#169#154#255#207#171#157#255#207#172#158#255#207#172 - +#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207 - +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255 - +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158 - +#255#207#172#158#255'~i`'#255#0#0#0#255#0#0#0#255#0#0#0#255#22#18#16#255#207 - +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255 - +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158 - +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172 - +#158#255'/''$'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#9#7#7#255 - +#164#136'~'#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158 - +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172 - +#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207 - +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255 - +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158 - +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172 - +#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#171#157#255#204 - +#167#151#255#196#153#136#255#183#131'l'#255#160'fK'#255'f;('#255']1'#30#255 - +'[/'#27#199'te^'#3#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#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'[/'#27'q\0'#28#255'`6"'#255#130'P9'#255#177'x`'#255#192#146 - +#127#255#203#164#149#255#208#173#159#255#209#175#161#255#209#175#161#255#209 - +#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255 - +#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161 - +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175 - +#161#255#199#167#153#255#0#0#0#255#0#0#0#255#0#0#0#255'.&#'#255#209#175#161 - +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175 - +#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209 - +#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255 - +#209#175#161#255'*$!'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'"'#28#26#255#197#165#153#255 - +#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161 - +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175 - +#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209 - +#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255 - +#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161 - +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175 - +#161#255#209#175#161#255#209#175#161#255#209#174#160#255#207#171#157#255#200 - +#160#144#255#188#139'w'#255#171'pV'#255'rD0'#255'^3'#31#255'\0'#28#250'\2'#30 - +'1'#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#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'[/'#27#1'[/'#27#184']1'#30#255'c9&'#255#148'^E'#255#182#128'j'#255#197 - +#154#136#255#206#170#155#255#210#176#163#255#211#178#164#255#211#178#165#255 - +#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165 - +#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178 - ,#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211 - +#178#165#255#12#10#9#255#0#0#0#255#0#0#0#255'MA<'#255#211#178#165#255#211#178 - +#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211 - +#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255 - +#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165 - +#255#211#178#165#255#178#150#139#255'D95'#255#9#7#7#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'VIC'#255#211#178#165#255#211#178#165 - +#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178 - +#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211 - +#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255 - +#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165 - +#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178 - +#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211 - +#178#165#255#211#178#165#255#211#178#164#255#209#176#162#255#204#167#151#255 - +#193#148#129#255#177'x`'#255#129'P9'#255'`6"'#255'\0'#28#255'[0'#28't'#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#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'[/'#27#21'\0'#28#229'^2'#31#255'i?+'#255#163'jP'#255#186#136 - +'s'#255#200#160#144#255#209#174#160#255#212#180#167#255#213#181#169#255#213 - +#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255 - +#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169 - +#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181 - +#169#255'.''%'#255#0#0#0#255',%#'#255#200#170#159#255#213#181#169#255#213#181 - +#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213 - +#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255 - +#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169 - +#255#213#181#169#255#213#181#169#255#213#181#169#255#139'vo'#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'.''$'#255#213#181#169#255#213#181#169 - +#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181 - +#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213 - +#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255 - +#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169 - +#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181 - +#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213 - +#181#169#255#213#181#169#255#212#180#168#255#211#178#165#255#207#171#157#255 - +#197#155#137#255#182#128'j'#255#148']E'#255'c9&'#255']1'#30#255'[/'#27#179#0 - +#0#0#1#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#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#0#0'[/'#27'?\0'#28#252'_4 '#255'tF1'#255#172 - +'sY'#255#190#142'z'#255#203#165#150#255#211#178#164#255#213#183#170#255#214 - +#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255 - +#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172 - +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184 - +#172#255#127'ng'#255'{ib'#255#214#184#172#255#214#184#172#255#214#184#172#255 - +#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172 - +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184 - +#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214 - +#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255' '#28#26#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#14#12#11#255#209#180#168#255#214#184#172 - +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184 - +#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214 - +#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255 - +#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172 - +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184 - +#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214 - +#184#172#255#214#184#172#255#214#184#172#255#213#182#169#255#209#176#161#255 - +#200#161#143#255#186#135'q'#255#161'gO'#255'h=*'#255'^2'#31#255'\0'#28#226'W' - +'-'#26#19#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#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#0#0#0#0#0#0#0#0#0#0'[/'#27'}\1'#29#255'`6"' - +#255'|M8'#255#175'x^'#255#192#147#127#255#205#170#154#255#213#181#169#255#215 - ,#185#173#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255 - +#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175 - +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187 - +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216 - +#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255 - +#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175 - +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187 - +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#187#162#151#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#2#255#180#156#146#255#216#187#175 - +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187 - +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216 - +#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255 - +#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175 - +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187 - +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216 - +#187#175#255#216#187#175#255#216#187#175#255#215#185#173#255#211#179#166#255 - +#202#165#148#255#188#139'w'#255#167'mU'#255'nC/'#255'^3'#31#255'\0'#28#251'Z' - +'.'#27';'#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#2'[/'#27 - +#170'\1'#29#255'a7$'#255#130'Q<'#255#178'{c'#255#195#151#132#255#208#173#159 - +#255#215#185#173#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189 - +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217 - +#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255 - +#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178 - +#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189 - +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217 - +#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255 - +#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255'.(&'#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#128'oi'#255#217#189#178#255#217#189#178 - +#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189 - +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217 - +#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255 - +#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178 - +#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189 - +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217 - +#189#178#255#217#189#178#255#217#188#177#255#213#183#170#255#205#168#153#255 - +#191#144'|'#255#170'rZ'#255'sF2'#255'`5!'#255'\0'#28#255'Z/'#27'g'#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#6'[/'#27 - +#188']1'#30#255'c9&'#255#136'V?'#255#180'~g'#255#197#154#136#255#209#176#162 - +#255#216#187#176#255#219#192#181#255#219#192#182#255#219#193#183#255#219#193 - +#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219 - +#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255 - +#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183 - +#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193 - +#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219 - +#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255 - +#219#193#183#255#219#193#183#255#158#138#131#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#1#1#1#255#131'sm'#255#219#193#183#255#219#193#183#255#219#193#183#255 - +#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183 - +#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193 - +#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219 - +#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255 - +#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183 - +#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#192 - +#182#255#218#191#180#255#215#185#173#255#207#172#156#255#193#147#128#255#174 - +'v^'#255'wJ6'#255'`6"'#255'\1'#29#255'[/'#27'~'#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#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#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'[/'#27#12'[/'#27#203 - +']1'#30#255'c:'''#255#141'YC'#255#181#128'h'#255#198#155#138#255#210#177#164 - +#255#217#190#178#255#220#194#184#255#221#195#185#255#221#196#186#255#221#196 - +#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221 - +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255 - +#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186 - +#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196 - +#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221 - +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255 - +#221#196#186#255're_'#255#0#0#0#255#0#0#0#255#4#4#4#255#160#142#134#255#221 - +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255 - +#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186 - +#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196 - +#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221 - +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255 - +#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186 - +#255#221#196#186#255#221#196#186#255#221#195#185#255#219#193#183#255#216#187 - +#175#255#207#172#158#255#194#148#130#255#176'x_'#255'{M8'#255'a6#'#255'\1'#29 - +#255'[/'#27#148#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#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#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'[/'#27#21'\0'#28#217']1'#30#255'c:''' - +#255#138'XB'#255#181#127'h'#255#197#156#137#255#211#178#164#255#218#191#180 - +#255#221#196#187#255#222#198#188#255#223#198#189#255#223#198#189#255#223#198 - +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223 - +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255 - +#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189 - +#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198 - +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223 - +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#221#196#187#255 - +#6#6#5#255#10#9#8#255#188#167#159#255#223#198#189#255#223#198#189#255#223#198 - +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223 - +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255 - +#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189 - +#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198 - +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223 - +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255 - +#222#198#188#255#221#196#186#255#217#188#177#255#208#173#159#255#193#149#129 - +#255#174'w^'#255'zM8'#255'a7$'#255'\1'#29#255'[/'#27#170'[/'#27#2#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#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#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'[/'#27' \0'#28#223']1'#30#255'c:'''#255#132'T?'#255#180 - +'~g'#255#197#155#136#255#211#178#164#255#219#193#181#255#223#198#189#255#224 - +#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255 - +#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192 - +#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201 - +#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224 - +#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255 - +#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192 - +#255#224#201#192#255#224#201#192#255#134'xr'#255#205#184#176#255#224#201#192 - +#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201 - +#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224 - +#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255 - +#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192 - +#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201 - +#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224 - +#201#192#255#224#201#192#255#223#200#191#255#222#197#187#255#217#189#178#255 - +#207#172#158#255#192#147#127#255#171'u\'#255'vI6'#255'a6#'#255'\1'#29#255'[/' - +#27#179'[/'#27#6#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#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#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'[/'#27#25'\' - +'0'#28#209']1'#30#255'c9&'#255#128'Q='#255#177'{c'#255#195#151#133#255#209 - +#176#162#255#219#192#181#255#223#200#191#255#225#203#194#255#226#204#196#255 - +#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196 - +#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204 - +#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226 - +#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255 - +#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196 - +#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204 - +#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226 - +#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255 - +#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196 - +#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204 - +#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226 - +#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255 - +#226#204#196#255#226#204#196#255#226#203#195#255#225#202#193#255#222#198#188 - +#255#217#188#177#255#206#169#155#255#191#144'|'#255#168'qY'#255'rG3'#255'`6"' - +#255'\1'#29#255'[/'#27#159'[/'#27#4#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#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#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'[/'#27#15'\0'#28#193']1'#30#255'b8%'#255'yM8'#255#170 - +'u\'#255#192#146'~'#255#207#171#156#255#217#189#178#255#223#200#191#255#226 - +#205#197#255#227#206#198#255#228#207#199#255#228#207#199#255#228#207#199#255 - +#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199 - +#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207 - +#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228 - +#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255 - +#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199 - +#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207 - +#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228 - +#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255 - +#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199 - +#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207 - +#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228 - +#207#199#255#228#207#199#255#227#206#198#255#226#204#196#255#222#198#188#255 - +#215#185#173#255#202#165#148#255#187#137'u'#255#159'jR'#255'nD0'#255'`6"'#255 - +'\1'#29#255'[/'#27#137#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#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#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#0#0#0#0#0#0#0'[/'#27#8'[/'#27#175'\1'#29#255'`6"'#255'n' - +'D0'#255#158'iR'#255#187#137'u'#255#202#165#148#255#215#186#174#255#223#199 - +#190#255#227#205#198#255#229#208#201#255#229#209#202#255#229#210#202#255#229 - +#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255 - +#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202 - +#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210 - +#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229 - +#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255 - +#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202 - +#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210 - +#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229 - +#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255 - +#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202 - +#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#209 - +#202#255#228#207#201#255#226#204#197#255#221#196#187#255#212#180#168#255#198 - +#157#140#255#183#130'l'#255#143'^G'#255'g>+'#255'_4 '#255'\1'#29#254'[/'#27 - +'q'#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#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#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 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#3'[/'#27#132'\1'#29#254'_4 '#255'g>+' - +#255#140'[F'#255#181#129'j'#255#198#155#138#255#211#178#165#255#221#195#185 - +#255#227#204#197#255#230#209#203#255#230#212#205#255#231#212#206#255#231#212 - +#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231 - +#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255 - +#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206 - +#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212 - +#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231 - +#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255 - +#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206 - +#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212 - +#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231 - +#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255 - +#231#212#206#255#231#211#206#255#230#211#205#255#229#209#201#255#225#203#194 - +#255#219#191#181#255#208#173#159#255#193#149#129#255#173'w`'#255'~Q='#255'c:' - +''''#255'^2'#31#255'\0'#28#238'[/'#27'O'#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#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#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#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'[/'#27'F\0'#28#234'^2'#31#255'c:'''#255'zN:'#255#168's['#255 - +#190#143'{'#255#205#167#152#255#217#187#177#255#225#201#193#255#229#209#202 - +#255#232#213#207#255#232#214#209#255#233#215#210#255#233#215#210#255#233#215 - +#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233 - +#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255 - +#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210 - +#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215 - +#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233 - +#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255 - +#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210 - +#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215 - +#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233 - +#215#210#255#232#215#209#255#232#214#208#255#231#212#206#255#228#207#201#255 - +#223#198#189#255#213#182#170#255#200#160#144#255#186#136'r'#255#158'iR'#255 - +'pE2'#255'a7$'#255']1'#30#255'\0'#28#201'[/'#27#31#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#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#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#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'[/'#27#26'\0'#28#193']1'#30#255'`' - +'6"'#255'iA.'#255#142']H'#255#179#128'h'#255#196#153#135#255#210#176#163#255 - +#220#194#184#255#227#205#198#255#231#212#206#255#233#216#211#255#234#217#212 - +#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218 - +#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234 - +#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255 - +#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213 - +#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218 - +#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234 - +#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255 - +#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213 - +#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#217 - +#212#255#234#216#211#255#233#215#210#255#230#211#205#255#226#203#195#255#218 - +#190#179#255#206#170#155#255#192#146#127#255#172'v`'#255#129'S?'#255'e<)'#255 - +'_4 '#255'\1'#29#255'[/'#27#143'[/'#27#5#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#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#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#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'[/'#27#3'[/'#27#127'\0'#28 - +#248'^3'#31#255'c:'''#255'sI6'#255#158'kT'#255#186#136's'#255#200#160#143#255 - ,#213#180#169#255#222#197#187#255#229#208#201#255#232#214#209#255#234#218#213 - +#255#235#219#215#255#236#220#215#255#236#220#216#255#236#220#216#255#236#220 - +#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236 - +#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255 - +#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216 - +#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220 - +#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236 - +#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255 - +#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216 - +#255#236#220#216#255#236#220#215#255#235#219#215#255#234#217#212#255#232#213 - +#207#255#227#205#198#255#219#193#183#255#209#176#162#255#196#153#136#255#181 - +#129'l'#255#145'`K'#255'lB0'#255'a7$'#255']1'#30#255'\0'#28#231'[/'#27'O'#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#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#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#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'[/'#27'$\0'#28#185'\1'#29#255'`5!'#255 - +'f=*'#255#128'S>'#255#166'r['#255#188#139'v'#255#201#161#145#255#213#181#169 - +#255#223#197#189#255#229#209#202#255#233#216#210#255#235#219#215#255#236#221 - +#217#255#237#222#219#255#238#223#220#255#238#223#220#255#238#223#220#255#238 - +#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255 - +#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220 - +#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223 - +#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238 - +#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255 - +#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220 - +#255#237#222#219#255#237#222#218#255#236#221#217#255#235#218#214#255#232#214 - +#208#255#228#206#199#255#220#193#184#255#210#176#163#255#197#155#137#255#184 - +#134'o'#255#155'iR'#255'uI7'#255'c:'''#255'^3'#31#255'\1'#29#252'[/'#27#144 - +'[/'#27#14#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#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#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#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#0#0#0#0#0#0#0#0'[' - +'/'#27'U\0'#28#228']1'#30#255'`6"'#255'g>,'#255#127'R?'#255#164'qZ'#255#188 - +#139'v'#255#200#159#144#255#211#179#166#255#220#194#184#255#228#206#199#255 - +#232#214#209#255#235#219#215#255#237#222#219#255#238#225#221#255#239#225#222 - +#255#239#225#222#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226 - +#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239 - +#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255 - +#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223 - +#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226 - +#223#255#239#226#223#255#239#226#223#255#239#225#222#255#238#225#221#255#238 - +#224#220#255#237#222#218#255#235#218#214#255#231#212#206#255#226#203#195#255 - +#218#191#180#255#209#174#160#255#197#154#136#255#184#132'o'#255#154'hR'#255 - +'uK8'#255'e;('#255'_4 '#255'\1'#29#255'\0'#28#197'[/'#27'/'#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#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#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27 - +#12'[/'#27#134'\0'#28#242'^2'#31#255'a5#'#255'g>+'#255'|Q='#255#160'lV'#255 - +#184#133'p'#255#196#152#134#255#207#170#156#255#216#187#175#255#224#200#192 - +#255#230#210#203#255#234#216#211#255#236#220#216#255#238#224#220#255#239#226 - +#223#255#240#227#225#255#240#228#225#255#240#228#225#255#241#229#226#255#241 - +#229#226#255#241#229#226#255#241#229#226#255#241#229#227#255#241#229#227#255 - +#241#229#227#255#241#229#227#255#241#229#227#255#241#229#227#255#241#229#227 - +#255#241#229#227#255#241#229#227#255#241#229#226#255#241#229#226#255#241#229 - ,#226#255#241#229#226#255#240#228#225#255#240#228#225#255#240#227#224#255#239 - +#225#222#255#238#223#220#255#236#220#215#255#233#215#210#255#228#207#201#255 - +#222#196#187#255#213#183#170#255#204#166#150#255#192#147#127#255#179#127'i' - +#255#150'fO'#255'tI7'#255'e;('#255'`5!'#255']1'#30#255'\0'#28#223'[/'#27'`[/' - +#27#1#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#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#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#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#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'[/'#27#17'[/'#27#127'\0'#28#238']1' - +#30#255'`6"'#255'e<)'#255'rI6'#255#142'_J'#255#170'wa'#255#188#140'w'#255#199 - +#158#141#255#208#173#159#255#216#186#175#255#222#196#187#255#227#206#198#255 - +#232#213#208#255#235#219#214#255#237#222#218#255#238#224#220#255#239#226#223 - +#255#240#227#225#255#241#229#226#255#242#230#228#255#242#230#228#255#242#231 - +#229#255#242#231#229#255#242#231#229#255#242#231#229#255#242#231#229#255#242 - +#231#229#255#242#231#229#255#242#230#228#255#241#229#227#255#241#229#226#255 - +#240#227#225#255#239#225#222#255#238#224#220#255#236#221#217#255#234#218#213 - +#255#231#211#206#255#226#204#196#255#220#194#184#255#214#183#171#255#206#169 - +#155#255#196#153#135#255#185#135'r'#255#162'q['#255#134'XD'#255'lC1'#255'c:' - +''''#255'_4 '#255']0'#30#255'\0'#28#217'[/'#27'`[/'#27#4#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#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#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#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#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'[/'#27#13'[/'#27'w\0'#28#233 - +']1'#30#255'_4 '#255'b8%'#255'h?-'#255'zN;'#255#149'dP'#255#170'xa'#255#187 - +#137't'#255#194#150#131#255#202#164#148#255#210#176#163#255#216#187#175#255 - +#220#194#184#255#224#200#192#255#228#207#199#255#231#212#206#255#234#217#211 - +#255#236#220#215#255#236#222#217#255#237#222#219#255#238#223#220#255#238#223 - +#220#255#238#224#220#255#238#223#220#255#237#223#219#255#237#223#218#255#236 - +#221#217#255#235#219#215#255#233#216#210#255#230#211#204#255#227#204#197#255 - +#223#199#190#255#219#192#183#255#215#185#173#255#208#173#159#255#200#160#144 - +#255#192#146#127#255#183#133'o'#255#164's\'#255#142']J'#255'rI7'#255'f=*'#255 - +'a6#'#255'^3'#31#255'\1'#29#255'\0'#28#210'[/'#27'X[/'#27#2#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#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#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#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#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#0'[/'#27#5'[/'#27'P\0'#28#173'\1'#29#249']1'#30#255'`5!'#255'c9&'#255'g' - +'>,'#255'qH6'#255#133'YE'#255#153'iT'#255#172'yd'#255#186#136'q'#255#191#144 - +'}'#255#196#153#136#255#202#162#146#255#207#171#156#255#211#178#165#255#214 - +#183#171#255#216#186#175#255#217#188#177#255#218#190#179#255#219#191#182#255 - +#219#192#182#255#219#192#181#255#218#189#179#255#217#187#177#255#215#185#173 - +#255#213#182#169#255#210#176#163#255#205#169#154#255#200#160#144#255#195#151 - +#133#255#190#142'z'#255#183#132'o'#255#167'u_'#255#148'eP'#255#127'S@'#255'm' - +'E2'#255'f=*'#255'b7%'#255'_4 '#255']1'#30#255'\0'#28#235'[/'#27#147'[/'#27 - +'5'#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#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#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 - +#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#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#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'[' - ,'/'#27#18'[/'#27'i\0'#28#199'\1'#29#254']1'#30#255'_4 '#255'a6#'#255'd9('#255 - +'g>,'#255'oF3'#255'}Q>'#255#138'[G'#255#149'fQ'#255#160'oZ'#255#170'xa'#255 - +#176'}h'#255#180#128'l'#255#183#133'p'#255#186#136's'#255#188#138'u'#255#188 - +#139'v'#255#187#138'u'#255#186#135'r'#255#183#132'n'#255#178#128'j'#255#174 - +'|e'#255#168'v`'#255#158'mW'#255#146'bN'#255#133'YE'#255'yM;'#255'mC1'#255'g' - +'>+'#255'c9&'#255'`6"'#255'^3'#31#255']1'#30#255'\0'#28#248'\0'#28#173'[/'#27 - +'O[/'#27#5#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#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#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#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#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#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'[/'#27#20'[/'#27'V\0'#28#153 - +'\0'#28#220'\1'#29#255']1'#30#255'^3'#31#255'`5!'#255'a7$'#255'c9&'#255'e;(' - +#255'f=*'#255'g>,'#255'i@.'#255'jB0'#255'mE2'#255'qH5'#255'tJ7'#255'qG5'#255 - +'lC1'#255'jA0'#255'h?-'#255'g>+'#255'e<)'#255'd:('#255'c9&'#255'a6#'#255'`5!' - +#255'^2'#31#255']1'#30#255'\1'#29#252'\0'#28#201'[/'#27#134'[/'#27'C[/'#27#8 - +#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#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#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#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#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#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#0#0 - +#0#0#0#0#0#0#0#0'[/'#27#31'[/'#27'_[/'#27#138'\0'#28#176'\0'#28#213'\0'#28 - +#248'\1'#29#255'\1'#29#255'\1'#29#255']1'#30#255'^2'#31#255'^2'#31#255'^3'#31 - +#255'^3'#31#255'^3'#31#255'^2'#31#255']1'#30#255']1'#30#255'\1'#29#255'\1'#29 - +#255'\1'#29#255'\0'#28#241'\0'#28#203'\0'#28#165'[/'#27#127'[/'#27'N[/'#27#15 - +#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#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#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#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#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#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#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'[/'#27#2'[/'#27'![/'#27'E[/'#27'U[/'#27'a[/'#27'm[/'#27'y[/'#27 - +#134'\0'#29#141'[/'#27#130'[/'#27'v[/'#27'j[/'#27'^[/'#27'Q[/'#27'=[/'#27#23 - +#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#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#255#255#255#255#255#255#255#128#0#255#255 - +#255#255#255#255#255#255#255#255#255#255#255#224#0#0#3#255#255#255#255#255 - +#255#255#255#255#255#255#254#0#0#0#0'?'#255#255#255#255#255#255#255#255#255 - +#255#240#0#0#0#0#7#255#255#255#255#255#255#255#255#255#255#128#0#0#0#0#0#255 - +#255#255#255#255#255#255#255#255#254#0#0#0#0#0#0'?'#255#255#255#255#255#255 - +#255#255#248#0#0#0#0#0#0#15#255#255#255#255#255#255#255#255#224#0#0#0#0#0#0#3 - +#255#255#255#255#255#255#255#255#128#0#0#0#0#0#0#0#255#255#255#255#255#255 - +#255#254#0#0#0#0#0#0#0#0'?'#255#255#255#255#255#255#252#0#0#0#0#0#0#0#0#31 - +#255#255#255#255#255#255#240#0#0#0#0#0#0#0#0#7#255#255#255#255#255#255#224#0 - +#0#0#0#0#0#0#0#3#255#255#255#255#255#255#128#0#0#0#0#0#0#0#0#1#255#255#255 - +#255#255#255#0#0#0#0#0#0#0#0#0#0#127#255#255#255#255#254#0#0#0#0#0#0#0#0#0#0 - +'?'#255#255#255#255#252#0#0#0#0#0#0#0#0#0#0#31#255#255#255#255#248#0#0#0#0#0 - +#0#0#0#0#0#15#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0#7#255#255#255#255#224#0 - +#0#0#0#0#0#0#0#0#0#3#255#255#255#255#192#0#0#0#0#0#0#0#0#0#0#1#255#255#255 - +#255#128#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#127 - +#255#255#254#0#0#0#0#0#0#0#0#0#0#0#0#127#255#255#254#0#0#0#0#0#0#0#0#0#0#0#0 - +'?'#255#255#252#0#0#0#0#0#0#0#0#0#0#0#0#31#255#255#248#0#0#0#0#0#0#0#0#0#0#0 - +#0#15#255#255#240#0#0#0#0#0#0#0#0#0#0#0#0#7#255#255#240#0#0#0#0#0#0#0#0#0#0#0 - +#0#7#255#255#224#0#0#0#0#0#0#0#0#0#0#0#0#3#255#255#192#0#0#0#0#0#0#0#0#0#0#0 - +#0#3#255#255#192#0#0#0#0#0#0#0#0#0#0#0#0#1#255#255#128#0#0#0#0#0#0#0#0#0#0#0 - +#0#1#255#255#128#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#127#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#127#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?' - +#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0#31#252#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#31#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#248#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#15#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#7#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3 - +#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0 - ,#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#3#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#15#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15 - +#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0#31#252#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#31#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#127#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#127#255#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#255#255#128#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#128#0#0#0#0#0#0#0#0 - +#0#0#0#0#1#255#255#128#0#0#0#0#0#0#0#0#0#0#0#0#1#255#255#192#0#0#0#0#0#0#0#0 - +#0#0#0#0#3#255#255#192#0#0#0#0#0#0#0#0#0#0#0#0#3#255#255#224#0#0#0#0#0#0#0#0 - +#0#0#0#0#7#255#255#224#0#0#0#0#0#0#0#0#0#0#0#0#15#255#255#240#0#0#0#0#0#0#0#0 - +#0#0#0#0#15#255#255#248#0#0#0#0#0#0#0#0#0#0#0#0#31#255#255#248#0#0#0#0#0#0#0 - +#0#0#0#0#0'?'#255#255#252#0#0#0#0#0#0#0#0#0#0#0#0#127#255#255#252#0#0#0#0#0#0 - +#0#0#0#0#0#0#255#255#255#254#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#0#0#0 - +#0#0#0#0#0#0#0#1#255#255#255#255#128#0#0#0#0#0#0#0#0#0#0#3#255#255#255#255 - +#128#0#0#0#0#0#0#0#0#0#0#7#255#255#255#255#192#0#0#0#0#0#0#0#0#0#0#15#255#255 - +#255#255#224#0#0#0#0#0#0#0#0#0#0#31#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0 - +#31#255#255#255#255#248#0#0#0#0#0#0#0#0#0#0'?'#255#255#255#255#252#0#0#0#0#0 - +#0#0#0#0#0#127#255#255#255#255#254#0#0#0#0#0#0#0#0#0#1#255#255#255#255#255 - +#255#0#0#0#0#0#0#0#0#0#3#255#255#255#255#255#255#128#0#0#0#0#0#0#0#0#7#255 - +#255#255#255#255#255#224#0#0#0#0#0#0#0#0#15#255#255#255#255#255#255#240#0#0#0 - +#0#0#0#0#0#31#255#255#255#255#255#255#248#0#0#0#0#0#0#0#0#127#255#255#255#255 - +#255#255#254#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#128#0#0#0#0#0#0 - +#3#255#255#255#255#255#255#255#255#192#0#0#0#0#0#0#7#255#255#255#255#255#255 - +#255#255#240#0#0#0#0#0#0#31#255#255#255#255#255#255#255#255#252#0#0#0#0#0#0 - +#127#255#255#255#255#255#255#255#255#255#0#0#0#0#0#3#255#255#255#255#255#255 - +#255#255#255#255#224#0#0#0#0#15#255#255#255#255#255#255#255#255#255#255#252#0 - +#0#0#0#127#255#255#255#255#255#255#255#255#255#255#255#192#0#0#7#255#255#255 - +#255#255#255#255#255#255#255#255#255#254#0#1#255#255#255#255#255#255#255#255 - +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 - +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255 - +#255#255#255#255#255#255#255#255#255'('#0#0#0'@'#0#0#0#128#0#0#0#1#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'@@@'#4'III'#7'III'#7 - +'333'#5#128#128#128#2#0#0#0#1#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#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'UUU'#6'DDD' - +#15'FFF'#22'EEE'#26'DDD'#30'III#GGG/DDD'#30#255'j>'#31#253'g>#'#249'[>+'#235'PB8'#218'HE' - +'C'#203'FEC'#195'EED'#184'DDD'#166'DDDqEEE4@@@'#20'@@@'#4#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#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#1 - +'999'#9'BBB'#31'CCCPEDD'#143'FFE'#182'NB:'#211'Z?-'#231'g>#'#249'l?'#31#255 - +'zK$'#253#150']*'#255#165'h.'#255#172'm0'#255#180's2'#255#186'x4'#255#189'{4' - +#255#192#127'5'#255#190'|4'#255#187'x4'#255#182'u3'#255#175'p1'#255#167'j/' - +#255#156'b+'#255#131'R&'#254'oB '#255'i>!'#253'_>)'#238'S@6'#222'FEB'#203'DD' - +'C'#190'DDD'#164'CCCkCCC.PPP'#16'UUU'#3#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#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#128#128#128#2'CCC'#19'BBBBDDD'#136'EED'#179'LA9' - +#209'`=&'#243'k?'#31#255#127'N&'#254#154'`,'#255#176'q1'#255#191'~5'#255#200 - +#138'7'#255#207#145'8'#255#210#149'9'#255#213#153'9'#255#217#157':'#255#219 - +#160';'#255#221#162';'#255#220#162':'#255#217#158':'#255#215#155':'#255#211 - +#151'9'#255#208#146'8'#255#203#141'8'#255#194#129'6'#255#183'v4'#255#163'f.' - +#255#137'U('#254'qC"'#254'f' - +'>>!+++'#6#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#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'@@@'#4'BBB'#27'CC' - +'C[CCB'#165'LD='#203']<('#238'j> '#255#135'R('#254#176'p3'#255#193#128'7'#255 - +#202#139'9'#255#211#151';'#255#220#162'<'#255#227#170'>'#255#232#176'?'#255 - +#234#180'?'#255#237#182'?'#255#239#185'@'#255#241#187'@'#255#242#188'A'#255 - +#241#187'@'#255#240#185'A'#255#238#183'@'#255#235#180'@'#255#233#178'?'#255 - +#229#173'>'#255#222#165'='#255#215#156'<'#255#205#144':'#255#196#133'8'#255 - +#185'x5'#255#152'^-'#255'oC"'#254'd<#'#247'QA7'#220'FFE'#200'CCC'#180'CCC}AA' - +'A/UUU'#9#0#0#0#1#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#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'CCC&DDDpECC'#180'X<,'#232'i=' - +'!'#254#128'O('#254#170'l3'#255#194#130':'#255#210#150'>'#255#220#163'?'#255 - +#227#171'A'#255#234#180'B'#255#240#187'D'#255#242#190'D'#255#244#193'E'#255 - +#246#194'D'#255#247#195'E'#255#248#197'E'#255#249#197'E'#255#249#198'E'#255 - +#249#197'E'#255#248#196'E'#255#247#195'E'#255#246#195'E'#255#245#194'D'#255 - +#243#191'D'#255#240#188'C'#255#236#183'C'#255#230#174'B'#255#223#165'@'#255 - +#215#156'?'#255#200#137';'#255#182'u6'#255#146'[,'#255'm@!'#254'`:%'#244'KA;' - +#211'CCC'#189'CCC'#144'BBB>PPP'#16#128#128#128#2#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'999'#9'@@@4CCC'#133 - +'HD@'#192'_9$'#244'rE%'#254#164'h3'#255#191#127';'#255#206#146'?'#255#219#163 - +'C'#255#232#178'F'#255#238#185'G'#255#241#189'H'#255#244#193'H'#255#246#195 - +'I'#255#247#196'I'#255#247#197'J'#255#247#197'I'#255#247#198'I'#255#248#198 - +'I'#255#248#198'I'#255#248#197'I'#255#248#198'I'#255#248#198'I'#255#248#198 - +'I'#255#247#197'I'#255#247#197'I'#255#247#196'I'#255#246#196'I'#255#245#194 - +'H'#255#242#190'H'#255#239#187'H'#255#235#182'G'#255#224#168'D'#255#211#153 - +'A'#255#196#134'='#255#177'q7'#255#133'Q)'#254'e: '#253'N?7'#218'DDC'#195'CC' - +'C'#160'FFFP@@@'#20#0#0#0#2#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 - +#0#0#0#0#0#0#0#0#0'III'#7'FFF3CCC'#145'LB;'#204'd:"'#250'|L('#254#180's9'#255 - +#202#143'A'#255#216#159'F'#255#228#174'I'#255#236#184'K'#255#241#191'L'#255 - +#243#193'M'#255#244#194'M'#255#244#195'M'#255#245#196'M'#255#245#195'M'#255 - +#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255 - +#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255 - +#245#195'M'#255#245#195'M'#255#245#196'M'#255#245#195'M'#255#244#194'M'#255 - +#243#194'M'#255#242#192'M'#255#238#186'L'#255#232#179'J'#255#220#165'F'#255 - +#208#150'C'#255#190#127'<'#255#147'[.'#255'h< '#255'S=1'#228'EED'#199'DDD' - +#168'BBBUGGG'#18#0#0#0#1#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#0 - +'@@@'#4'FFF(EEE'#134'P?5'#212'e:!'#254#137'U,'#254#186'z='#255#208#150'E'#255 - +#224#171'L'#255#233#181'O'#255#238#187'P'#255#240#191'P'#255#242#192'Q'#255 - +#242#193'Q'#255#242#193'Q'#255#242#193'P'#255#242#193'Q'#255#242#193'Q'#255 - +#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255 - ,#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255 - +#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255 - +#242#193'Q'#255#242#193'Q'#255#241#192'Q'#255#239#189'P'#255#234#184'O'#255 - +#228#175'M'#255#215#159'I'#255#194#132'@'#255#160'd3'#255'k?"'#254'X:*'#236 - +'FDC'#201'CCC'#164'AAAG;;;'#13#0#0#0#1#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'U' - +'UU'#3'BBB'#31'CCCvO=3'#211'f:'#31#255#150']2'#255#190#128'A'#255#211#155'I' - +#255#226#175'Q'#255#234#185'S'#255#237#188'T'#255#238#190'T'#255#239#191'U' - +#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U' - +#255#239#191'U'#255#239#191'U'#255#235#189'S'#255'|d,'#255'N>'#28#255'4*'#19 - +#255'=1'#22#255'WE'#31#255'w_*'#255#173#139'='#255#239#191'U'#255#239#191'U' - +#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U' - +#255#239#191'U'#255#239#191'U'#255#239#190'T'#255#238#189'U'#255#236#187'S' - +#255#230#179'R'#255#217#162'L'#255#198#138'D'#255#170'l8'#255'pC$'#254'Z8''' - +#240'DBB'#197'CCC'#153'FFF:@@@'#8#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#2'FFF'#22 - +'BBBeJ?9'#195'b8 '#254#150']2'#255#194#133'E'#255#213#158'N'#255#226#176'T' - +#255#233#185'W'#255#236#187'W'#255#236#188'X'#255#236#188'X'#255#236#188'X' - +#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X' - +#255#236#188'X'#255'cO%'#255#4#3#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#18#14#7#255'A4'#24#255#134'k2' - +#255#218#174'R'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X' - +#255#236#188'X'#255#236#188'X'#255#236#187'W'#255#234#186'W'#255#229#180'U' - +#255#218#165'P'#255#201#143'H'#255#173'o<'#255'k>#'#254'S;-'#231'CCC'#193'CC' - +'C'#141'DDD-fff'#5#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'@@@'#12'DDDKFA='#179'`7 '#251#137'S-' - +#255#192#131'E'#255#214#161'Q'#255#226#176'W'#255#231#183'Y'#255#233#185'[' - +#255#233#186'['#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255#234#185'Z' - +#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255'L<'#29#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#7#3#255'P' - +'?'#31#255#203#161'N'#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255#234 - +#185'Z'#255#233#186'['#255#232#183'Z'#255#228#178'Y'#255#219#167'T'#255#201 - +#143'K'#255#163'g8'#255'f: '#255'O=4'#222'DDD'#188'CCCzBBB'#27#0#0#0#1#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'U' - +'UU'#3'GGG$D@@'#147'\6#'#245'{I*'#254#185'{C'#255#211#157'R'#255#225#175'Z' - +#255#229#181'\'#255#230#183']'#255#230#183']'#255#230#183']'#255#230#183']' - +#255#230#183']'#255#230#183']'#255#230#183']'#255#230#183']'#255#230#183']' - +#255#230#183']'#255#138'm8'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#24#20#10#255'x_0' - +#255#226#181'['#255#230#183']'#255#230#183']'#255#230#183']'#255#230#181'\' - +#255#227#177'['#255#217#165'V'#255#196#136'J'#255#151']4'#255'b8 '#254'K@9' - +#214'CCC'#175'AAAJ...'#11#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'@@@'#16'CCC\V6'''#228'nA&'#254#178'tA'#255#205 - +#151'R'#255#221#172'\'#255#226#179'_'#255#228#180'_'#255#228#180'_'#255#228 - +#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228 - +#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#17#13#7#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#1#1#255'H9'#30#255#224#178']' - +#255#228#180'_'#255#228#180'_'#255#227#179'^'#255#224#175']'#255#213#160'W' - +#255#190#129'H'#255#137'T/'#255'^4 '#252'FB?'#201'CCC'#140'DDD"'#0#0#0#3#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'@@@'#4'FFF,J=7' - +#175'`4'#30#255#165'g;'#255#200#144'Q'#255#217#166'\'#255#223#176'`'#255#225 - +#177'`'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225 - +#177'a'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225 - +#177'a'#255#218#171'^'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#11#9#5#255#196#154'U'#255#225#177'a'#255#225#177 - +'`'#255#224#177'a'#255#220#171'^'#255#208#154'W'#255#184'{F'#255'nA%'#254'T8' - +'*'#233'DDD'#180'CCCX333'#15#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'CCC'#19'CCCjY5#'#239'~J,'#254#191#132'M'#255#213#162']'#255 - ,#220#171'a'#255#221#173'c'#255#222#174'b'#255#222#174'b'#255#222#174'b'#255 - +#222#174'b'#255#222#174'b'#255#222#174'b'#255#222#174'b'#255#222#174'b'#255 - +#222#174'b'#255#222#174'b'#255#222#174'b'#255#154'yC'#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#15#11#6 - +#255#218#172'`'#255#222#174'b'#255#222#174'b'#255#221#173'b'#255#217#167'_' - +#255#202#146'T'#255#156'a9'#255'^4'#30#254'G@='#206'DDD'#151'>>>)@@@'#4#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'AAA+L;4'#188'b6 '#254#170 - +'l@'#255#206#152'Z'#255#217#168'b'#255#219#171'd'#255#219#171'd'#255#219#171 - +'d'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171 - +'d'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171 - +'d'#255#219#171'd'#255#26#20#12#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'oW3'#255#219#171'd'#255#219 - +#171'd'#255#219#171'd'#255#218#169'c'#255#212#161'_'#255#187#127'L'#255'uD)' - +#254'W6('#238'CCC'#182'CCC[III'#14#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0'@@@'#12'EBBS[3'#31#244#134'O/'#255#192#134'Q'#255#212#162'b'#255#215 - +#167'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216 - +#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216 - +#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#198 - +#154'\'#255#5#4#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255'!'#25#15#255#216#168'd'#255#216#168'd'#255#216#168 - +'d'#255#216#168'd'#255#214#166'd'#255#202#147'Y'#255#161'e='#255'^2'#29#255 - +'J?:'#208'CCC'#137'EEE'#26#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'C' - +'CC'#23'O9/'#171'`3'#31#254#174'pD'#255#203#150']'#255#212#163'e'#255#213#164 - +'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164 - +'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164 - +'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164 - +'e'#255#173#133'R'#255#3#2#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#22#17#11#255#213#164'e'#255#213#164'e'#255#213#164 - +'e'#255#213#164'e'#255#213#164'f'#255#209#158'a'#255#187#128'O'#255'yD)'#254 - +'W4$'#241'BBB'#169'DDD1@@@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'FFF(W4' - +'$'#229'{E)'#255#191#134'T'#255#207#157'c'#255#210#160'f'#255#210#160'f'#255 - +#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255 - +#210#160'f'#255#152'tJ'#255'[E,'#255'K9$'#255'{]<'#255#196#149'_'#255#210#160 - +'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#159'yM' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'"' - +#26#17#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210 - +#160'f'#255#209#160'e'#255#199#146']'#255#156'_;'#255'\1'#28#254'FBA'#188'FF' - +'FXNNN'#13#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'FFF'#11'F@=T\/'#28#253#151'\9'#255 - +#200#147'_'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255 - +#207#156'e'#255#207#156'e'#255#207#156'e'#255#178#135'W'#255'$'#27#17#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'N:&'#255#207#156'e'#255#207 - +#156'e'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255#3#2#1#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'uX9'#255#207#156'e'#255#207 - +#156'e'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255#207#157'e'#255#204 - +#153'b'#255#180'wK'#255'a4'#30#254'M;3'#216'DDD'#132'==='#25#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0'CCC'#19'N9.'#159'^2'#30#254#176'rI'#255#202#150'c'#255#203 - +#153'e'#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203 - +#153'f'#255#163'zQ'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#29#22#15#255#203#153'f'#255#203#153'f'#255#203#153 - +'f'#255#203#153'f'#255#14#10#7#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - ,#0#0#255#4#3#2#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203#153'f' - +#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203#152'e'#255#190#134'X' - +#255'yC)'#254'V5&'#239'DDD'#165'FFF('#128#128#128#2#0#0#0#0#0#0#0#0#0#0#0#0 - +'GGG'#25'V4%'#212's@&'#254#186#128'U'#255#199#148'd'#255#200#148'd'#255#200 - +#148'd'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255#198#146'd'#255#12#9 - +#6#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#138'fE'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255 - +#15#11#7#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'&'#28#19#255#145'kH'#255 - +#200#148'd'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255 - +#200#148'd'#255#200#148'd'#255#200#148'd'#255#194#141'^'#255#146'W6'#255'[0' - +#28#254'EBB'#178'CCC9UUU'#6#0#0#0#0#0#0#0#0#0#0#0#0'JAA'#31'\1'#29#249#140'P' - +'2'#255#190#135'\'#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#196#143 - +'c'#255#196#143'c'#255#196#143'c'#255'>-'#31#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'&' - +#28#19#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#25#18#12#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1 - +#255'*'#31#21#255'kM6'#255#187#137'_'#255#196#143'c'#255#196#143'c'#255#196 - +#143'c'#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#196 - +#143'c'#255#196#143'c'#255#196#143'c'#255#194#141'b'#255#170'kF'#255'\0'#28 - +#254'L<5'#203'CCCH333'#10#0#0#0#0#0#0#0#0#0#0#0#1'K3+@[/'#27#255#160'`>'#255 - +#190#136'_'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255 - +#191#137'`'#255#189#135'`'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#30#21#15#255 - +#191#137'`'#255#191#137'`'#255#191#137'`'#255'aF1'#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#5#3#2#255#165'vS'#255#191#137'`' - +#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`' - +#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`' - +#255#191#137'`'#255#191#137'`'#255#191#136'`'#255#178'vQ'#255'h7 '#253'Q8,' - +#220'DDDV;;;'#13#0#0#0#0#0#0#0#0'UUU'#3'R4''^[/'#27#255#169'hF'#255#187#131 - +']'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132 - +'^'#255'uS;'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'{W>'#255#187#132'^'#255 - +#187#132'^'#255#187#132'^'#255#185#130'^'#255#19#14#10#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255#158'oO'#255#187#132'^'#255#187#132'^' - +#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^' - +#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^' - +#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#181'{V'#255'r<"'#255'T6''' - +#228'BBBd@@@'#16#0#0#0#0#0#0#0#0'UUU'#6'T5''}_2'#30#253#171'kI'#255#183'}Z' - +#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255'. '#23#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#1#1#0#255'S9)'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z' - +#255#183'~Z'#255#173'xV'#255#31#21#15#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'b' - +'C0'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z' - +#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255 - +#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#181'zV'#255'zA%'#255'X4$' - +#237'DDDqCCC'#19#0#0#0#0#0#0#0#0'@@@'#8'U4%'#149'f5'#31#252#172'mK'#255#180 - +'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#6#4#3 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#19#13#9#255#153'gK'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX' - +#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255'{S<'#255'+'#29#21#255#7 - +#4#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1 - +#255'gF3'#255#180'yX'#255#180'yX'#255#180'yX'#255#139']D'#255'+'#29#21#255#8 - +#6#4#255#8#6#4#255#16#11#8#255'W:*'#255#178'wV'#255#180'yX'#255#180'yX'#255 - +#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#179'yV'#255#131 - +'F+'#255'[3!'#245'CCCyIII'#21#0#0#0#0#0#0#0#0'UUU'#6'X3"'#165'n:"'#253#172'p' - +'O'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#173'uU' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1 - +#0#0#255'P6'''#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW' - ,#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255 - +#177'wW'#255#177'wW'#255#158'jM'#255'W;+'#255''''#26#19#255'"'#23#17#255'%' - +#25#18#255'W:+'#255#167'qS'#255#177'wW'#255#177'wW'#255#177'wW'#255'@+'#31 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#3#2#1#255 - +#149'dI'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177 - +'wW'#255#177'vV'#255#139'M0'#255'[1'#30#250'DDDpCCC'#19#0#0#0#0#0#0#0#0'UUU' - +#3'Y1'#31#182'v>%'#255#172'oQ'#255#175'tW'#255#175'tW'#255#175'tW'#255#175't' - +'W'#255#175'tW'#255'}S?'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#26#17#13#255#150'cK'#255#175'tW'#255#175'tW'#255#175'tW'#255 - +#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175 - +'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW' - +#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255 - +#175'tW'#255'dC2'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#9#6#4#255#169'pU'#255#175'tW'#255#175'tW'#255#175't' - +'W'#255#175'tW'#255#175'tW'#255#174'sU'#255#145'S6'#255']0'#28#254'DBBd@@@' - +#16#0#0#0#0#0#0#0#0#0#0#0#0'Z0'#30#175'v=%'#255#171'nP'#255#174'rV'#255#174 - +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255'L2&'#255#0#0#0#255'/'#31#23#255 - +'}R>'#255' '#21#16#255'!'#22#17#255#139'[E'#255#174'rV'#255#174'rV'#255#174 - +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV' - +#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255 - +#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174 - +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255'?*'#31#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'6#'#27 - +#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#173'qT'#255 - +#145'S7'#255'\1'#29#254'AAAV;;;'#13#0#0#0#0#0#0#0#0#0#0#0#0'Z1'#30#150'n;$' - +#252#169'jM'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255 - +#149'bI'#255'@* '#255#170'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU' - +#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255 - +#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172 - +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU' - +#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255 - +'G/#'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#24#16#12#255#172'qU'#255#172'qU'#255#172'qU'#255#172 - +'qU'#255#172'qU'#255#171'oS'#255#138'N3'#255'\2'#31#249'DDDG999'#9#0#0#0#0#0 - +#0#0#0#0#0#0#0'X1!|g7#'#250#167'gI'#255#172'pT'#255#172'qU'#255#172'qU'#255 - +#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172 - +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU' - +#255#172'qU'#255'P5('#255')'#27#20#255#27#18#13#255'5#'#26#255'pJ8'#255#172 - +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU' - +#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255 - +#172'qU'#255#172'qU'#255#162'jO'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#9#6#4#255#172'qU'#255#172 - +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#170'mR'#255#131'I.'#255'[4"'#241 - +'FFF7UUU'#6#0#0#0#0#0#0#0#0#0#0#0#0'Y1!`b5 '#251#164'cG'#255#172'pU'#255#173 - +'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW' - +#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255 - +#173'rW'#255'}S?'#255#9#6#5#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#16#11#8#255#152'dM'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255 - +#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173 - +'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255'$'#24#18#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#2#255#173'r' - +'W'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#170'mQ'#255'|C*'#255 - +'W4$'#229'CCC&'#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0'X5!A^2'#31#254#162'bE'#255 - +#173'rV'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175 - +'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY' - +#255#175'tY'#255'{Q?'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#14#9#7#255#173'tY'#255#175'tY'#255#175'tY'#255 - +#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175 - +'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#132'XC'#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#21 - +#14#11#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#174'tY'#255#170'm' - +'P'#255't?('#254'U5&'#203'@@@'#24#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'X0'#24' ^2' - +#31#255#156'\A'#255#175'v\'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`' - +#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255 - ,#177'y`'#255#177'y`'#255#177'y`'#255#11#8#6#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#136']J'#255#177 - +'y`'#255#177'y`'#255'7%'#30#255#9#6#5#255#13#9#7#255#16#11#9#255#26#18#14#255 - +#139'_K'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177 - +'y`'#255#18#12#9#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255'<)!'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#176 - +'x^'#255#169'kP'#255'j<&'#253'U4%'#168';;;'#13#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0'^2'#29#234#136'O4'#255#176'x^'#255#180'~f'#255#180'~f'#255#180'~f' - +#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255 - +#180'~f'#255#180'~f'#255#180'~f'#255#146'gS'#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#139'bO'#255#170'x`'#255#20#14#11#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255']A4'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255 - +#180'~f'#255'qO@'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#1#1#0#255#165't^'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255 - +#178'zb'#255#162'dH'#255'_3'#31#254'R6)c@@@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0'[/'#29#153'r?)'#252#174'sZ'#255#182#129'j'#255#183#131'l'#255#183 - +#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183 - +#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255'ZA5' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#5#3#3#255#179#127'j'#255'uTE'#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'{XI'#255#183#131'l' - +#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#20#15#12#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255':)"'#255#183#131'l'#255 - +#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#179'|c'#255#140 - +'R9'#255'\2'#31#248'@@6'#28#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +'[/'#29'E`5 '#252#166'iO'#255#183#131'l'#255#186#136'q'#255#186#136'q'#255 - +#186#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255 - +#186#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255'\D8'#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255'oQC'#255#186#136'q'#255'X@6'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#12#9#7#255#186#136'q'#255#186 - +#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255#148'lZ'#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#169'|g'#255#186#136'q'#255#186 - +#136'q'#255#186#136'q'#255#186#136'q'#255#185#134'q'#255#177'y`'#255'tB+'#254 - +'W2!'#194'III'#14#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#4'^3' - +#30#245#144'W='#255#184#134'o'#255#189#141'x'#255#189#141'x'#255#189#141'x' - +#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#189#141'x' - +#255#189#141'x'#255#189#141'x'#255#189#141'x'#255'tWJ'#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'('#30#26#255 - +#189#141'x'#255#189#141'x'#255'?/('#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#187#139'v'#255#189#141 - +'x'#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#172#128 - +'m'#255'_G<'#255#1#0#0#255#0#0#0#255'-"'#28#255#189#141'x'#255#189#141'x'#255 - +#189#141'x'#255#189#141'x'#255#189#141'x'#255#186#137's'#255#171'oU'#255'a6"' - +#253'T5$jUUU'#3#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'\/' - +#27#170'vD,'#252#181#128'h'#255#190#144'{'#255#192#146'~'#255#192#146'~'#255 - +#192#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255 - +#192#146'~'#255#192#146'~'#255#192#146'~'#255#186#142'z'#255#1#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#1#1#255#186#142'z' - +#255#192#146'~'#255#192#146'~'#255'=.('#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#192#146'~'#255#192 - +#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255#192 - +#146'~'#255#192#146'~'#255#0#0#0#255#0#0#0#255#167#127'n'#255#192#146'~'#255 - +#192#146'~'#255#192#146'~'#255#192#146'~'#255#191#145'}'#255#186#137's'#255 - +#149'[A'#255'^1'#31#250'F:.'#22#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'\.'#28'H`5 '#252#164'jP'#255#190#143'z'#255#194#151#131 - +#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151 - +#131#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151#131#255#194 - +#151#131#255#27#21#18#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255' '#25#21#255#194#151#131#255#194#151#131#255#194#151#131#255'7*%' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#12#9#8#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151 - +#131#255#194#151#131#255#194#151#131#255#194#151#131#255#190#149#129#255#0#0 - ,#0#255'0% '#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151#131 - +#255#194#151#131#255#192#147#127#255#180'~f'#255'q@+'#252'Z0'#29#180#0#0#0#2 - +#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' - +#28#199'{H2'#252#184#134'o'#255#196#153#134#255#197#156#137#255#197#156#137 - +#255#197#156#137#255#197#156#137#255#197#156#137#255#197#156#137#255#197#156 - +#137#255#197#156#137#255#197#156#137#255#197#156#137#255'G81'#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'WE='#255#197#156#137#255#197 - +#156#137#255#191#152#133#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#135'k^'#255#197#156#137#255#197 - +#156#137#255#197#156#137#255#197#156#137#255#197#156#137#255#197#156#137#255 - +#197#156#137#255#197#156#137#255#16#12#11#255#174#138'y'#255#197#156#137#255 - +#197#156#137#255#197#156#137#255#197#156#137#255#197#155#136#255#191#145'|' - +#255#151'_F'#255'^3'#31#253'T2!-'#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'#29'5_4 '#254#161'hP'#255#195#152#132 - +#255#200#161#143#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161 - +#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200 - +#161#144#255'xaW'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1 - +#255#171#138'{'#255#200#161#144#255#200#161#144#255#127'f\'#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255')!'#30#255 - +#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144 - +#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#153'{n' - +#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161 - +#144#255#198#156#138#255#181#128'h'#255'l>*'#252'Z1'#30#159#0#0#0#1#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'#27#173'uE/'#249#186#136'r'#255#201#162#145#255#203#165#150#255#203#165 - +#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203 - +#165#150#255#203#165#150#255#203#165#150#255#163#132'x'#255#0#0#0#255#0#0#0 - +#255#26#21#19#255',$!'#255'-%!'#255#156'~s'#255#203#165#150#255#203#165#150 - +#255#203#165#150#255'@4/'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#4#3#3#255#186#151#138#255#203#165#150#255#203#165 - +#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203 - +#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255 - +#203#165#150#255#203#165#150#255#203#165#150#255#203#164#149#255#195#152#132 - +#255#146'\D'#255'_3'#31#247'R3'#30#25#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'Z-'#30'"^4 '#252#155 - +'cK'#255#196#153#136#255#206#169#155#255#207#171#156#255#207#171#156#255#207 - +#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255 - +#207#171#156#255#203#167#152#255#0#0#0#255#0#0#0#255#193#159#145#255#207#171 - +#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207 - +#171#156#255'E94'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#15#12#11#255#182#150#137#255#207#171#156#255#207#171#156#255#207#171#156 - +#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171 - +#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207 - +#171#156#255#207#171#156#255#206#170#155#255#201#162#145#255#178'}f'#255'h<(' - +#250'[0'#28#129#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']1'#29#130'f:&'#250#171'u' - +'^'#255#202#164#148#255#210#176#163#255#210#177#164#255#210#177#164#255#210 - +#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255 - +#210#177#164#255#2#1#1#255#27#22#21#255#210#177#164#255#210#177#164#255#210 - +#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255 - +#210#177#164#255'I=8'#255#6#5#4#255#0#0#0#255#0#0#0#255#0#0#0#255'''!'#31#255 - +#206#175#162#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164 - +#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177 - +#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210 - +#177#164#255#210#176#163#255#206#170#155#255#188#139'w'#255'zI4'#252'^2'#29 - +#222']/'#23#11#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#1'^1'#29#181'oA-' - +#249#182#132'n'#255#208#173#159#255#213#182#169#255#213#183#170#255#213#183 - +#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213 - +#183#170#255#12#10#9#255#159#136#127#255#213#183#170#255#213#183#170#255#213 - +#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255 - +#213#183#170#255#213#183#170#255#139'xo'#255#0#0#0#255#0#0#0#255'% '#30#255 - +#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170 - +#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183 - ,#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213 - +#183#170#255#213#183#170#255#211#178#165#255#196#152#134#255#136'T?'#254'`1 ' - +#243'U+'#28'$'#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#0'U+'#21#12 - +']2'#30#218'zK5'#251#192#146#127#255#212#180#168#255#216#187#176#255#217#188 - +#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217 - +#188#177#255'o`Z'#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188 - +#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217 - +#188#177#255#217#188#177#255#27#24#22#255#0#0#0#255#9#8#7#255#209#180#171#255 - +#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177 - +#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188 - +#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217 - +#188#177#255#215#185#173#255#202#163#147#255#152'cM'#255'`5 '#252'X.'#27'B'#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#0#0#0#0#0#0#0#0#0'].'#23'!_' - +'3 '#241#135'V@'#254#197#155#137#255#215#185#173#255#219#193#183#255#220#194 - +#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220 - +#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255 - +#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184 - +#255#220#194#184#255#4#4#4#255#13#11#11#255#197#173#164#255#220#194#184#255 - +#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184 - +#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194 - +#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#183#255#218 - +#190#179#255#205#169#154#255#165'pY'#255'b8$'#252'[/'#27'h'#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Y1'#28'?_' - +'3!'#249#132'T?'#252#193#148#130#255#215#186#174#255#223#198#189#255#223#200 - +#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223 - +#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255 - +#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191 - +#255#199#179#171#255#215#192#183#255#223#200#191#255#223#200#191#255#223#200 - +#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223 - +#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255 - +#223#200#191#255#223#200#191#255#223#199#190#255#219#192#183#255#203#165#150 - +#255#158'kS'#255'c9%'#251']0'#30#147#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#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'Z-'#25'3_3'#30 - +#234'wI5'#250#185#138'v'#255#215#186#174#255#225#203#194#255#227#205#197#255 - +#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197 - +#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205 - +#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227 - +#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255 - +#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197 - +#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#226#204 - +#196#255#220#194#183#255#200#159#143#255#144'_H'#254'a6"'#253'\1'#30'y'#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#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'\3'#31#25'^2'#29#207'nB.'#249#175'~i'#255 - +#213#182#169#255#225#202#193#255#230#209#203#255#230#211#205#255#230#211#205 - +#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211 - +#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230 - +#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255 - +#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205 - +#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#210 - +#204#255#227#205#198#255#219#191#181#255#193#149#131#255#131'R='#251'_4 '#247 - +'Z0'#26'O'#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#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'` '#8']0' - +#28#169'e:'''#250#148'aL'#255#196#153#136#255#220#193#183#255#229#209#202#255 - +#233#216#210#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211 - +#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216 - +#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234 - +#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255 - +#234#216#211#255#234#216#211#255#234#216#211#255#233#216#211#255#231#212#206 - ,#255#224#200#192#255#207#171#156#255#168'va'#255'rE1'#249'^3'#31#230'Y,'#28 - +'.'#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#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'^1'#29'h`3'#31#237'nA/'#249#158'mW'#255#203#165#150#255#224#201#192 - +#255#232#213#208#255#235#219#215#255#237#222#218#255#237#222#218#255#237#222 - +#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237 - +#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255 - +#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218 - +#255#236#220#216#255#233#216#211#255#228#206#200#255#213#182#170#255#177#131 - +'n'#255'}M:'#250'a6"'#253']1'#29#155'U1'#24#21#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#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'].'#23#11 - +']1'#29'~`5!'#246'tF5'#249#166'u`'#255#202#164#148#255#221#195#186#255#230 - +#210#203#255#234#218#213#255#238#224#220#255#240#227#224#255#240#227#225#255 - +#240#227#225#255#240#227#225#255#240#227#225#255#240#227#225#255#240#227#225 - +#255#240#227#225#255#240#227#225#255#240#227#225#255#240#227#225#255#239#225 - +#222#255#236#220#215#255#232#213#207#255#225#203#194#255#210#176#164#255#183 - +#138'u'#255#133'UA'#252'c9&'#254'^2'#30#178'\.'#26''''#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U1'#24#21']0'#30#147'`7"'#251'jA-'#249#133'UA' - +#253#169'zf'#255#201#162#146#255#220#194#184#255#230#211#205#255#233#215#210 - +#255#234#217#212#255#236#220#215#255#237#222#218#255#238#223#220#255#237#222 - +#219#255#236#220#216#255#234#219#213#255#233#216#211#255#231#213#206#255#225 - +#203#194#255#209#174#160#255#181#136'u'#255#145'`L'#255'sG4'#249'c9&'#255'_2' - +#30#198'].'#28'7'#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#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#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'U+'#28#18'\.'#27'^_1'#30#179'c7$'#248'h?,'#251#127 - +'Q;'#251#148'dN'#255#163't_'#255#175#129'n'#255#186#143'~'#255#198#157#141 - +#255#204#167#151#255#201#161#145#255#191#149#132#255#179#135'u'#255#167'ye' - +#255#153'iT'#255#136'WC'#254'pE2'#249'c9&'#255'_3'#31#212'Z/'#27'|].'#29','#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#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#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'U9'#28#9'\.'#26'N^0'#29#157'`' - +'4 '#203'c6#'#230'c7%'#249'd:('#255'f=*'#255'i?-'#252'g>+'#255'e;('#255'd9&' - +#253'b7$'#237'a5!'#214'_1'#30#180'\/'#26'lX,'#26#29#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#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0'`0 '#16'[1'#24'*].'#27'B]1'#29'4\3'#31#25'UU'#0#3#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#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#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#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#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#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#255#255#255#248#15#255 - +#255#255#255#255#254#0#0#127#255#255#255#255#240#0#0#7#255#255#255#255#192#0 - +#0#1#255#255#255#255#0#0#0#0#255#255#255#252#0#0#0#0'?'#255#255#248#0#0#0#0 - +#31#255#255#240#0#0#0#0#7#255#255#192#0#0#0#0#3#255#255#128#0#0#0#0#1#255#255 - +#128#0#0#0#0#0#255#255#0#0#0#0#0#0#127#254#0#0#0#0#0#0#127#252#0#0#0#0#0#0'?' - +#252#0#0#0#0#0#0#31#248#0#0#0#0#0#0#31#248#0#0#0#0#0#0#15#240#0#0#0#0#0#0#15 - ,#240#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#3#192 - +#0#0#0#0#0#0#3#192#0#0#0#0#0#0#3#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0#1#192#0#0 - +#0#0#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0 - +#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0#0#0#1#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0 - +#1#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0#3#192#0#0#0#0#0#0#3 - +#224#0#0#0#0#0#0#3#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#240 - +#0#0#0#0#0#0#15#240#0#0#0#0#0#0#15#248#0#0#0#0#0#0#31#248#0#0#0#0#0#0#31#252 - +#0#0#0#0#0#0'?'#252#0#0#0#0#0#0#127#254#0#0#0#0#0#0#127#254#0#0#0#0#0#0#255 - +#255#0#0#0#0#0#1#255#255#128#0#0#0#0#3#255#255#192#0#0#0#0#7#255#255#224#0#0 - +#0#0#15#255#255#240#0#0#0#0#31#255#255#248#0#0#0#0'?'#255#255#254#0#0#0#0#127 - +#255#255#255#0#0#0#1#255#255#255#255#192#0#0#7#255#255#255#255#240#0#0#31#255 - +#255#255#255#254#0#0#255#255#255#255#255#255#248#31#255#255#255#255#255#255 - +#255#255#255#255#255'('#0#0#0'0'#0#0#0'`'#0#0#0#1#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#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'UUU'#3'333'#5'UUU'#6'III'#7'@@@'#8'@@@'#8'III'#7 - +'UUU'#6'333'#5'UUU'#3#0#0#0#1#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#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#0#0#0#0#0#0#0#0#0#1'@@@' - +#4'@@@'#8'@@@'#16'DDD1BBBMCCC_FCCrDBB'#129'FDD'#133'CCCvCCCcDDDRDDD('#240'l@!'#252'qE!' - +#253'yJ$'#252#129'R&'#252#138'X)'#253#134'T('#253'}N%'#252'uG#'#252'oC"'#253 - +'h=#'#248'Z>.'#230'OC;'#211'FEC'#198'DDC'#187'BBB|CCC&999'#9#0#0#0#1#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#2'<<<'#17'CCCWEED'#170'OB9'#211'd=&'#244'qE"'#253#137'V)'#253 - +#164'h.'#255#186'y3'#255#194#130'5'#255#198#135'6'#255#203#140'7'#255#207#145 - +'8'#255#205#143'7'#255#201#137'7'#255#196#132'6'#255#192#127'5'#255#177'r1' - +#255#152'_+'#254'{L%'#252'k?"'#251'[>-'#233'IEA'#203'EDD'#184'DDDq<<<'#30'@@' - +'@'#4#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#0#0#0#0#0#0#0#0#0#0#0 - +#0#0'@@@'#4'BBB#EDD'#146'KB<'#205'a='''#242'yK&'#252#166'i/'#255#192#128'6' - +#255#205#143'9'#255#217#159'<'#255#226#169'>'#255#230#173'>'#255#232#176'>' - +#255#235#180'?'#255#237#182'@'#255#236#181'?'#255#234#178'>'#255#231#175'>' - +#255#228#171'>'#255#223#165'<'#255#211#150':'#255#199#136'8'#255#182'v5'#255 - +#146'\,'#253'k@"'#252'W?1'#227'GFE'#199'CCC'#171'???=@@@'#8#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#0#0#0#0#0'III'#7'DDD8ECB'#170'[>,'#234'sF$' - +#252#160'e0'#255#196#133';'#255#216#158'@'#255#227#170'A'#255#234#180'C'#255 - +#241#189'D'#255#245#193'E'#255#246#195'F'#255#247#195'F'#255#247#196'E'#255 - +#248#197'F'#255#248#197'E'#255#247#195'F'#255#247#194'F'#255#246#194'E'#255 - +#244#192'E'#255#238#184'C'#255#230#176'C'#255#223#166'A'#255#207#147'='#255 - +#182'w7'#255#138'V+'#253'h>#'#250'NA9'#215'CCC'#186'@@@[;;;'#13#0#0#0#1#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'@@@'#8'EEENGC?'#189'b;%'#245#139'W-'#253#190 - +#127';'#255#212#153'B'#255#227#172'F'#255#239#186'I'#255#242#191'J'#255#244 - +#193'K'#255#246#195'K'#255#247#196'K'#255#247#196'K'#255#247#196'L'#255#247 - +#196'L'#255#247#196'L'#255#247#196'L'#255#247#196'L'#255#247#196'K'#255#247 - +#196'K'#255#246#196'K'#255#245#195'J'#255#243#193'J'#255#242#190'J'#255#234 - +#180'H'#255#221#165'E'#255#202#142'@'#255#173'o5'#255'oC$'#252'T?3'#225'CCC' - +#193'AAAy@@@'#16#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'+++'#6'DDD@K@<'#198'g<"'#250#154 - +'a2'#254#200#141'B'#255#222#168'J'#255#234#183'N'#255#239#189'P'#255#242#192 - +'P'#255#242#193'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193 - +'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193 - ,'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#242#193 - +'P'#255#242#193'P'#255#241#191'P'#255#238#187'N'#255#229#176'L'#255#214#158 - +'G'#255#183'y;'#255'yJ)'#252'[=,'#236'CCB'#195'EEEoFFF'#11#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'UUU'#3 - +'CCC.J?;'#190'g=#'#252#167'k7'#255#205#147'H'#255#226#173'P'#255#235#186'T' - +#255#238#189'T'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U' - +#255#239#190'U'#255#239#190'U'#255#191#152'D'#255'A4'#23#255'>1'#22#255'D6' - +#24#255'H9'#26#255'RA'#29#255#146's4'#255#228#182'Q'#255#239#190'U'#255#239 - +#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#238#190'U'#255#237 - +#187'T'#255#232#182'S'#255#217#162'M'#255#191#129'B'#255#132'R-'#253'[9('#240 - +'DDD'#191'CCCW@@@'#8#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#1'>>>'#29'F@='#169'd9#'#250#165'i8'#255#208#151'L'#255 - +#226#174'U'#255#233#184'Y'#255#235#186'Y'#255#235#187'Y'#255#235#187'Y'#255 - +#235#187'Y'#255#235#187'Y'#255#235#187'Y'#255#235#187'Y'#255'<0'#23#255#1#1#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#0#0#0#255#6 - +#5#2#255'*!'#16#255'w^-'#255#227#181'W'#255#235#187'Y'#255#235#187'Y'#255#235 - +#186'Y'#255#234#186'Y'#255#231#181'X'#255#218#164'Q'#255#194#133'E'#255'{J*' - +#252'U=/'#230'CCC'#186'EEE?@@@'#4#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'333'#10'DAAw_9%'#244#150'^4'#254#204#148'N'#255#225#175 - +'Y'#255#230#181'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183 - +'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255'hR*'#255#1#1#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#1#1#0#255#1#1#0#255'*!'#17#255#164#130'B'#255#231#183'\' - +#255#231#183'\'#255#231#182']'#255#228#179'['#255#217#165'V'#255#185'|C'#255 - +'nA'''#252'N>5'#219'CCC'#163'@@@'#20#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#128#128#128#2'@@@,W8*'#227#132'P/'#253#196#139'M'#255#220 - +#170'['#255#226#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227 - +#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#4#3#2 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0 - +#255#7#6#3#255#178#141'J'#255#227#179'_'#255#227#179'_'#255#225#176'^'#255 - +#211#158'U'#255#174'q?'#255'c9"'#252'GA>'#203'BBB]III'#7#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0'FFF'#11'H>:'#150'e:#'#252#186'~H'#255#214#164'\' - +#255#222#174'a'#255#223#175'b'#255#223#175'b'#255#223#175'b'#255#223#175'b' - +#255#223#175'b'#255#223#175'b'#255#223#175'b'#255#223#175'b'#255#188#148'S' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#1#1#1#255#154'yC'#255#223#175'b'#255#223#175'a'#255 - +#220#171'`'#255#204#150'U'#255#145'Y5'#254'Y8('#238'CCC'#175'FFF'#29#0#0#0#1 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'AAA3Z7'''#236#148'\6'#255#207#154'Z' - +#255#218#170'b'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd' - +#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd' - +#255#211#165'`'#255#6#5#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1#255#219#171'd'#255#219 - +#171'd'#255#219#171'd'#255#215#166'`'#255#189#129'M'#255'h=$'#252'H>;'#207'E' - +'EEhIII'#7#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'III'#7'K<5'#137'h;$'#252#188#130 - +'O'#255#213#164'b'#255#215#167'd'#255#215#167'd'#255#215#167'd'#255#215#167 - +'d'#255#215#167'd'#255#215#167'd'#255#215#167'd'#255#215#167'd'#255#215#167 - +'d'#255#215#167'd'#255#215#167'd'#255#168#130'N'#255#1#1#1#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#200#155']'#255#215#167'd'#255#215#167'd'#255#215#166'd'#255#205#153']' - +#255#153'`:'#255'[6$'#243'CCC'#164';;;'#13#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'7' - +'77'#14'Z5%'#229#150'[8'#255#203#150'^'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211 - +#162'e'#255#142'mD'#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#145'pF'#255#211#162'e'#255#211#162 - +'e'#255#211#162'e'#255#210#159'd'#255#189#131'R'#255'f9#'#252'I@;'#202'===.' - +#128#128#128#2#0#0#0#0#0#0#0#0#128#128#128#2'D??4]3'#30#252#181'yM'#255#206 - +#155'd'#255#207#157'f'#255#207#157'f'#255#207#157'f'#255#207#157'f'#255#205 - +#155'f'#255'S?('#255#1#1#1#255#1#0#0#255#3#2#1#255#15#11#7#255#169#128'S'#255 - ,#207#157'f'#255#207#157'f'#255#207#157'f'#255#16#12#8#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#186#141'\' - +#255#207#157'f'#255#207#157'f'#255#207#157'f'#255#207#157'e'#255#201#148'`' - +#255#135'O0'#254'R9-'#226'BBBeIII'#7#0#0#0#0#0#0#0#0'UUU'#6'O8/'#141'o>''' - +#251#193#139'['#255#203#151'e'#255#203#152'e'#255#203#152'e'#255#203#152'e' - +#255#203#152'e'#255#23#17#11#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#1#1#1#255#153'rL'#255#203#152'e'#255#203#152'e'#255',!'#22#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255' '#24#16 - +#255#203#152'e'#255#203#152'e'#255#203#152'e'#255#203#152'e'#255#203#152'e' - +#255#202#150'd'#255#165'jC'#255'\3!'#247'DDD'#151'MMM'#10#0#0#0#0#0#0#0#0'@@' - +'@'#8'Z6%'#206#142'T5'#255#195#142'a'#255#198#145'c'#255#198#145'c'#255#198 - +#145'c'#255#198#145'c'#255'W@,'#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255'%'#27#19#255#198#145'c'#255#198#145'c'#255'U>+' - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#1#1#1#255#27#20#13#255'vW;' - +#255#198#145'c'#255#198#145'c'#255#198#145'c'#255#198#145'c'#255#198#145'c' - +#255#198#145'c'#255#198#145'c'#255#184'}S'#255'`4 '#252'FA>'#183'@@@'#12#0#0 - +#0#0#0#0#0#0'999'#9']2'#30#243#166'gD'#255#192#138'`'#255#192#139'a'#255#192 - +#139'a'#255#192#139'a'#255#190#137'a'#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#6#4#255#192#139'a'#255#192#139 - +'a'#255#129']B'#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'Q;)'#255#192#139'a' - +#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#192#139'a' - +#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#188#132'[' - +#255'u@'''#252'M;3'#212'999'#18#0#0#0#0#0#0#0#0'FFF'#11'^1'#29#250#174'oK' - +#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255'vS:'#255#1#1 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255 - +'S:)'#255#186#131'\'#255#186#131'\'#255#184#129'\'#255'('#28#20#255#1#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255'Q9('#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186 - +#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186 - +#131'\'#255#186#131'\'#255#186#130'['#255#131'I-'#255'Q9-'#221'FFF!'#0#0#0#1 - +#0#0#0#0'M33'#20'_2'#30#251#173'pN'#255#180'{X'#255#180'{X'#255#180'{X'#255 - +#180'{X'#255'-'#30#22#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#2#1#1#255'dE1'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X'#255 - +#180'{X'#255'O6&'#255#2#1#1#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255'G0#'#255#180'{X'#255#180'{X'#255#178'{X'#255'hH3'#255'U:)'#255 - +'mK5'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X' - +#255#180'{X'#255#139'P3'#255'U7)'#231'BBB2UUU'#3#0#0#0#0'T1&,c5 '#249#174'rQ' - +#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#8#5#4#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#1#0#0#255#27#18#13#255#164'nQ'#255#178'wW'#255#178 - +'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW' - +#255#142'_F'#255'H0#'#255#20#13#10#255#25#16#12#255'9'''#28#255'lI5'#255#178 - +'wW'#255#178'wW'#255'kG4'#255#1#1#1#255#1#1#0#255#1#0#0#255#1#0#0#255#3#2#1 - +#255'zQ<'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#149 - +'W9'#255'Z5%'#238'DDD-'#128#128#128#2#0#0#0#0'Y3 Bj8#'#248#173'qS'#255#175't' - +'W'#255#175'tW'#255#175'tW'#255#175'tW'#255#1#0#0#255#1#1#1#255#0#0#0#255#0#0 - +#0#255#5#3#3#255'cB2'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175 - +'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW' - +#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255 - +#173'rU'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#1 - +#1#255#152'eL'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#155'[>' - +#255'\4"'#244'@@@'#28#0#0#0#1#0#0#0#0'X0!3g7"'#246#172'oR'#255#174'rV'#255 - +#174'rV'#255#174'rV'#255#166'lR'#255#7#5#3#255#131'VA'#255#155'fM'#255'oI7' - +#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255 - +#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174 - +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV' - +#255#153'dL'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#0#0#0#255'<'''#29#255#174'rV'#255#174'rV'#255#174'rV'#255#173'qU'#255#151'Y' - +'='#255']6%'#239'333'#15#0#0#0#0#0#0#0#0'O1'''#25'b3'#31#247#168'jN'#255#172 - +'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU' - +#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#136'XD'#255 - ,'U7*'#255'^=/'#255'kE5'#255#170'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255 - +#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172 - +'oU'#255#172'oU'#255#5#3#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255'!'#21#16#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oT'#255 - +#143'R7'#255'Y6('#225'@@@'#12#0#0#0#0#0#0#0#0'333'#5'_2'#31#248#167'hL'#255 - +#172'qW'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172 - +'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255':&'#30#255#1#0#0#255 - +#1#1#0#255#1#1#1#255#1#1#0#255#4#2#2#255#133'WD'#255#172'qX'#255#172'qX'#255 - +#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172 - +'qX'#255#172'qX'#255'E.$'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#30#20#15#255#172'qX'#255#172'qX'#255#172'qX'#255#172'pV'#255 - +#134'K2'#255'V8)'#199'999'#9#0#0#0#0#0#0#0#0#0#0#0#1'_3'#30#239#164'fJ'#255 - +#175'w]'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'w^'#255#175 - +'w^'#255#175'w^'#255#175'w^'#255#175'w^'#255'hF7'#255#1#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#5#4#255#175'w^'#255#175'w^'#255'{TB' - +#255'X;/'#255']?2'#255#127'VD'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'w' - +'^'#255#165'qY'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1 - +#255'fF7'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'v\'#255'{D-'#253'S5(' - +#154'333'#5#0#0#0#0#0#0#0#0#0#0#0#0'a3'#30#200#149'Z?'#255#179'|c'#255#179'}' - +'e'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e' - +#255#179'}e'#255#179'}e'#255#19#13#11#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#2#1#1#255#179'}e'#255'E0'''#255#1#0#0#255#1#1#0#255 - +#1#1#0#255#0#0#0#255'R:/'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e'#255 - +'.!'#26#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255#177'}e'#255#179 - +'}e'#255#179'}e'#255#179'}e'#255#175'v\'#255'g8$'#251'W7*O'#0#0#0#1#0#0#0#0#0 - +#0#0#0#0#0#0#0'[0'#29'lyD-'#249#181#128'i'#255#183#131'l'#255#183#131'l'#255 - +#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255 - +#183#131'l'#255#183#131'l'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255'"'#25#20#255#183#131'l'#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255'B/'''#255#183#131'l'#255#183#131'l'#255 - +#183#131'l'#255#169'yd'#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255'#'#25#21 - +#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#167'lQ'#255 - +'^3'#31#248'@@@'#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Y1'#30#26'b5 '#244#178'z' - +'c'#255#187#138't'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#187#138 - +'u'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#2#2#1#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#170'~j'#255#177 - +#130'o'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#3 - +#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255'jNB'#255#11 - +#8#7#255#0#0#0#255#0#0#0#255#152'p`'#255#187#138'u'#255#187#138'u'#255#187 - +#138'u'#255#186#136'r'#255#144'W?'#255']6#'#193'333'#5#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0'`4'#31#217#160'gN'#255#190#143'{'#255#191#145'}'#255#191 - +#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#191 - +#145'}'#255#191#145'}'#255#19#14#12#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255'7*$'#255#191#145'}'#255#164'|k'#255#1#1#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1#255#191#145'}'#255#191#145'}'#255 - +#191#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#0#0#0#255#30#23 - +#20#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#187#138 - +'t'#255'p>('#249'Y2#U'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27 - +'huB+'#244#190#142'z'#255#195#152#132#255#195#152#132#255#195#152#132#255#195 - +#152#132#255#195#152#132#255#195#152#132#255#195#152#132#255#195#152#132#255 - +'A3,'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#183#142'|'#255 - +#195#152#132#255#138'k]'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#9#7#6#255#195#152#132#255#195#152#132#255#195#152#132#255#195 - +#152#132#255#195#152#132#255#195#152#132#255#1#1#1#255#160'}m'#255#195#152 - +#132#255#195#152#132#255#195#152#132#255#194#150#131#255#167'pW'#255'`4 '#240 - +'M33'#10#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#4'`3'#30#229 - +#164'nU'#255#197#156#137#255#199#159#141#255#199#159#141#255#199#159#141#255 - +#199#159#141#255#199#159#141#255#199#159#141#255#199#159#141#255'x`U'#255#1#1 - +#1#255#0#0#0#255#0#0#0#255#0#0#0#255#18#14#13#255#199#159#141#255#199#159#141 - +#255' '#26#23#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255 - +#139'oc'#255#199#159#141#255#199#159#141#255#199#159#141#255#199#159#141#255 - +#199#159#141#255#199#159#141#255'^KC'#255#199#159#141#255#199#159#141#255#199 - +#159#141#255#199#159#141#255#192#147#127#255'rB-'#249'\1 k'#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'\.'#28'Sn>('#243#194#149#131 - ,#255#202#165#148#255#203#165#149#255#203#165#149#255#203#165#149#255#203#165 - +#149#255#203#165#149#255#203#165#149#255#169#138'|'#255#0#0#0#255#1#1#1#255 - +#16#13#11#255#23#19#17#255#171#139'~'#255#203#165#149#255#203#165#149#255#3#3 - +#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'*"'#31#255#203#165 - +#149#255#203#165#149#255#203#165#149#255#203#165#149#255#203#165#149#255#203 - +#165#149#255#203#165#149#255#203#165#149#255#203#165#149#255#203#165#149#255 - +#203#165#149#255#201#162#145#255#163'mU'#255'_3'#31#227'U'#0#0#3#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'a3'#30#213#153 - +'eM'#254#204#167#151#255#207#172#158#255#207#172#158#255#207#172#158#255#207 - +#172#158#255#207#172#158#255#207#172#158#255#205#170#156#255#0#0#0#255'<1.' - +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172 - +#158#255#20#16#15#255#1#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'?40'#255#207 - +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255 - +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158 - +#255#207#172#158#255#207#171#156#255#192#147#127#255'k<'''#244'Z.'#29'L'#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 - +'^/'#27'&b5!'#240#174'{f'#255#209#176#162#255#212#180#167#255#212#180#167#255 - +#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167#255#6#5#5#255 - +#179#151#140#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167 - +#255#212#180#167#255#212#180#167#255'gXR'#255#0#0#0#255#0#0#0#255'gXR'#255 - +#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167 - +#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180 - +#167#255#212#180#167#255#211#179#166#255#202#162#146#255#127'M7'#248'`2'#31 - +#169#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'[/'#26'Fg:#'#242#190#145#127#255#214#184#172#255#216 - +#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255 - +'k]X'#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216 - +#187#176#255#216#187#176#255#216#187#176#255'E<8'#255#0#0#0#255'>63'#255#216 - +#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255 - +#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176 - +#255#216#187#176#255#216#187#175#255#210#176#163#255#147'_H'#252'`4'#31#210 - +'U++'#6#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'#29'trB-'#242#198#157#140#255#218#191 - +#180#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221 - +#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255 - +#221#195#185#255#221#195#185#255#221#195#185#255',''%'#255'920'#255#221#195 - +#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221 - +#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255 - +#221#195#185#255#220#194#184#255#213#183#170#255#162'oW'#255'b5 '#232'].'#23 - +#22#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'_1'#30#138'l>)'#242#187#143'|' - +#255#221#196#186#255#225#202#193#255#225#203#194#255#225#203#194#255#225#203 - +#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225 - +#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255 - +#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194 - +#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203 - +#194#255#224#201#192#255#212#180#168#255#149'aK'#252'a5!'#230']2'#25')'#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#0#0#0#0#0'[/'#28'\d9$'#241#172 - +'|h'#255#222#197#187#255#228#206#200#255#230#209#203#255#230#209#203#255#230 - +#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255 - +#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203 - +#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209 - +#203#255#230#209#203#255#230#209#203#255#229#209#202#255#226#204#197#255#208 - +#173#159#255#131'R;'#245'a3'#31#207'Y3'#26#20#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#0#0#0#0#0#0#0#0#0#0#0#0#0'].'#28'7a5!'#236#137'WB'#248#201 - +#163#148#255#229#210#202#255#233#215#210#255#234#217#212#255#234#217#212#255 - +#234#217#212#255#234#217#212#255#234#217#212#255#234#217#212#255#234#217#212 - +#255#234#217#212#255#234#217#212#255#234#217#212#255#234#217#212#255#234#217 - +#212#255#234#217#212#255#234#217#212#255#234#217#212#255#234#216#211#255#231 - +#212#206#255#221#195#185#255#174#128'm'#255'm>*'#242'`1'#29#163'f33'#5#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - ,#0#0#0#0#0'b'''#20#13'`2'#29#140'd8$'#241#151'hR'#251#211#179#167#255#233#215 - +#210#255#236#220#215#255#237#222#219#255#238#225#221#255#238#225#221#255#238 - +#225#221#255#238#225#221#255#238#225#221#255#238#225#221#255#238#225#221#255 - +#238#225#221#255#238#225#221#255#238#223#220#255#236#221#217#255#234#219#213 - +#255#227#205#198#255#188#146#128#255'wH2'#242'b5 '#219'].'#27'B'#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#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'X1'#29#26'a3'#30#168'f:$'#242#134'T?' - +#246#179#136'v'#255#214#183#172#255#235#218#214#255#238#225#221#255#239#226 - +#223#255#240#227#224#255#240#227#225#255#240#227#225#255#239#226#223#255#239 - +#225#222#255#238#224#220#255#226#204#196#255#199#161#145#255#158'o['#254'rD-' - +#239'b4"'#232'^2'#30'\'#0#0#0#1#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#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'`+ '#24']/'#30'fd6#'#197'c8#'#243'vE0'#240#140'ZF' - +#247#156'mY'#255#171#127'm'#255#184#143#127#255#178#136'v'#255#164'wd'#255 - +#148'dP'#252#130'Q;'#243'l<('#239'b6"'#234'b5!'#151'Z-'#29'>UU'#0#3#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#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#0#0#0#0#0#0'].'#23#11'Z/'#29'G^4 fa4!'#130'd6!'#166'd7#'#194 - +'d7"'#182'c6"'#150'_3'#31's\0'#29'YY/'#30'+'#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#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#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#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#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#224#3#255#255#255 - +#255#255#254#0#0#127#255#255#255#255#248#0#0#31#255#255#255#255#224#0#0#7#255 - +#255#255#255#192#0#0#3#255#255#255#255#128#0#0#1#255#255#255#255#0#0#0#0#127 - +#255#255#254#0#0#0#0#127#255#255#252#0#0#0#0'?'#255#255#248#0#0#0#0#31#255 - +#255#240#0#0#0#0#15#255#255#240#0#0#0#0#15#255#255#224#0#0#0#0#7#255#255#224 - +#0#0#0#0#3#255#255#192#0#0#0#0#3#255#255#192#0#0#0#0#3#255#255#192#0#0#0#0#1 - +#255#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255#255 - +#128#0#0#0#0#1#255#255#128#0#0#0#0#0#255#255#128#0#0#0#0#0#255#255#128#0#0#0 - +#0#0#255#255#128#0#0#0#0#0#255#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255 - +#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255#255#192#0#0#0#0#1#255#255#192#0 - +#0#0#0#3#255#255#192#0#0#0#0#3#255#255#224#0#0#0#0#7#255#255#224#0#0#0#0#7 - +#255#255#224#0#0#0#0#15#255#255#240#0#0#0#0#15#255#255#248#0#0#0#0#31#255#255 - +#248#0#0#0#0'?'#255#255#252#0#0#0#0'?'#255#255#254#0#0#0#0#127#255#255#255#0 - +#0#0#0#255#255#255#255#128#0#0#1#255#255#255#255#192#0#0#3#255#255#255#255 - +#224#0#0#15#255#255#255#255#248#0#0#31#255#255#255#255#254#0#0#127#255#255 - +#255#255#255#192#7#255#255#255#255#255#255#255#255#255#255#255#255'('#0#0#0 - +' '#0#0#0'@'#0#0#0#1#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#0#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'CCC'#19'FFF'#22'UUU'#3#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#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'@@@'#12'EAAGDDB'#133'DDC'#181'HC?'#205'LA;'#213 - +'JB='#212'FC@'#204'EED'#185'DDC'#145'DDDSFFF'#22#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#0#0#0#0#0#0#0#0#0'III'#14'EEBoLA;'#208'eE-'#235'xK(' - +#246#131'R)'#250#139'W*'#251#149'_,'#252#145'\+'#252#136'V*'#250#128'Q('#249 - +'rI)'#244'\D2'#227'FB?'#207'CCC'#134'DDD'#30#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'EEENMA9'#206'oF)'#245#147']-'#252#187'}4'#255#211#150'9'#255#224 - +#167';'#255#230#174'='#255#234#179'>'#255#233#178'>'#255#228#171'='#255#221 - +#163'<'#255#205#143'8'#255#175'r2'#255#131'R*'#250'eC,'#238'FB?'#205'CCCoUUU' - +#3#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'@@@'#4'GEA|dB+'#239#142'[.'#252#198#137'<'#255#227#172'C'#255 - +#236#183'E'#255#242#190'F'#255#246#195'G'#255#248#198'G'#255#249#199'H'#255 - +#249#198'H'#255#247#196'G'#255#245#193'G'#255#240#188'F'#255#234#180'D'#255 - +#220#163'A'#255#183'y8'#255'}O*'#250'WA4'#225'CCC'#152'<<<'#17#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#1'G@='#148 - +'lD*'#245#175'u8'#254#221#166'I'#255#234#182'M'#255#242#193'P'#255#243#194'O' - +#255#244#195'O'#255#244#195'P'#255#244#195'P'#255#244#195'P'#255#244#195'P' - +#255#244#195'P'#255#244#195'P'#255#243#194'O'#255#243#194'O'#255#240#190'O' - +#255#230#179'L'#255#212#155'F'#255#148'^1'#252'`A.'#234'CCC'#171'@@@'#12#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'FA>vmB)'#247#189 - +#130'A'#255#224#172'P'#255#236#187'U'#255#238#189'W'#255#238#190'V'#255#238 - +#190'V'#255#238#190'V'#255'fQ%'#255#17#14#6#255#17#13#6#255#16#13#6#255',#' - +#16#255#155'|8'#255#238#190'V'#255#238#190'V'#255#238#189'V'#255#238#189'W' - +#255#233#184'U'#255#217#163'M'#255#164'l8'#254'_>+'#238'DDD'#147#128#128#128 - +#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'FDD=e?*'#243#183'}B'#255 - +#223#171'W'#255#232#183'['#255#232#183'\'#255#232#183'\'#255#232#183'\'#255 - +#232#183'\'#255'>1'#25#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 - +#1#1#1#255#5#4#2#255#22#17#9#255'pX,'#255#218#171'V'#255#232#183'\'#255#230 - +#182'['#255#217#164'T'#255#152'a7'#252'V=1'#228'DDDb'#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#128#128#128#2'Z<-'#215#163'k='#254#217#166'['#255#226#178'`' - +#255#226#179'a'#255#226#179'a'#255#226#179'a'#255#226#179'a'#255#226#179'a' - +#255#5#4#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#3#3#1#255',#'#19#255#226#179'a'#255#225#177'_' - +#255#208#154'T'#255#129'O1'#251'H?;'#205'@@@'#20#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0'J@<[vF,'#249#206#153'Y'#255#220#172'b'#255#220#172'c'#255#220#172'c'#255 - +#220#172'c'#255#220#172'c'#255#220#172'c'#255#205#160']'#255#4#3#2#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#1#0#0#255'.$'#21#255#220#172'c'#255#218#170'a'#255#190#132 - +'N'#255'c=)'#242'CCCz'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'\9('#218#177'vG'#255 - +#213#164'c'#255#214#166'e'#255#214#166'e'#255#214#166'e'#255#214#166'e'#255 - +#214#166'e'#255#214#166'e'#255#214#166'e'#255'v\8'#255#2#2#1#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#11#9#5#255#214#166'e'#255#214#166'e'#255#209#159'a'#255#139'Y' - +'6'#252'K>7'#206'333'#5#0#0#0#0#0#0#0#0'?;9'#19'mA+'#247#201#148'^'#255#209 - +#159'e'#255#209#159'e'#255#209#159'e'#255#146'oF'#255#18#14#9#255#21#16#10 - +#255'O<&'#255#209#159'e'#255#209#159'e'#255'$'#27#17#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#11#8#5#255#209#159'e'#255#209#159'e'#255#208#158'e'#255#185#128'Q'#255 - +'^9)'#240'BBB6'#0#0#0#0#0#0#0#0'P8-q'#144'Z:'#252#201#150'd'#255#202#151'd' - +#255#202#151'd'#255'uW:'#255#2#1#1#255#0#0#0#255#0#0#0#255#1#0#0#255'-!'#22 - +#255#202#151'd'#255'ZC-'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#5#4#3#255'gM3'#255#202#151'd' - +#255#202#151'd'#255#202#151'd'#255#197#145'`'#255'l@*'#248'CCBo'#0#0#0#0#0#0 - +#0#0'^7$'#194#171'pK'#255#194#140'a'#255#194#140'a'#255#194#140'a'#255#6#4#3 - +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#5#4#255#194#140'a'#255#139'eE' - +#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#13 - +#9#6#255'wV<'#255#192#138'a'#255#194#140'a'#255#194#140'a'#255#194#140'a'#255 - +#194#140'a'#255#193#140'a'#255#137'T7'#252'K=6'#158#0#0#0#0#0#0#0#0'a6#'#220 - +#177'uQ'#255#185#129'['#255#185#129'['#255#127'Y>'#255#1#1#0#255#0#0#0#255#0 - +#0#0#255#0#0#0#255#2#1#1#255'8'''#27#255#185#129'['#255#185#129'['#255'+'#30 - +#21#255#2#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#13#9#6#255#179'}Y' - +#255#185#129'['#255#185#129'['#255#185#129'['#255#185#129'['#255#185#129'[' - +#255#185#129'['#255#185#129'['#255#152'^>'#255'P:1'#190#0#0#0#0#0#0#0#0'c7#' - +#227#175'sS'#255#178'xW'#255#178'xW'#255','#30#21#255#0#0#0#255#0#0#0#255#0#0 - +#0#255#5#4#3#255'uO:'#255#178'xW'#255#178'xW'#255#178'xW'#255#178'xW'#255'xP' - +':'#255'('#26#19#255#10#7#5#255#10#7#5#255#28#19#13#255#168'rS'#255#163'nO' - +#255#25#17#12#255#6#4#3#255#17#11#8#255'bB/'#255#178'xW'#255#178'xW'#255#178 - +'xW'#255#158'aB'#255'V9,'#210#0#0#0#0#0#0#0#0'f7"'#227#173'sT'#255#175'tW' - +#255#175'tW'#255#15#10#7#255#13#8#6#255#5#4#3#255'+'#29#21#255#169'pU'#255 - +#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175 - +'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#17#11#8#255#0#0#0 - +#255#0#0#0#255#0#0#0#255#2#2#1#255#136'ZD'#255#175'tW'#255#175'tW'#255#161'd' - +'G'#255'[8('#211#0#0#0#0#0#0#0#0'e6"'#218#171'nR'#255#173'qV'#255#173'qV'#255 - +#136'YC'#255#173'qV'#255#173'qV'#255#173'qV'#255#173'qV'#255#173'qV'#255'sK9' - +#255'uM:'#255#159'gN'#255#173'qV'#255#173'qV'#255#173'qV'#255#173'qV'#255#173 - +'qV'#255#173'qV'#255#173'qV'#255'5"'#27#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0 - +#0#255'H/$'#255#173'qV'#255#173'qV'#255#153'^D'#255'Y8*'#188#0#0#0#0#0#0#0#0 - +'c5 '#203#170'kQ'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY' - ,#255#174'sY'#255#164'mU'#255#11#7#6#255#1#1#1#255#1#1#1#255#5#3#2#255#127'TA' - +#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255 - +#128'UA'#255#2#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255'J1&'#255#174'sY'#255#174 - +'sY'#255#147'X?'#255'S8,'#140#0#0#0#0#0#0#0#0'd4'#30#153#162'gM'#255#178'{c' - +#255#178'{c'#255#178'{c'#255#178'{c'#255#178'{c'#255#178'{c'#255'A-$'#255#0#0 - +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#20#14#11#255'xSB'#255#6#4#3#255#5#4#3 - +#255#18#12#10#255#170'u_'#255#178'{c'#255#178'{c'#255#9#6#5#255#0#0#0#255#0#0 - +#0#255#3#2#2#255#166's]'#255#178'{c'#255#178'{c'#255#131'P8'#252'S3$>'#0#0#0 - +#0#0#0#0#0'[/'#27'3'#137'T='#247#184#134'o'#255#184#134'o'#255#184#134'o'#255 - +#184#134'o'#255#184#134'o'#255#184#134'o'#255#14#10#9#255#0#0#0#255#0#0#0#255 - +#0#0#0#255#1#1#1#255'\C7'#255#14#10#8#255#0#0#0#255#0#0#0#255#0#0#0#255#14#10 - +#8#255#184#134'o'#255#184#134'o'#255'xWI'#255#2#1#1#255#0#0#0#255#18#14#11 - +#255#184#134'o'#255#184#134'o'#255#183#131'l'#255'h:&'#240#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0'n<%'#218#189#140'x'#255#190#143'z'#255#190#143'z'#255#190#143 - +'z'#255#190#143'z'#255#190#143'z'#255',!'#28#255#0#0#0#255#0#0#0#255#0#0#0 - +#255#9#7#6#255#190#143'z'#255#9#7#6#255#0#0#0#255#0#0#0#255#0#0#0#255#5#4#3 - +#255#190#143'z'#255#190#143'z'#255#190#143'z'#255#159'xe'#255#0#0#0#255#140 - +'jZ'#255#190#143'z'#255#190#143'z'#255#175'yc'#255'b6"'#193#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0'd4'#30#151#167's\'#254#196#154#135#255#196#154#135#255#196#154 - +#135#255#196#154#135#255#196#154#135#255'qYN'#255#0#0#0#255#0#0#0#255#1#1#1 - +#255'v]R'#255#194#152#133#255#5#4#4#255#0#0#0#255#0#0#0#255#0#0#0#255#10#8#7 - +#255#196#154#135#255#196#154#135#255#196#154#135#255#196#154#135#255'"'#27#24 - +#255#196#154#135#255#196#154#135#255#196#154#135#255#131'R<'#248'^1'#28'1'#0 - +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#14'o>('#224#198#157#140#255#202#163#146 - +#255#202#163#146#255#202#163#146#255#202#163#146#255#170#138'{'#255#0#0#0#255 - +#8#6#6#255#26#21#19#255#202#163#146#255#143'th'#255#1#1#1#255#0#0#0#255#0#0#0 - +#255#2#2#2#255#143'sg'#255#202#163#146#255#202#163#146#255#202#163#146#255 - +#202#163#146#255#191#155#138#255#202#163#146#255#202#163#146#255#183#135'r' - +#255'd5 '#193#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'd3'#30'{'#156 - +'jS'#248#209#174#160#255#209#174#160#255#209#174#160#255#209#174#160#255#209 - +#174#160#255#2#2#2#255#205#172#158#255#209#174#160#255#209#174#160#255#169 - +#140#129#255#11#9#9#255#1#1#0#255#4#3#3#255#132'oe'#255#209#174#160#255#209 - +#174#160#255#209#174#160#255#209#174#160#255#209#174#160#255#209#174#160#255 - +#209#174#160#255#205#167#152#255'yG3'#235'[/'#27'"'#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'd4'#30#181#179#134'r'#254#215#185#173#255#215 - +#185#173#255#215#185#173#255#215#185#173#255'm^X'#255#215#185#173#255#215#185 - +#173#255#215#185#173#255#215#185#173#255#133'sk'#255#0#0#0#255#156#134'}'#255 - +#215#185#173#255#215#185#173#255#215#185#173#255#215#185#173#255#215#185#173 - +#255#215#185#173#255#215#185#173#255#214#183#172#255#143'^I'#243'b3'#29'`'#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'[/'#27#8'f6 ' - +#205#189#148#131#254#222#197#187#255#222#197#187#255#222#197#187#255#222#197 - +#187#255#222#197#187#255#222#197#187#255#222#197#187#255#222#197#187#255#127 - +'qk'#255#134'wq'#255#222#197#187#255#222#197#187#255#222#197#187#255#222#197 - +#187#255#222#197#187#255#222#197#187#255#222#197#187#255#220#193#183#255#159 - +'o['#247'd3'#30#147#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'[/'#27#15'c3'#30#193#176#132'q'#248#228#206#199#255 - +#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201 - +#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208 - +#201#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201#255#221 - +#196#186#255#141']I'#237'c3'#29#129#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'[/'#27#2'c3'#29#150 - +#135'XD'#231#208#176#164#255#235#219#215#255#235#219#215#255#235#219#215#255 - +#235#219#215#255#235#219#215#255#235#219#215#255#235#219#215#255#235#219#215 - +#255#235#219#215#255#235#219#215#255#235#219#215#255#232#214#209#255#189#149 - +#133#253'qA+'#220'a2'#29'O'#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'[/'#27 - +'"e4'#30#185#144'cO'#235#195#158#144#254#230#209#203#255#242#231#229#255#242 - +#231#229#255#242#231#229#255#242#231#229#255#242#231#229#255#241#230#226#255 - +#220#193#184#255#180#141'|'#251'zK6'#226'd3'#30#142'[/'#27#10#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#0#0#0#0#0#0#0#0#0'[/'#27#28'b3'#29'{g5'#30 - +#198'xH2'#218#137']J'#229#156'r`'#236#151'mZ'#234#132'VB'#227'q?)'#213'f4'#30 - +#182'_1'#28'W[/'#27#11#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#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'[/'#27#5'[/' - +#27#30'[/'#27#22'[/'#27#1#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#255#252'?'#255 - +#255#192#3#255#255#0#0#255#254#0#0'?'#248#0#0#31#240#0#0#15#240#0#0#7#224#0#0 - +#7#192#0#0#3#192#0#0#3#192#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128 - +#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128#0#0#3#192#0#0#3#192#0#0#3 - +#192#0#0#7#224#0#0#7#240#0#0#15#240#0#0#31#248#0#0'?'#252#0#0#127#255#0#0#255 - +#255#192#3#255#255#252'?'#255'('#0#0#0#16#0#0#0' '#0#0#0#1#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 - +';;;'#13'ICB7M=4zL>6xFBA;@@@'#16#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'III'#7'W;,'#171'nC('#245#145'`+'#250#181#127'2'#253#175 - +'z1'#253#139'\*'#250'h?&'#244'P=3'#159'@@@'#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0'K921d;'''#235#191#137'7'#254#249#198'E'#255#251#199'F'#255#251#200 - +'F'#255#251#200'F'#255#251#199'F'#255#246#194'E'#255#173'y3'#253'\9)'#229'E>' - +';2'#0#0#0#0#0#0#0#0#0#0#0#0'>2,'#7'nC'''#238#223#171'N'#255#239#191'U'#255 - +#240#192'U'#255#164#131':'#255'@3'#23#255'J;'#26#255'~e-'#255#196#157'E'#255 - +#239#191'U'#255#212#159'J'#255'a<('#231'MMM'#10#0#0#0#0#0#0#0#0'[7('#183#195 - +#145'N'#254#228#180'_'#255#228#180'_'#255#228#180'_'#255'40'#255#210#176#163#255 - +#148'|s'#255'RD?'#255#210#176#163#255#140'fW'#243'[/'#27#2#0#0#0#0'tI6'#209 - +#216#188#178#255#221#195#185#255#213#188#178#255'$'#31#30#255#131'sn'#255'sf' - +'`'#255#0#0#0#255'eYU'#255#221#195#185#255#221#195#185#255#204#180#170#255 - +#207#178#166#255'k>+'#182#0#0#0#0#0#0#0#0'[/'#27#31#156'xi'#240#232#213#207 - +#255#232#213#207#255#180#165#161#255#232#213#207#255#182#167#162#255'ICA'#255 - +#226#207#201#255#232#213#207#255#232#213#207#255#231#213#206#255#134'_O'#233 - +'[/'#27#12#0#0#0#0#0#0#0#0#0#0#0#0'd3'#30'e'#171#139'~'#240#239#226#224#255 - +#242#231#229#255#242#231#229#255#240#229#227#255#242#231#229#255#242#231#229 - +#255#242#231#229#255#235#221#216#255#153'uh'#236'a2'#29'?'#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#0#0#0#0'\0'#27'*'#131'\I'#215#212#191#183#252#239#229#226#255 - +#253#250#252#255#253#249#250#255#236#223#220#255#204#180#172#250'yM;'#196'[/' - +#27#23#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'[/'#27#3'[/' - +#27'>c3'#29#131'uI4'#190'oA-'#183'b2'#29'v[/'#27'4'#0#0#0#0#0#0#0#0#0#0#0#0#0 - +#0#0#0#0#0#0#0#248#31#172'A'#224#7#172'A'#192#3#172'A'#128#1#172'A'#128#1#172 - +'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#128#1 - +#172'A'#128#1#172'A'#192#3#172'A'#224#7#172'A'#240#31#172'A' -]); - diff --git a/demos_lazarus/Demo25/project1.manifest b/demos_lazarus/Demo25/project1.manifest deleted file mode 100644 index 515fede..0000000 --- a/demos_lazarus/Demo25/project1.manifest +++ /dev/null @@ -1,17 +0,0 @@ - - - - Your application description here. - - - - - - - - - - - - - \ No newline at end of file diff --git a/demos_lazarus/Demo25/project1.rc b/demos_lazarus/Demo25/project1.rc deleted file mode 100644 index cd8e7b0..0000000 --- a/demos_lazarus/Demo25/project1.rc +++ /dev/null @@ -1,7 +0,0 @@ -#define RT_MANIFEST 24 -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2 -#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3 - -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "project1.manifest" -MAINICON ICON "project1.ico" diff --git a/demos_lazarus/Demo25/project1.res b/demos_lazarus/Demo25/project1.res deleted file mode 100644 index 708df3c..0000000 Binary files a/demos_lazarus/Demo25/project1.res and /dev/null differ diff --git a/demos_lazarus/Demo25/unit1.lfm b/demos_lazarus/Demo25/unit1.lfm deleted file mode 100644 index f71828c..0000000 --- a/demos_lazarus/Demo25/unit1.lfm +++ /dev/null @@ -1,147 +0,0 @@ -object Form1: TForm1 - Left = 372 - Height = 522 - Top = 100 - Width = 795 - Caption = 'Form1' - ClientHeight = 522 - ClientWidth = 795 - OnCreate = FormCreate - LCLVersion = '0.9.28.2' - object Panel1: TPanel - Left = 0 - Height = 522 - Top = 0 - Width = 795 - Align = alClient - ClientHeight = 522 - ClientWidth = 795 - TabOrder = 0 - object Memo1: TMemo - Left = 1 - Height = 231 - Top = 1 - Width = 793 - Align = alTop - TabOrder = 0 - end - object PairSplitter1: TPairSplitter - Left = 1 - Height = 8 - Top = 232 - Width = 793 - Align = alTop - Position = 45 - object PairSplitterSide1: TPairSplitterSide - Cursor = crArrow - Left = 0 - Height = 8 - Top = 0 - Width = 45 - end - object PairSplitterSide2: TPairSplitterSide - Cursor = crArrow - Left = 50 - Height = 8 - Top = 0 - Width = 743 - end - end - object Memo2: TMemo - Left = 1 - Height = 168 - Top = 240 - Width = 793 - Align = alClient - Lines.Strings = ( - 'class XYZ(object):' - ' pass' - '' - 'class Foo:' - ' def __init__(Self, Value=0):' - ' Self.Value = Value' - ' def __del__(Self):' - ' print "delete", Self' - ' def __add__(self, other):' - ' return Foo(self.Value + other.Value)' - ' def Inc(Self, AValue = 1):' - ' Self.Value = Self.Value + AValue' - ' def GetSelf(Self):' - ' return Self' - ' def GetValue(Self):' - ' return Self.Value' - ' def SetABC(Self, A, B, C):' - ' Self.A = A' - ' Self.B = B' - ' Self.C = C' - ' def Add(Self, AFooInst):' - ' Self.Value = Self.Value + AFooInst.Value' - 'class Bar(Foo):' - ' def Inc(Self, AValue = 1):' - ' Self.Value = Self.Value - AValue' - 'def Add(a, b):' - ' return a + b' - 'def MakeList(a, b, c, d):' - ' return [a, b, c, d]' - '' - 'f = Foo()' - 'print "Created", f' - 'f.Inc()' - 'f.Inc(2)' - 'b = Bar()' - 'b.Inc()' - 'b.Inc(2)' - ) - TabOrder = 2 - end - object Panel2: TPanel - Left = 1 - Height = 113 - Top = 408 - Width = 793 - Align = alBottom - ClientHeight = 113 - ClientWidth = 793 - TabOrder = 3 - object Button1: TButton - Left = 15 - Height = 25 - Top = 8 - Width = 75 - Caption = 'Execute' - OnClick = Button1Click - TabOrder = 0 - end - object btnTestIntegers: TButton - Left = 119 - Height = 25 - Top = 8 - Width = 75 - Caption = 'Test Integers' - OnClick = btnTestIntegersClick - TabOrder = 1 - end - object cbTestIntegers: TCheckBox - Left = 122 - Height = 19 - Top = 41 - Width = 66 - Caption = 'Included' - TabOrder = 2 - end - end - end - object PythonEngine1: TPythonEngine - IO = PythonGUIInputOutput1 - left = 96 - top = 48 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - DelayWrites = True - UnicodeIO = False - RawOutput = False - Output = Memo1 - left = 338 - top = 48 - end -end diff --git a/demos_lazarus/Demo25/unit1.lrs b/demos_lazarus/Demo25/unit1.lrs deleted file mode 100644 index 619b7de..0000000 --- a/demos_lazarus/Demo25/unit1.lrs +++ /dev/null @@ -1,40 +0,0 @@ -LazarusResources.Add('TForm1','FORMDATA',[ - 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3't'#1#6'Height'#3#10#2#3'Top'#2'd'#5'Width' - +#3#27#3#7'Caption'#6#5'Form1'#12'ClientHeight'#3#10#2#11'ClientWidth'#3#27#3 - +#8'OnCreate'#7#10'FormCreate'#10'LCLVersion'#6#8'0.9.28.2'#0#6'TPanel'#6'Pan' - +'el1'#4'Left'#2#0#6'Height'#3#10#2#3'Top'#2#0#5'Width'#3#27#3#5'Align'#7#8'a' - +'lClient'#12'ClientHeight'#3#10#2#11'ClientWidth'#3#27#3#8'TabOrder'#2#0#0#5 - +'TMemo'#5'Memo1'#4'Left'#2#1#6'Height'#3#231#0#3'Top'#2#1#5'Width'#3#25#3#5 - +'Align'#7#5'alTop'#8'TabOrder'#2#0#0#0#13'TPairSplitter'#13'PairSplitter1'#4 - +'Left'#2#1#6'Height'#2#8#3'Top'#3#232#0#5'Width'#3#25#3#5'Align'#7#5'alTop'#8 - +'Position'#2'-'#0#17'TPairSplitterSide'#17'PairSplitterSide1'#6'Cursor'#7#7 - +'crArrow'#4'Left'#2#0#6'Height'#2#8#3'Top'#2#0#5'Width'#2'-'#0#0#17'TPairSpl' - +'itterSide'#17'PairSplitterSide2'#6'Cursor'#7#7'crArrow'#4'Left'#2'2'#6'Heig' - +'ht'#2#8#3'Top'#2#0#5'Width'#3#231#2#0#0#0#5'TMemo'#5'Memo2'#4'Left'#2#1#6'H' - +'eight'#3#168#0#3'Top'#3#240#0#5'Width'#3#25#3#5'Align'#7#8'alClient'#13'Lin' - +'es.Strings'#1#6#18'class XYZ(object):'#6#6' pass'#6#0#6#10'class Foo:'#6#30 - +' def __init__(Self, Value=0):'#6#22' Self.Value = Value'#6#20' def __d' - +'el__(Self):'#6#24' print "delete", Self'#6#27' def __add__(self, other)' - +':'#6'( return Foo(self.Value + other.Value)'#6#28' def Inc(Self, AValue' - +' = 1):'#6'$ Self.Value = Self.Value + AValue'#6#20' def GetSelf(Self):' - +#6#15' return Self'#6#21' def GetValue(Self):'#6#21' return Self.Valu' - +'e'#6#28' def SetABC(Self, A, B, C):'#6#14' Self.A = A'#6#14' Self.B ' - +'= B'#6#14' Self.C = C'#6#26' def Add(Self, AFooInst):'#6', Self.Valu' - +'e = Self.Value + AFooInst.Value'#6#15'class Bar(Foo):'#6#28' def Inc(Self,' - +' AValue = 1):'#6'$ Self.Value = Self.Value - AValue'#6#14'def Add(a, b):' - +#6#14' return a + b'#6#25'def MakeList(a, b, c, d):'#6#21' return [a, b, c' - +', d]'#6#0#6#9'f = Foo()'#6#18'print "Created", f'#6#7'f.Inc()'#6#8'f.Inc(2)' - +#6#9'b = Bar()'#6#7'b.Inc()'#6#8'b.Inc(2)'#0#8'TabOrder'#2#2#0#0#6'TPanel'#6 - +'Panel2'#4'Left'#2#1#6'Height'#2'q'#3'Top'#3#152#1#5'Width'#3#25#3#5'Align'#7 - +#8'alBottom'#12'ClientHeight'#2'q'#11'ClientWidth'#3#25#3#8'TabOrder'#2#3#0#7 - +'TButton'#7'Button1'#4'Left'#2#15#6'Height'#2#25#3'Top'#2#8#5'Width'#2'K'#7 - +'Caption'#6#7'Execute'#7'OnClick'#7#12'Button1Click'#8'TabOrder'#2#0#0#0#7'T' - +'Button'#15'btnTestIntegers'#4'Left'#2'w'#6'Height'#2#25#3'Top'#2#8#5'Width' - +#2'K'#7'Caption'#6#13'Test Integers'#7'OnClick'#7#20'btnTestIntegersClick'#8 - +'TabOrder'#2#1#0#0#9'TCheckBox'#14'cbTestIntegers'#4'Left'#2'z'#6'Height'#2 - +#19#3'Top'#2')'#5'Width'#2'B'#7'Caption'#6#8'Included'#8'TabOrder'#2#2#0#0#0 - +#0#13'TPythonEngine'#13'PythonEngine1'#2'IO'#7#21'PythonGUIInputOutput1'#4'l' - +'eft'#2'`'#3'top'#2'0'#0#0#21'TPythonGUIInputOutput'#21'PythonGUIInputOutput' - +'1'#11'DelayWrites'#9#9'UnicodeIO'#8#9'RawOutput'#8#6'Output'#7#5'Memo1'#4'l' - +'eft'#3'R'#1#3'top'#2'0'#0#0#0 -]); diff --git a/demos_lazarus/Demo25/unit1.pas b/demos_lazarus/Demo25/unit1.pas deleted file mode 100644 index b1f0380..0000000 --- a/demos_lazarus/Demo25/unit1.pas +++ /dev/null @@ -1,269 +0,0 @@ -unit Unit1; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, - StdCtrls, ExtCtrls, PairSplitter, PythonEngine, PythonGUIInputOutput; - -type - - { TForm1 } - - TForm1 = class(TForm) - Button1: TButton; - btnTestIntegers: TButton; - cbTestIntegers: TCheckBox; - Memo1: TMemo; - Memo2: TMemo; - PairSplitter1: TPairSplitter; - PairSplitterSide1: TPairSplitterSide; - PairSplitterSide2: TPairSplitterSide; - Panel1: TPanel; - Panel2: TPanel; - PythonEngine1: TPythonEngine; - PythonGUIInputOutput1: TPythonGUIInputOutput; - procedure btnTestIntegersClick(Sender: TObject); - procedure Button1Click(Sender: TObject); - procedure FormCreate(Sender: TObject); - private - { private declarations } - fVerbose : Boolean; - procedure Log( const AText : String ); - procedure RunSelectedTests; - public - { public declarations } - end; - -var - Form1: TForm1; - -implementation - -Uses - VarPyth; - -{ TForm1 } - - -procedure TForm1.Button1Click(Sender: TObject); -begin - PythonEngine1.ExecStrings( Memo2.Lines ); -end; - -procedure TForm1.btnTestIntegersClick(Sender: TObject); -var - a, b, c : Variant; - big : Int64; -begin - // initialize the operands - a := VarPythonCreate(2); - Assert(VarIsPython(a)); - Assert(VarIsPythonNumber(a)); - Assert(VarIsPythonInteger(a)); - Assert(Integer(a) = 2); - - b := VarPythonCreate(3); - Assert(VarIsPython(b)); - Assert(VarIsPythonNumber(b)); - Assert(VarIsPythonInteger(b)); - Assert(Integer(b) = 3); - - // arithmetic operations - //---------------------- - - // addition - c := a + b; - // check result of operation - Assert( Integer(c) = 5 ); - // check that operation did not change the content of operands. - Assert(Integer(a) = 2); - Assert(Integer(b) = 3); - // now with a litteral - c := a + b + 1; - Assert( Integer(c) = 6 ); - c := a + 1 + b; - Assert( Integer(c) = 6 ); - c := 1 + a + b; - Assert( Integer(c) = 6 ); - - // substraction - c := b - a; - Assert( Integer(c) = 1 ); - // now with a litteral - c := b - a - 1; - Assert( Integer(c) = 0 ); - c := b - 1 - a; - Assert( Integer(c) = 0 ); - c := 1 - b - a; - Assert( Integer(c) = -4 ); - - // multiplication - c := a * b; - Assert( Integer(c) = 6 ); - // now with a litteral - c := a * b * 2; - Assert( Integer(c) = 12 ); - c := a * 2 * b; - Assert( Integer(c) = 12 ); - c := 2 * a * b; - Assert( Integer(c) = 12 ); - - // integer division - c := b div a; - Assert( Integer(c) = 1 ); - - // division: in Python a division between 2 integers is the same as the integer division - c := b / a; - Assert( c = 1.5 ); - Assert( Integer(c) = 2 ); - - // modulus - c := b mod a; - Assert( Integer(c) = 1 ); - c := BuiltinModule.divmod(b, a); // this returns a tuple whose first item is the result of the division, - // and second item the modulo. - if VarIsPythonSequence(c) and (c.Length = 2) then - begin - Assert(Integer(c.GetItem(0)) = 1); // division - Assert(Integer(c.GetItem(1)) = 1); // modulo - end; - - // power - c := BuiltinModule.pow(a, b); - Assert(c = 8); - - // negation - c := -a; - Assert( Integer(c) = -2 ); - - // logical operations - //------------------ - - // inverse - c := not a; // in python it would be: c = ~2 - Assert( Integer(c) = -3 ); - - // shift left (<<) - c := a shl b; - Assert( Integer(c) = 16 ); - c := a shl 1; - Assert( Integer(c) = 4 ); - - // shift right (>>) - c := a shl b; - c := c shr b; - Assert( Integer(c) = Integer(a) ); - c := b shr 1; - Assert( Integer(c) = 1 ); - - // and - c := a and (a*5); - Assert( Integer(c) = Integer(a) ); - c := a and 6; - Assert( Integer(c) = Integer(a) ); - - // or - c := a or b; - Assert( Integer(c) = 3 ); - c := a or 3; - Assert( Integer(c) = 3 ); - - // xor - c := a xor b; - Assert( Integer(c) = 1 ); - c := a xor 3; - Assert( Integer(c) = 1 ); - - // comparisons - //------------ - - // equal - c := a = b; - Assert(c = False); - c := a = a; - Assert(c = True); - Assert( a = 2); - - // not equal - c := a <> b; - Assert(c = True); - Assert( not (c = b) ); - c := a <> a; - Assert(c = False); - Assert( a = 2); - - // greater than - c := a > b; Assert(c = False); - c := b > a; Assert(c = True); - Assert( a > 1); - - // greater or equal than - c := a >= b; Assert(c = False); - c := b >= a; Assert(c = True); - c := a >= a; Assert(c = True); - Assert( a >= 2 ); - - // less than - c := a < b; Assert(c = True); - c := b < a; Assert(c = False); - Assert( a < 6); - - // less or equal than - c := a <= b; Assert(c = True); - c := b <= a; Assert(c = False); - c := a <= a; Assert(c = True); - Assert( a <= 2); - - // parenthesis - c := a * ((a * b) div b); - Assert( c = a*2 ); - - // copy - c := a; - Assert( c = a); - Assert( VarIsSame(c, a) ); // checks if 2 variants share the same Python object. - - // test long long (Int64) - big := Int64(MaxInt)*4; - b := VarPythonCreate(big); - Assert( b = big ); - Assert( b <> big+1 ); - Assert( b > MaxInt ); - Assert( MaxInt < b ); - Assert( b+1 = big+1 ); - Assert( b*2 = big*2 ); - Assert( b div 2 = big div 2 ); - c := VarPythonCreate(True); - Assert(VarIsBool(c)); - Assert(VarIsTrue(c)); - c := VarPythonCreate(False); - Assert(VarIsBool(c)); - Assert(not VarIsTrue(c)); - - // Done! - Log('Integer test was Ok.');end; - -procedure TForm1.FormCreate(Sender: TObject); -begin - fVerbose := True; -end; - -procedure TForm1.Log(const AText: String); -begin - if fVerbose then - Memo1.Lines.Add(AText); -end; - -procedure TForm1.RunSelectedTests; -begin - -end; - -initialization - {$I unit1.lrs} - -end. - diff --git a/demos_lazarus/Demo31/Project1.lpi b/demos_lazarus/Demo31/Project1.lpi deleted file mode 100644 index 1e998ff..0000000 --- a/demos_lazarus/Demo31/Project1.lpi +++ /dev/null @@ -1,342 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos_lazarus/Demo31/Project1.lpr b/demos_lazarus/Demo31/Project1.lpr deleted file mode 100644 index 2a8c920..0000000 --- a/demos_lazarus/Demo31/Project1.lpr +++ /dev/null @@ -1,18 +0,0 @@ -program Project1; - -{.$I Definition.Inc} -uses - Interfaces, - Forms, - Unit1 in 'Unit1.pas' {Form1}, - WrapDelphiTypes in '..\..\Components\Sources\Core\WrapDelphiTypes.pas', - Unit2 in 'Unit2.pas' {TestForm}; - -{$R *.res} - -begin - Application.Initialize; - Application.CreateForm(TForm1, Form1); - Application.CreateForm(TTestForm, TestForm); - Application.Run; -end. diff --git a/demos_lazarus/Demo31/Project1.res b/demos_lazarus/Demo31/Project1.res deleted file mode 100644 index e66ecf8..0000000 Binary files a/demos_lazarus/Demo31/Project1.res and /dev/null differ diff --git a/demos_lazarus/Demo31/Unit1.lfm b/demos_lazarus/Demo31/Unit1.lfm deleted file mode 100644 index a4a1d97..0000000 --- a/demos_lazarus/Demo31/Unit1.lfm +++ /dev/null @@ -1,476 +0,0 @@ -object Form1: TForm1 - Left = 659 - Height = 647 - Top = 47 - Width = 685 - VertScrollBar.Range = 210 - ActiveControl = Memo1 - Caption = 'Form1' - ClientHeight = 647 - ClientWidth = 668 - Color = clBtnFace - Font.Color = clWindowText - Font.Height = 11 - Font.Name = 'MS Sans Serif' - Font.Pitch = fpVariable - OnCreate = FormCreate - LCLVersion = '0.9.30.2' - Visible = True - object Splitter1: TSplitter - Cursor = crVSplit - Left = 0 - Height = 3 - Top = 169 - Width = 668 - Align = alTop - ResizeAnchor = akTop - end - object Memo1: TMemo - Left = 0 - Height = 434 - Top = 172 - Width = 668 - Align = alClient - Lines.Strings = ( - 'from spam import DelphiVersion, MainForm, DVar, CreateComponent, Application, Screen, mrOk, Form, Button, CheckBox, caFree' - 'from spam import Point, Monitor, DrawGrid, gdSelected, clBlue, ssCtrl, PageControl, TabSheet' - 'if DelphiVersion >= 6:' - ' from spam import mdNearest' - 'import unittest' - 'import sys' - 'py_major, py_minor = sys.version_info[:2]' - '' - 'class MyForm(Form):' - ' def __init__(self, Owner):' - ' self.Caption = ''Subclassed form''' - ' self.btnClose = Button(self)' - ' self.btnClose.Parent = self' - ' self.btnClose.Caption = ''Close''' - ' self.btnClose.SetBounds(10, 10, 120, 30)' - ' self.btnClose.OnClick = self.btnCloseClick' - '' - ' self.chkCanClose = CheckBox(self)' - ' self.chkCanClose.Parent = self' - ' self.chkCanClose.Caption = ''Can close?''' - ' self.chkCanClose.SetBounds(10, 50, 120, 30)' - '' - ' self.grdTest = DrawGrid(self)' - ' self.grdTest.Parent = self' - ' self.grdTest.SetBounds(10, 100, 300, 250)' - ' self.grdTest.OnDrawCell = self.grdTestDrawCell' - ' self.grdTest.OnSelectCell = self.grdTestSelectCell' - '' - ' self.OnCloseQuery = self.MyFormCloseQuery' - ' self.OnClose = self.MyFormClose' - ' self.Width = 400' - ' self.Height = 400' - '' - ' def btnCloseClick(self, Sender):' - ' print "Close!"' - ' self.Close()' - '' - ' def MyFormCloseQuery(self, Sender, CanClose):' - ' CanClose.Value = self.chkCanClose.Checked' - '' - ' def MyFormClose(self, Sender, Action):' - ' Action.Value = caFree' - '' - ' def grdTestDrawCell(self, Sender, Col, Row, Rect, State):' - ' if gdSelected in State:' - ' Sender.Canvas.Brush.Color = clBlue # 0x00ff0000 # blue' - ' print "Cell[%d, %d] is selected, Rect=%s, State=%s" % (Col, Row, Rect, State)' - ' Sender.Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2, "%d @ %d" % (Col, Row))' - '' - ' def grdTestSelectCell(self, Sender, Col, Row, CanSelect):' - ' if Col == 2 and Row == 2:' - ' CanSelect.Value = False' - '' - 'class TTestForm(Form):' - ' def __init__(self, Owner):' - ' self.Caption = self.Caption + '' - changed by Python subclass''' - ' self.BindMethodsToEvents()' - '' - ' def handle_btnAdd_OnClick(self, Sender):' - ' self.ListBox1.Items.Add(self.Edit1.Text)' - '' - 'class TestDelphiWrapper(unittest.TestCase):' - '' - ' def testReadWriteProperties(self):' - ' DVar.SValue = ''Weight''' - ' self.assertEqual(DVar.SValue, ''Weight'')' - ' DVar.IValue = 70' - ' self.assertEqual(DVar.IValue, 70)' - ' MainForm.Caption = ''PyDelphi rocks!'' #setting properties' - ' self.assertEqual(MainForm.Caption, ''PyDelphi rocks!'')' - ' print' - ' print ''MainForm.ActiveControl='', MainForm.ActiveControl # class properties' - ' MainForm.BorderStyle = ''bsSizeable'' #enumeration property' - ' MainForm.Anchors = [''akTop'', ''akLeft''] #set property' - ' self.assertEqual(MainForm.Anchors, [''akTop'', ''akLeft''])' - '' - ' def testTObject(self):' - ' self.assertEqual(MainForm.ClassName, ''TForm1'')' - ' self.assert_(MainForm.InheritsFrom(''TObject''))' - '' - ' def testMethodCall(self):' - ' if DelphiVersion >= 7:' - ' DVar.SetMeUp(''Age'', 25)' - ' self.assertEqual(DVar.SValue, ''Age'')' - ' self.assertEqual(DVar.IValue, 25)' - ' print' - ' print DVar.DescribeMe() #method calls' - '' - ' def testRepr(self):' - ' print' - ' print ''Representation of Delphi objects''' - ' print DVar' - ' print MainForm' - ' if DelphiVersion >= 7:' - ' print DVar.DescribeMe # method object' - ' print DVar.SL # TStrings' - '' - ' def testTStrings(self):' - ' SL = DVar.SL' - ' self.assertEqual(len(SL), 2)' - ' print' - ' for i in DVar.SL: print i, '' contains '', DVar.SL[i]' - ' SL.Add(''New String'')' - ' self.assertEqual(len(SL), 3)' - ' self.assertEqual(SL.IndexOf(''New String''), 2)' - ' self.assertEqual(SL[0], ''Form1'')' - ' self.assertEqual(SL.Objects[0], MainForm)' - ' self.assertEqual(MainForm in SL.Objects, True)' - ' SL[2] = ''Changed''' - ' self.assertEqual(SL[2], ''Changed'')' - ' self.assertEqual(SL.Objects[2], None)' - ' SL.Objects[2] = MainForm' - ' self.assertEqual(SL.Objects[2], MainForm)' - ' self.assertEqual(MainForm in SL.Objects, True)' - ' SL.Delete(2)' - ' self.assertEqual(len(SL), 2)' - ' print "str(SL) =", str(SL)' - ' SL.Assign([1, 2, 3])' - ' self.assertEqual(len(SL), 3)' - ' self.assertEqual(''2'' in SL, True)' - ' self.assertEqual(SL[1], ''2'')' - ' tmp = [''a'', ''b'', ''c'']' - ' SL.Assign(tmp)' - ' self.assertEqual(SL.ToList(), tmp)' - ' tmp = (''a'', ''b'', ''c'')' - ' SL.Assign(tmp)' - ' self.assertEqual(SL.ToTuple(), tmp)' - '' - ' def testTComponent(self):' - ' self.assertEqual(MainForm.Name, ''Form1'')' - ' count = MainForm.ComponentCount' - ' def SetComponentCount():' - ' MainForm.ComponentCount = 3' - ' if py_major == 2 and py_minor < 5:' - ' self.assertRaises(TypeError, SetComponentCount)' - ' else:' - ' self.assertRaises(AttributeError, SetComponentCount)' - ' self.assertEquals(MainForm.__owned__, False)' - '' - ' def testSubComponents(self):' - ' MainForm.Button1.Caption = ''Click me!!''' - ' self.assertEqual(MainForm.Button1.Caption, ''Click me!!'')' - ' # test alternate mapping notation' - ' MainForm[''Button1''].Caption = ''Click me!!!!''' - ' self.assertEqual(MainForm[''Button1''].Caption, ''Click me!!!!'')' - ' self.assertEqual(MainForm.Button1.Caption, ''Click me!!!!'')' - ' # Test Owner property and DelphiObject comparison' - ' self.assert_(MainForm.Button1.Owner == MainForm)' - ' print [i.Name for i in MainForm.Components]' - '' - ' def testCreateComponent(self):' - ' NewButton = CreateComponent(''TButton'', None)' - ' self.assertEquals(NewButton.__bound__, True)' - ' self.assertEquals(NewButton.__owned__, True)' - ' NewButton.Free()' - ' self.assertEquals(NewButton.__bound__, False)' - '' - ' def testWinControls(self):' - ' self.assertEqual(MainForm.Panel1.Parent, MainForm)' - ' print' - ' print ''MainForm contains '', MainForm.ControlCount, '' controls''' - ' print [i.Name for i in MainForm.Controls]' - '' - ' def testForm(self):' - ' MyForm = CreateComponent(''TForm'', None)' - ' MyForm.Name = ''MyForm''' - ' MyForm.Caption = ''Python Generated Form''' - ' MyForm.Height = 300' - ' MyForm.Width = 310' - ' MyForm.Position = ''poDefaultPosOnly''' - ' PC = PageControl(MyForm)' - ' PC.Name = "MyPageControl"' - ' PC.Parent = MyForm' - ' PC.Align = "alClient"' - ' P1 = TabSheet(MyForm)' - ' P1.PageControl = PC' - ' P1.Caption = "Page 1"' - ' LB = CreateComponent(''TListBox'', MyForm)' - ' B1 = CreateComponent(''TButton'', MyForm)' - ' B2 = CreateComponent(''TButton'', MyForm)' - ' Edit = CreateComponent(''TEdit'', MyForm)' - ' LB.Name = ''ListBox1''' - ' LB.Parent = P1' - ' LB.Left = 20' - ' LB.Top = 14' - ' LB.Width = 121' - ' LB.Height = 97' - ' LB.TabOrder = 0' - ' B1.Name = ''Button1''' - ' B1.Parent = P1' - ' B1.Left = 185' - ' B1.Top = 60' - ' B1.Width = 75' - ' B1.Height = 25' - ' B1.Caption = ''Add to list''' - ' B1.TabOrder = 1' - ' Edit.Name = ''Edit1''' - ' Edit.Parent = P1' - ' Edit.Left = 168' - ' Edit.Top = 27' - ' Edit.Width = 121' - ' Edit.Height = 21' - ' Edit.TabOrder = 2' - ' Edit.Text = ''Add me to List''' - ' B2.Name = ''Button2''' - ' B2.Parent = P1' - ' B2.Left = 121' - ' B2.Top = 125' - ' B2.Width = 75' - ' B2.Height = 25' - ' B2.Caption = ''Close''' - ' B2.ModalResult = mrOk' - ' B2.TabOrder = 3' - ' def ClickHandler(Sender):' - ' print Sender.Name, '' was clicked''' - ' LB.Items.Add(Edit.Text)' - ' B1.OnClick = ClickHandler' - ' def KeyPressHandler(Sender, Key):' - ' if Key.Value == ''a'':' - ' Key.Value = ''z''' - ' Edit.OnKeyPress = KeyPressHandler' - ' def KeyDownHandler(Sender, Key, Shift):' - ' # forbid Ctrl+Home' - ' if Key.Value == 36 and ssCtrl in Shift:' - ' Key.Value = 0' - ' Edit.OnKeyDown = KeyDownHandler' - ' BtnNextPage = Button(MyForm)' - ' BtnNextPage.Parent = P1' - ' BtnNextPage.SetBounds(10, 200, 150, 24)' - ' BtnNextPage.Caption = "Select Next Page"' - ' def NextPageClick(Sender):' - ' Sender.Owner.MyPageControl.SelectNextPage(True, True)' - ' BtnNextPage.OnClick = NextPageClick' - ' P2 = TabSheet(MyForm)' - ' P2.PageControl = PC' - ' P2.Caption = "Page 2"' - ' BtnGotoPage3 = Button(MyForm)' - ' BtnGotoPage3.Parent = P2' - ' BtnGotoPage3.SetBounds(10, 10, 150, 24)' - ' BtnGotoPage3.Caption = "Goto Page 3"' - ' def GotoPage3Click(Sender):' - ' Sender.Owner.MyPageControl.ActivePage = Sender.Owner.Page3' - ' BtnGotoPage3.OnClick = GotoPage3Click' - '' - ' P3 = TabSheet(MyForm)' - ' P3.PageControl = PC' - ' P3.Caption = "Page 3"' - ' P3.Name = "Page3"' - ' BtnGotoFirstPage = Button(MyForm)' - ' BtnGotoFirstPage.Parent = P3' - ' BtnGotoFirstPage.SetBounds(10, 10, 150, 24)' - ' BtnGotoFirstPage.Caption = "Goto First Page"' - ' def GotoFirstPageClick(Sender):' - ' PC.ActivePageIndex = 0' - ' BtnGotoFirstPage.OnClick = GotoFirstPageClick' - ' chkAllowChange = CheckBox(MyForm)' - ' chkAllowChange.Parent = P3' - ' chkAllowChange.SetBounds(10, 40, 150, 24)' - ' chkAllowChange.Caption = "Allow Page Change?"' - ' chkAllowChange.Checked = True' - '' - ' def PCChanging(Sender, AllowChange):' - ' AllowChange.Value = chkAllowChange.Checked' - ' PC.OnChanging = PCChanging' - '' - ' MyForm.ShowModal()' - '' - ' def testFormSubclass(self):' - ' f = MyForm(Application)' - ' try:' - ' print f.ShowModal()' - ' finally:' - ' f.Free()' - '' - ' def testFormSubclass2(self):' - ' f = TTestForm(Application)' - ' try:' - ' print f.ShowModal()' - ' finally:' - ' f.Free()' - '' - ' def testPointConversions(self):' - ' p1 = Point(10, 10)' - ' p = MainForm.ClientToScreen(p1)' - ' print p' - ' p2 = MainForm.ScreenToClient(p)' - ' self.assertEqual(p2.X, p1.X)' - ' self.assertEqual(p2.Y, p1.Y)' - '' - ' def testObjectNotification(self):' - ' DVar.IValue = 0' - ' def ChangeHandler(Sender):' - ' print Sender' - ' Sender.IValue = 55' - ' DVar.OnChange = ChangeHandler' - ' if DelphiVersion >= 7:' - ' DVar.TriggerChange()' - ' self.assertEqual(DVar.IValue, 55)' - ' DVar.OnChange = None' - ' DVar.IValue = 0' - ' DVar.TriggerChange()' - ' self.assertEqual(DVar.IValue, 0)' - '' - ' def testActions(self):' - ' self.assertEqual(MainForm.ActionList1.ActionCount, 1)' - ' self.assertEqual(MainForm.ActionList1.Actions[0], MainForm.actTest)' - ' self.assertEqual(MainForm.actTest in MainForm.ActionList1, True)' - ' DVar.IValue = 0' - ' MainForm.actTest.Execute()' - ' self.assertEqual(DVar.IValue, 1)' - ' def ActionHandler(Sender):' - ' print "Action", Sender.Name, "executed from Python"' - ' DVar.IValue = 2' - ' self.assertEqual(MainForm.actTest.OnExecute, None)' - ' MainForm.actTest.OnExecute = ActionHandler' - ' self.assertEqual(MainForm.actTest.OnExecute, ActionHandler)' - ' DVar.IValue = 0' - ' MainForm.actTest.Execute()' - ' self.assertEqual(DVar.IValue, 2)' - ' MainForm.actTest.OnExecute = None' - ' self.assertEqual(MainForm.actTest.OnExecute, None)' - '' - ' def testScreen(self):' - ' self.assertEqual(Screen.DataModuleCount, 0)' - ' self.assertEqual(Screen.FormCount > 0, True)' - ' self.assertEqual(Screen.CustomFormCount > 0, True)' - ' idx = -1' - ' for i, f in enumerate(Screen.Forms):' - ' if f == MainForm:' - ' idx = i' - ' break;' - ' self.assertEqual(idx > -1, True)' - ' self.assertEqual(Screen.Forms[idx], MainForm)' - ' self.assertEqual(Screen.CustomForms[idx], MainForm)' - ' self.assertEqual(Screen.Width > 0, True)' - ' self.assertEqual(Screen.Height > 0, True)' - ' MainForm.Button1.SetFocus()' - ' self.assertEqual(Screen.ActiveControl, MainForm.Button1)' - ' def ActiveControlChangeHandler(Sender):' - ' print "ActiveControlChangeHandler fired"' - ' print "New active constrol is", Sender.ActiveControl.Name' - ' DVar.IValue = 2' - ' self.assertEqual(Screen.OnActiveControlChange, None)' - ' Screen.OnActiveControlChange = ActiveControlChangeHandler' - ' self.assertEqual(Screen.OnActiveControlChange, ActiveControlChangeHandler)' - ' DVar.IValue = 0' - ' self.assertEqual(DVar.IValue, 0)' - ' MainForm.Memo2.SetFocus()' - ' self.assertEqual(DVar.IValue, 2)' - ' Screen.OnActiveControlChange = None' - ' self.assertEqual(Screen.OnActiveControlChange, None)' - ' DVar.IValue = 0' - ' MainForm.Button1.SetFocus()' - ' self.assertEqual(DVar.IValue, 0)' - ' if DelphiVersion >= 6:' - ' m = Screen.MonitorFromPoint(Point(10, 10), mdNearest)' - ' self.assertEqual(isinstance(m, Monitor), True)' - '' - ' def testPublished(self):' - ' L = MainForm.__published__' - ' self.assertEqual(len(L) > 0, True)' - ' self.assertEqual(''Caption'' in L, True)' - ' self.assertEqual(''OnShow'' in L, True)' - '' - 'if __name__ == ''__main__'':' - ' try:' - ' unittest.main()' - ' except SystemExit:' - ' pass' - ' MainForm.ActiveControl = MainForm.Memo2 # Class property!' - '' - ' ' - ' ' - ) - ScrollBars = ssVertical - TabOrder = 0 - end - object Panel1: TPanel - Left = 0 - Height = 41 - Top = 606 - Width = 668 - Align = alBottom - BevelOuter = bvNone - ClientHeight = 41 - ClientWidth = 668 - TabOrder = 1 - object Button1: TButton - Left = 8 - Height = 25 - Top = 8 - Width = 75 - Caption = 'Execute' - OnClick = Button1Click - TabOrder = 0 - end - end - object Memo2: TMemo - Left = 0 - Height = 169 - Top = 0 - Width = 668 - Align = alTop - ScrollBars = ssBoth - TabOrder = 2 - end - object PyEngine: TPythonEngine - IO = PythonGUIInputOutput1 - left = 16 - top = 16 - end - object PythonModule: TPythonModule - Engine = PyEngine - Events = < - item - Name = 'TestFunction' - OnExecute = PythonModuleEvents0Execute - DocString.Strings = ( - 'doc for TestFunction' - ) - end> - ModuleName = 'spam' - Errors = <> - left = 56 - top = 16 - end - object PythonGUIInputOutput1: TPythonGUIInputOutput - UnicodeIO = False - RawOutput = False - Output = Memo2 - left = 168 - top = 17 - end - object ActionList1: TActionList - left = 96 - top = 80 - object actTest: TAction - Caption = 'Test' - OnExecute = actTestExecute - end - end -end diff --git a/demos_lazarus/Demo31/Unit1.pas b/demos_lazarus/Demo31/Unit1.pas deleted file mode 100644 index 6a5b450..0000000 --- a/demos_lazarus/Demo31/Unit1.pas +++ /dev/null @@ -1,204 +0,0 @@ -unit Unit1; - -{.$I Definition.Inc} - -interface - -uses - SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - StdCtrls, ExtCtrls, ComCtrls, - PythonEngine, PythonGUIInputOutput, WrapDelphi, ActnList; - -type - TForm1 = class(TForm) - Splitter1: TSplitter; - Memo1: TMemo; - PyEngine: TPythonEngine; - PythonModule: TPythonModule; - Panel1: TPanel; - Button1: TButton; - PythonGUIInputOutput1: TPythonGUIInputOutput; - Memo2: TMemo; - ActionList1: TActionList; - actTest: TAction; - procedure Button1Click(Sender: TObject); - procedure FormCreate(Sender: TObject); - procedure PythonModuleEvents0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); - procedure actTestExecute(Sender: TObject); - private - public - PyDelphiWrapper : TPyDelphiWrapper; - end; - - -var - Form1: TForm1; - -implementation - -{$R *.lfm} - -Uses - TypInfo, - Variants, - VarPyth; - - -////////////////////////////////////////////////////////////////////////// -// Using TPyDelphiObject you can wrap any Delphi object exposing published -// properties and methods. Note that the conditional defines TYPEINFO and -// METHODINFO need to be on -////////////////////////////////////////////////////////////////////////// - -{$TYPEINFO OFF} -{$IFNDEF FPC}{$METHODINFO OFF}{$ENDIF} -Type -TTestBase = class - fdouble : double; - function DoubleDValue : double; // not visible in subclasses -published - property DValue : Double read fdouble write fdouble; // will be visible in subclasses -end; - -function TTestBase.DoubleDValue : double; -begin - Result := 2 * fdouble; -end; - -type -{$TYPEINFO ON} -{$IFNDEF FPC}{$METHODINFO ON}{$ENDIF} -TTestClass = class(TTestBase, IFreeNotification) -private - fSValue : string; - fIValue : integer; - fSL : TStrings; - fOnChange: TNotifyEvent; - fFreeNotifImpl : IFreeNotification; - // implementation of interface IUnknown - function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; - function _AddRef: Integer; stdcall; - function _Release: Integer; stdcall; -protected - property FreeNotifImpl : IFreeNotification read fFreeNotifImpl implements IFreeNotification; -public - constructor Create; - destructor Destroy; override; - procedure SetMeUp(S: string; I : Integer); - function DescribeMe(): string; - procedure TriggerChange; -published - property SL : TStrings read fSL; - property SValue : string read fSValue write fSValue; - property IValue : integer read fIValue write fIValue; - property OnChange : TNotifyEvent read fOnChange write fOnChange; -end; -{$TYPEINFO OFF} -{$IFNDEF FPC}{$METHODINFO OFF}{$ENDIF} - -constructor TTestClass.Create; -begin - inherited; - fFreeNotifImpl := TFreeNotificationImpl.Create(Self); - fSL := TStringList.Create; - fSL.AddObject('Form1', Form1); - fSL.AddObject('Form1.Button1', Form1.Button1); -end; - -destructor TTestClass.Destroy; -begin - fSL.Free; - inherited; -end; - -procedure TTestClass.SetMeUp(S: string; I : Integer); -begin - SValue := S; - IValue := I; -end; - -function TTestClass.Describeme() : string; -begin - Result := fSValue + ' : ' + IntToStr(IValue); -end; - -procedure TTestClass.TriggerChange; -begin - if Assigned(fOnChange) then - fOnChange(Self); -end; - -function TTestClass._AddRef: Integer; -begin - Result := -1; // we don't want reference counting -end; - -function TTestClass._Release: Integer; -begin - Result := -1; // we don't want reference counting -end; - -function TTestClass.QueryInterface(const IID: TGUID; out Obj): HResult; -begin - if GetInterface(IID, Obj) then - Result := 0 - else - Result := E_NOINTERFACE; -end; - -{ TForm1 } - -procedure TForm1.Button1Click(Sender: TObject); -var - p : PPyObject; -begin - actTest.OnExecute := actTestExecute; - - // Wrap the Form itself. - p := PyDelphiWrapper.Wrap(Self); - PythonModule.SetVar( 'MainForm', p ); - PyEngine.Py_DecRef(p); - - // Now wrap the an instance our TestClass - // This time we would like the object to be destroyed when the PyObject - // is destroyed, so we need to set its Owned property to True; - p := PyDelphiWrapper.Wrap(TTestClass.Create, soOwned); - PythonModule.SetVar( 'DVar', p ); - PyEngine.Py_DecRef(p); - - {$IF DEFINED(FPC_VER) and (FPC_VER >= 5)} - p := PyEngine.PyInt_FromLong(FPC_VER); - {ELSE} - p := PyEngine.PyInt_FromLong(4); - {$IFEND} - PythonModule.SetVar( 'DelphiVersion', p ); - PyEngine.Py_DecRef(p); - - // Excecute the script - PyEngine.ExecStrings( memo1.Lines ); -end; - - -procedure TForm1.FormCreate(Sender: TObject); -begin - PyDelphiWrapper := TPyDelphiWrapper.Create(Self); // no need to destroy - PyDelphiWrapper.Engine := PyEngine; - PyDelphiWrapper.Module := PythonModule; - PyDelphiWrapper.Initialize; // Should only be called if PyDelphiWrapper is created at run time -end; - -procedure TForm1.PythonModuleEvents0Execute(Sender: TObject; PSelf, - Args: PPyObject; var Result: PPyObject); -begin - ShowMessage(VarPythonCreate(Args).GetItem(0)); - Result := PyEngine.ReturnNone; -end; - -procedure TForm1.actTestExecute(Sender: TObject); -begin - Memo2.Lines.Add('Delphi event actTestExecute fired'); - Import('spam').DVar.IValue := 1; -end; - -end. diff --git a/demos_lazarus/Demo31/Unit2.lfm b/demos_lazarus/Demo31/Unit2.lfm deleted file mode 100644 index b5979eb..0000000 --- a/demos_lazarus/Demo31/Unit2.lfm +++ /dev/null @@ -1,62 +0,0 @@ -object TestForm: TTestForm - Left = 725 - Height = 341 - Top = 200 - Width = 614 - ClientHeight = 341 - ClientWidth = 614 - LCLVersion = '1.5' - object CheckBox1: TCheckBox - Left = 96 - Height = 22 - Top = 16 - Width = 91 - Caption = 'CheckBox1' - TabOrder = 0 - end - object CheckBox2: TCheckBox - Left = 96 - Height = 22 - Top = 56 - Width = 91 - Caption = 'CheckBox2' - Checked = True - State = cbChecked - TabOrder = 1 - end - object btnClose: TButton - Left = 88 - Height = 25 - Top = 256 - Width = 75 - Caption = 'Close' - OnClick = btnCloseClick - TabOrder = 2 - end - object Edit1: TEdit - Left = 96 - Height = 25 - Top = 96 - Width = 121 - TabOrder = 3 - Text = 'Edit1' - end - object ListBox1: TListBox - Left = 328 - Height = 169 - Top = 48 - Width = 249 - ItemHeight = 0 - ScrollWidth = 247 - TabOrder = 4 - TopIndex = -1 - end - object btnAdd: TButton - Left = 104 - Height = 25 - Top = 128 - Width = 75 - Caption = 'Add' - TabOrder = 5 - end -end diff --git a/demos_lazarus/Demo31/Unit2.pas b/demos_lazarus/Demo31/Unit2.pas deleted file mode 100644 index 50181c7..0000000 --- a/demos_lazarus/Demo31/Unit2.pas +++ /dev/null @@ -1,42 +0,0 @@ -unit Unit2; - -{$MODE Delphi} - -interface - -uses - SysUtils, - Variants, Classes, Graphics, Controls, Forms, - Dialogs, StdCtrls; - -type - TTestForm = class(TForm) - CheckBox1: TCheckBox; - CheckBox2: TCheckBox; - btnClose: TButton; - Edit1: TEdit; - ListBox1: TListBox; - btnAdd: TButton; - procedure btnCloseClick(Sender: TObject); - private - { Private declarations } - public - { Public declarations } - end; - -var - TestForm: TTestForm; - -implementation - -{$R *.lfm} - -procedure TTestForm.btnCloseClick(Sender: TObject); -begin - Close; -end; - -initialization - RegisterClass(TTestForm); -end. - diff --git a/demos_lazarus/Python_Console/formmain.pas b/demos_lazarus/Python_Console/formmain.pas index dd24664..b2c989a 100644 --- a/demos_lazarus/Python_Console/formmain.pas +++ b/demos_lazarus/Python_Console/formmain.pas @@ -42,15 +42,15 @@ implementation {$R *.lfm} const - cPyLibraryWindows = 'python37.dll'; - cPyLibraryLinux = 'libpython3.7m.so.1.0'; - cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; - cPyZipWindows = 'python37.zip'; + cPyLibraryWindows: string = 'python37.dll'; + cPyLibraryLinux: string = 'libpython3.8.so.1.0'; //default in Ubuntu 20.x + cPyLibraryMac: string = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib'; + cPyZipWindows: string = 'python37.zip'; function Py_s0(Self, Args : PPyObject): PPyObject; cdecl; begin with GetPythonEngine do - Result:= PyString_FromString('1.0.0'); + Result:= PyUnicode_FromString('1.0.0'); end; function Py_s1(Self, Args : PPyObject): PPyObject; cdecl; @@ -58,7 +58,13 @@ function Py_s1(Self, Args : PPyObject): PPyObject; cdecl; S0: string = 'begin.Привет.end'; begin with GetPythonEngine do - Result:= PyString_FromString(PChar(S0)); + Result:= PyUnicode_FromString(PChar(S0)); +end; + +function Py_n1(Self, Args : PPyObject): PPyObject; cdecl; +begin + with GetPythonEngine do + Result:= PyLong_FromLong(-100000); end; { TfmMain } @@ -83,6 +89,7 @@ procedure TfmMain.PythonModule1Initialization(Sender: TObject); begin AddMethod('s0', @Py_s0, ''); AddMethod('s1', @Py_s1, ''); + AddMethod('n1', @Py_n1, ''); end; end; @@ -110,6 +117,8 @@ procedure TfmMain.InitFonts; end; procedure TfmMain.PythonEngineAfterInit(Sender: TObject); +const + NTest: Longint = 1 shl 30; var dir: string; begin @@ -118,6 +127,9 @@ procedure TfmMain.PythonEngineAfterInit(Sender: TObject); Py_SetSysPath([dir+'DLLs', dir+cPyZipWindows], false); {$endif} Py_SetSysPath([dir+'Py'], true); + + //test for LongInt + //Caption:= BoolToStr(PythonEngine.PyInt_AsLong(PythonEngine.PyInt_FromLong(NTest)) = NTest, true); end; procedure TfmMain.DoPy_InitEngine; @@ -133,5 +145,30 @@ procedure TfmMain.DoPy_InitEngine; PythonEngine.LoadDll; end; +{$ifdef darwin} +procedure InitMacLibPath; +var + N: integer; + S: string; +begin + for N:= 11 downto 5 do + begin + S:= Format('/Library/Frameworks/Python.framework/Versions/3.%d/lib/libpython3.%d.dylib', + [N, N]); + if FileExists(S) then + begin + cPyLibraryMac:= S; + exit; + end; + end; +end; +{$endif} + +initialization + + {$ifdef darwin} + InitMacLibPath; + {$endif} + end. diff --git a/demos_lazarus/Python_Thread/TestPyThread.lpi b/demos_lazarus/Python_Thread/TestPyThread.lpi new file mode 100644 index 0000000..44596dc --- /dev/null +++ b/demos_lazarus/Python_Thread/TestPyThread.lpi @@ -0,0 +1,100 @@ + + + + + + + + + + <Scaled Value="True"/> + <ResourceType Value="res"/> + <UseXPManifest Value="True"/> + <XPManifest> + <DpiAware Value="True"/> + </XPManifest> + <Icon Value="0"/> + </General> + <VersionInfo> + <UseVersionInfo Value="True"/> + <MinorVersionNr Value="1"/> + <CharSet Value="04E7"/> + <Attributes pvaPreRelease="True"/> + </VersionInfo> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0"/> + </RunParams> + <RequiredPackages Count="2"> + <Item1> + <PackageName Value="python4lazarus_package"/> + </Item1> + <Item2> + <PackageName Value="LCL"/> + </Item2> + </RequiredPackages> + <Units Count="3"> + <Unit0> + <Filename Value="TestPyThread.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + <Unit1> + <Filename Value="unit1.pas"/> + <IsPartOfProject Value="True"/> + <ComponentName Value="Form1"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="Unit1"/> + </Unit1> + <Unit2> + <Filename Value="testthds.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="Testthds"/> + </Unit2> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="TestPyThread"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <SyntaxMode Value="fpc"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf2Set"/> + </Debugging> + </Linking> + <Other> + <CustomOptions Value="-dUseCThreads"/> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/demos_lazarus/Demo04/project1.lpr b/demos_lazarus/Python_Thread/TestPyThread.lpr similarity index 72% rename from demos_lazarus/Demo04/project1.lpr rename to demos_lazarus/Python_Thread/TestPyThread.lpr index c450b0c..2e862e4 100644 --- a/demos_lazarus/Demo04/project1.lpr +++ b/demos_lazarus/Python_Thread/TestPyThread.lpr @@ -1,4 +1,4 @@ -program project1; +program TestPyThread; {$mode objfpc}{$H+} @@ -7,17 +7,12 @@ cthreads, {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset - Forms, Unit1; + Forms, Unit1, testThds + { you can add units after this }; -{$IFDEF WINDOWS} -{$R project1.rc} -{$ENDIF} -{$IFDEF UNIX} {$R *.res} -{$ENDIF} begin - //{$I project1.lrs} RequireDerivedFormResource:=True; Application.Scaled:=True; Application.Initialize; diff --git a/demos_lazarus/Python_Thread/TestPyThread.res b/demos_lazarus/Python_Thread/TestPyThread.res new file mode 100644 index 0000000..2a393ca Binary files /dev/null and b/demos_lazarus/Python_Thread/TestPyThread.res differ diff --git a/demos_lazarus/Python_Thread/testThread.py b/demos_lazarus/Python_Thread/testThread.py new file mode 100644 index 0000000..5095c1a --- /dev/null +++ b/demos_lazarus/Python_Thread/testThread.py @@ -0,0 +1,12 @@ +# coding: utf8 +# script for testing PythonThread +# Jurassic Pork october 2020 +import time +print('Coundown Thread1 :') +time.sleep(1.0) +i = 1 +while i < 5: + print('Thread1 : ',5 - i) + i += 1 + time.sleep(1.0) +print('Thread1 terminated') diff --git a/demos_lazarus/Python_Thread/testthds.pas b/demos_lazarus/Python_Thread/testthds.pas new file mode 100644 index 0000000..23b9a47 --- /dev/null +++ b/demos_lazarus/Python_Thread/testthds.pas @@ -0,0 +1,71 @@ +unit Testthds; + + {$mode objfpc}{$H+} + + +interface + +uses + Classes, + Graphics, ExtCtrls, Forms, + PythonEngine; + +type + +{ TTestThread } + + TTestThread = class(TPythonThread) + private + FScript: TStrings; + running : Boolean; + + protected + procedure ExecuteWithPython; override; + public + constructor Create( AThreadExecMode: TThreadExecMode; script: TStrings); + procedure Stop; + end; + + +implementation + + +{ TTestThread } + +constructor TTestThread.Create( AThreadExecMode: TThreadExecMode; script: TStrings); +begin + fScript := script; + FreeOnTerminate := True; + ThreadExecMode := AThreadExecMode; + inherited Create(False); +end; + +procedure TTestThread.ExecuteWithPython; +begin + running := true; + try + with GetPythonEngine do + begin + if Assigned(fScript) then + ExecStrings(fScript); + end; + finally + running := false; + end; +end; + +procedure TTestThread.Stop; +begin + with GetPythonEngine do + begin + if running then + begin + PyEval_AcquireThread(self.ThreadState); + PyErr_SetString(PyExc_KeyboardInterrupt^, 'Terminated'); + PyEval_ReleaseThread(self.ThreadState); + end; + end; +end; + + +end. diff --git a/demos_lazarus/Python_Thread/unit1.lfm b/demos_lazarus/Python_Thread/unit1.lfm new file mode 100644 index 0000000..3b806e1 --- /dev/null +++ b/demos_lazarus/Python_Thread/unit1.lfm @@ -0,0 +1,85 @@ +object Form1: TForm1 + Left = 159 + Height = 240 + Top = 207 + Width = 504 + Caption = 'Thread Python Test' + ClientHeight = 240 + ClientWidth = 504 + OnCloseQuery = FormCloseQuery + object ScriptBtn: TButton + Left = 6 + Height = 35 + Top = 199 + Width = 138 + Anchors = [akLeft, akBottom] + Caption = 'Start script' + Font.CharSet = ANSI_CHARSET + Font.Color = clBlack + Font.Height = -16 + Font.Name = 'Segoe UI' + Font.Pitch = fpVariable + Font.Quality = fqDraft + Font.Style = [fsBold] + OnClick = ScriptBtnClick + ParentFont = False + TabOrder = 0 + end + object Memo1: TMemo + Left = 6 + Height = 180 + Top = 6 + Width = 495 + Anchors = [akTop, akLeft, akRight, akBottom] + ParentFont = False + ScrollBars = ssAutoBoth + TabOrder = 1 + end + object ThreadBtn: TButton + Left = 166 + Height = 35 + Top = 199 + Width = 176 + Anchors = [akLeft, akBottom] + Caption = 'Start 3 threads' + Font.CharSet = ANSI_CHARSET + Font.Color = clBlack + Font.Height = -16 + Font.Name = 'Segoe UI' + Font.Pitch = fpVariable + Font.Quality = fqDraft + Font.Style = [fsBold] + OnClick = ThreadBtnClick + ParentFont = False + TabOrder = 2 + end + object StopThreadBtn: TButton + Left = 368 + Height = 35 + Top = 199 + Width = 132 + Anchors = [akRight, akBottom] + Caption = 'Stop threads' + Font.CharSet = ANSI_CHARSET + Font.Color = clBlack + Font.Height = -16 + Font.Name = 'Segoe UI' + Font.Pitch = fpVariable + Font.Quality = fqDraft + Font.Style = [fsBold] + OnClick = StopThreadBtnClick + ParentFont = False + TabOrder = 3 + end + object PythonEngine1: TPythonEngine + DllName = 'python38.dll' + DllPath = 'M:/dev/python38' + APIVersion = 1013 + RegVersion = '3.8' + UseLastKnownVersion = False + InitThreads = True + PyFlags = [pfDebug, pfInteractive] + Left = 64 + Top = 26 + end +end diff --git a/demos_lazarus/Python_Thread/unit1.pas b/demos_lazarus/Python_Thread/unit1.pas new file mode 100644 index 0000000..ebf6c2c --- /dev/null +++ b/demos_lazarus/Python_Thread/unit1.pas @@ -0,0 +1,128 @@ +unit Unit1; + +{$mode objfpc}{$H+} + + +interface + +uses + Classes, SysUtils, Forms, Controls, + Graphics, Dialogs, StdCtrls,strUtils, + PythonEngine,Testthds; + +type + + { TForm1 } + + TForm1 = class(TForm) + ScriptBtn: TButton; + ThreadBtn: TButton; + StopThreadBtn: TButton; + Memo1: TMemo; + PythonEngine1: TPythonEngine; + procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); + procedure ScriptBtnClick(Sender: TObject); + procedure StopThreadBtnClick(Sender: TObject); + procedure ThreadBtnClick(Sender: TObject); + + private + OwnThreadState: PPyThreadState; + ThreadsRunning: Integer; + procedure ThreadDone(Sender: TObject); + procedure InitThreads(ThreadExecMode: TThreadExecMode); + + + public + Thread1 : TTestThread; + Thread2 : TTestThread; + Thread3 : TTestThread; + end; + +var + Form1: TForm1; + +implementation + +{$R *.lfm} + +{ TForm1 } +procedure TForm1.InitThreads(ThreadExecMode: TThreadExecMode); +var script1,script2,script3 : TStringList; +begin +script1 := TStringList.Create(); +script2 := TStringList.Create(); +script3 := TStringList.Create(); +script1.LoadFromFile('testThread.py'); +ThreadsRunning := 3; +Memo1.Clear; +Memo1.Append('Starting 3 threads'); +with GetPythonEngine do + begin + OwnThreadState := PyEval_SaveThread(); + + Thread1 := TTestThread.Create( ThreadExecMode, script1); + Thread1.OnTerminate := @ThreadDone; + script2.Text := ReplaceStr(script1.Text,'Thread1','Thread2'); + script2.Text := ReplaceStr(script2.Text,'(1.0)','(1.4)'); + Thread2 := TTestThread.Create( ThreadExecMode, script2); + Thread2.OnTerminate := @ThreadDone; + script3.Text := ReplaceStr(script1.Text,'Thread1','Thread3'); + script3.Text := ReplaceStr(script3.Text,'(1.0)','(1.9)'); + Thread3 := TTestThread.Create( ThreadExecMode, script3); + Thread3.OnTerminate := @ThreadDone; + +end; +ScriptBtn.Enabled := False; +ThreadBtn.Enabled := False; +StopThreadBtn.Enabled := True; + +end; +procedure TForm1.ThreadDone(Sender: TObject); +begin + Dec(ThreadsRunning); + if ThreadsRunning = 0 then + begin + Memo1.Append('all the threads Terminated'); + GetPythonEngine.PyEval_RestoreThread(OwnThreadState); + ScriptBtn.Enabled := True; + ThreadBtn.Enabled := True; + StopThreadBtn.Enabled := False; + Thread1 := nil; + Thread2 := nil; + Thread3 := nil; + end; +end; + +procedure TForm1.ScriptBtnClick(Sender: TObject); +var script : TStringList; +begin +script := TStringList.Create(); +script.LoadFromFile('testThread.py'); +script.Text := ReplaceStr(script.Text,'Thread1','Script'); +Memo1.Clear; +Memo1.Append('Starting Python Script'); +GetPythonEngine.ExecStrings(script); +Memo1.Append('Python Script Terminated'); +end; + +procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean); +begin + CanClose := ThreadsRunning = 0; +end; + + +procedure TForm1.ThreadBtnClick(Sender: TObject); +begin + InitThreads(emNewInterpreter); +end; + +procedure TForm1.StopThreadBtnClick(Sender: TObject); +begin + if Assigned(Thread1) and not Thread1.Finished then Thread1.Stop(); + if Assigned(Thread2) and not Thread2.Finished then Thread2.Stop(); + if Assigned(Thread3) and not Thread3.Finished then Thread3.Stop(); +end; + + +end. + diff --git a/doc_original/Changes.txt b/doc_original/Changes.txt deleted file mode 100644 index 9f18398..0000000 --- a/doc_original/Changes.txt +++ /dev/null @@ -1,1249 +0,0 @@ -This is the list of all changes since the first release: - ----------------------------------------------------------------------- -1.2 error handling in run component ----------------------------------------------------------------------- -1.3 Inserted functionality and definitions got from - Grzegorz Makarewicz - mak@mikroplan.com.pl - http://www.mikroplan.com.pl/home/mak/python - Thank you for permission and help! ----------------------------------------------------------------------- -1.4 Cleaning up, eliminating German comments, further tests - Inserted some ideas from Andrew Robinson, - andy@hps1.demon.co.uk ----------------------------------------------------------------------- -1.5 Initialization String, some minor functionalities ----------------------------------------------------------------------- -2.0 18/12/1997 - Extended by Morgan Martinet (mmm@imaginet.fr) - The architecture of the system was changed a lot ! - See the text files (Documentation and tutorial) for more infos. - * Works with Python 1.5 Beta 2 - * Renamed unit as PythonEngine - * Cleaned the formatting of the source code - * Reorganized some parts of the source - * Reorganized the content of the components - * Used exceptions instead of error variables - * Suppressed the script, methods and InitModule of TPytRun, - because there are new components for that. - * We use the ExitProcess function instead of Halt, because - Halt does not unload the Dlls before it leaves. - * When defining methods, there's no need to add a blank method - for the last one, because we allways allocate n+1 methods, - and the new allocated data is allways cleared. - * Renamed classes, in order to avoid name conflicts - with the previous components, which can coexist: - TDynDll --> TDynamicDll - TPytDll --> TPythonInterface - TPytRun --> TPythonEngine (It hosts the interpreter) - - * Added components - TEngineClient - TMethodsContainer - TPythonType --> Lets you create a new Type object - TPythonModule --> Lets you create a new module - TPythonDelphiVar --> Lets you create Python variables - that are bound to Delphi. - TPythonOutput --> Works as a console for displaying - Python outputs. - ----------------------------------------------------------------------- -2.01 - * Py_BuildValue modified to support floats thanks to Grzegorz Makarewicz - * Renamed the functions Exec_command -> ExecString - Eval_command -> EvalString - * Added the functions EvalStringAsStr and EvalStringsAsStr - * Added a delay mechanism for the output, in order to let threads write - to output. There are 2 new functions in the module pyio: - SetDelayWrites(1/0) -> (de)activates the delaying - SetMaxLines(val) -> sets the # of lines of the output - * Added 2 functions to convert Python objects to variants and vice versa: - PyObjectAsVariant - VariantAsPyObject - VarRecAsPyObject - * Removed the flag argument of the AddMethod procedure, because it must - be always 1. - * Checked if the VarName attribute of a TPythonDelphiVar does already - exist and raise an exception. - * Added functions CheckSyntax, CheckEvalSyntax, CheckExecSyntax. - * Added functions MakePyTuple, MakePyList, - ArrayToPyTuple, ArrayToPyList, ArrayToPyDict - StringsToPyList, StringsToPyTuple, - PyListToStrings, PyTupleToStrings - * Added a function ReturnNone that returns a - Py_None object, correctly incremented. - * Extended the exception classes in Delphi that map the exceptions of Python. - Now, there's a one to one maping. - ----------------------------------------------------------------------- -2.02 07/01/1998 - * modified Py_BuildValue to handle currencies as python doubles. - * Added method TMethodsContainer.MethodWrap to call Delphi Methods - from Python. - ----------------------------------------------------------------------- -2.03 09/01/1998 - * Removed MethodWrap and added AddDelphiMethod. - I added a new type TDelphiMethod wich will constrain - to declare a valid delphi method to pass to Python. - Now it simplifies the declaration of a method, and it - checks the type of the method passed. - * Added Demo7 to show the new functionality of the Delphi - methods. I show in this demo how to use ArrayToPyTuple - in the getlong2 function. - ----------------------------------------------------------------------- -2.04 12/01/1998 - * Removed the DelphiObject argument of the AddDelphiMethod because - it could be extracted from the DelphiMethod arg (look at the trick !). - ----------------------------------------------------------------------- -2.05 13/01/1998 - * Added a property APIVersion in order to use different versions of - Python. - * Added GetOfObjectCallBack in the MethodCallback.pas and used it in - the AddDelphiMethod. - ----------------------------------------------------------------------- -2.06 27/01/1998 - * Changed how TPythonEngine checks if it already exists. - Now you can open several forms containing each a TPythonEngine, - but you can't drop 2 TPythonEngine on the same form, and when - your application will execute it will check that there's only one - instance of TPythonEngine. - * Added a new property "ExecModule" that lets you specify in which - module your code will be executed. By default it's "__main__". - * Added a new system that lets you create new Python types with - Delphi classes. So, you can use the inheritence and polymorphism - in your Python types ! And it is more easier to build ! - * Changed the tutorial, and added a demo8 that shows you how to use - the Delphi classes. ----------------------------------------------------------------------- -2.07 02/02/1998 - * Added a property "AutoFinalize" to TPythonEngine that enables or not - the call to Py_Finalize in the destructor of TPythonEngine. - It's usefull for the Python modules as Dlls. - * Added a Demo9 to show how to build a Python module as a Dll - and explained it in the tutorial. - * Changed TPythonType so that it automatically creates a variable - containing the type and labelled with the TypeName in its - linked module. Now you can check the type of an object like this: - if type(obj) is spam.Point: - ... ----------------------------------------------------------------------- -2.08 05/02/1998 - * Changed the Input/Output mechanism thanks to Mark Watts. - Renamed TPythonOutput as TPythonInputOutput. It is now a - base class that can be derived in order to output on what - you want (a RichEdit for instance). - There are 2 new events OnSendData and OnReceiveData that let - you send/receive data to/from Python where you want without - deriving a new class. You can use it if you want to send - the output to a file for debuging purposes. - There's a new component TPythonGUIInputOutput that has a property - Output that redirects the output to a RichEdit. - * Changed all demos to reflect the new design. - * Changed tutorial - * Changed Demo9, use module.Initialize instead of module.MakeModule - * cleaned up the "uses" part of the units. Used MessageBox instead of - MessageDlg. ----------------------------------------------------------------------- -2.09 08/02/1998 - * Added a property "Errors" to TPythonModule that lets you - define python errors and then raise them easily with the - 3 methods RaiseError, RaiseErrorFmt and RaiseErrorObj of TPythonModule. - Errors is a collection of TError items. - TError must have a Name (that will be used to define a string - variable into the module). You can define the property "Text" - that will define the content of the string error, if it is of type String. - If you don't define it, then we will use the property "Name" instead. - The property "ErrorType" lets you select between a String error or - a class error. The latter has the advantage of containing instance variables - that provide infos when we catch an error. And because of the class hierarchy, - we can catch a parent class. So, if you define the ErrorType to etClass, then - you can provide the name of the parent class. If it is empty, then there's no - parent ! You can define in which module the parent class can be found (we will - IMPORT this module, so it can be any module, internal or external), else it - will use the module's name of the TPythonModule where the errors are located. - * Changed demo8 to show the use of errors inside an object. - * Updated tutorial.txt - * Updated PyDelphi for the new input/output mechanism. ----------------------------------------------------------------------- -2.10 12/02/1998 - * When the Name of an Error is changed, then we update all Errors that - are derived from. We check if this Name does not already exist in the - TError collection. - * When the Module of an Error is changed, then we update all Errors that - where referencing it. - * Reactived the AddClient/RemoveClient of a TClientEngine when in - design mode. It seems that there's no crash. ----------------------------------------------------------------------- -2.11 19/03/1998 - * Corrected a bug in TMethodsContainer.ReallocMethods, because the - function realloc did not clear the new allocated memory. - * Imported function Py_malloc of the python15.dll - * Made procedure TEngineClient.SetEngine virtual ----------------------------------------------------------------------- -2.12 06/04/1998 - * Added PyFunction_Check to TPythonInterface - * Added FindFunction, EvalPyFunction, EvalFunction and EvalFunctionNoArgs - to TPythonEngine for a more sophisticated interface from Delphi - to Python functions ----------------------------------------------------------------------- -====================================================================== ----------------------------------------------------------------------- -3.00 29/11/1998 - Updated for compatibility to Delphi 4: - * TPythonModule.Clients published -> public - * TPythonDelphiVar.VarObject published -> public - * PythonVCLStd not regenerated with VCL Generator to - provide backward compatibility to Delphi 3. - - Following points conditional compiled with - $IFDEF DELPHI4_OR_HIGHER (Delphi 4, Compiler VER120): - * Included Definition.Inc to have central conditional defines. - * Python_Controls,Delphi_Controls: uses ImgList added - * Properties TCustomImageList.DragCursor and - TCustomImageList.Dragging removed. - * TDesigner in Python_Forms, Delphi_Forms deleted, - because of missing in Delphi 4 - - * Added all missing functions from Python/C API Reference Manual - part "8. Initialization, Finalization, and Threads" except - Py_GetCompiler (which is not exported by the DLL). The Py_GetPlatform - is a cheat; the result will always be "win32" (even if running - Delphi 5 under LINUX!). Py_Get(Exec)Prefix return empty strings! - * PyFrameObject updated - * PyInterpreterState and PyThreadState added. - * Added Properties InterpreterState and ThreadState to TPythonEngine - * Added published property InitThreads to PythonEngine. - * Added TPythonThread class. ----------------------------------------------------------------------- -3.01 25/05/1999 - * Fixed bug in method TPythonModule.Initialize - the event OnInitialize was fired before the module was created - * Added Date support in method TPythonEngine.VariantAsPyObject - Any TDateTime type is converted to a tuple of the form: - (year, month, day, hours, minutes, seconds, milliseconds) - * Added Date support in method TPythonEngine.PyObjectAsVariant - Any tuple of the form: - (year, month, day, hours, minutes, seconds, milliseconds) - is converted in a TDateTime - * Added methods SetVar, GetVar, DeleteVar, SetVarFromVariant, - GetVarAsVariant to the TPythonModule. - They let you easily create/modify/read/delete vars inside a Python module. - * Fixed a RefCount leak in ArrayToPyDict - * Added Demo10 implementing new Python types mapping the VCL components - TTable and TQuery for easy Database access from inside Python. - * Added method FindClient to TPythonEngine - * Fixed small bug in Repr method of a PyObject : it returned the - classname of TPythonEngine instead of this of the TPyObject ! - * Fixed bugs with Number, Sequence and Mapping services : they were - not available. - * Fixed missing reference to the function Py_GetBuildInfo in python15.dll - of Python 1.5.2 - --> full compatible with last version 1.5.2 - * Renamed package Python.dpk to Python_d3.dpk - * Added package for Delphi 4 (Python_d4.dpk) - * Removed references to the TPythonVCLStd when compiling with Delphi 4 ----------------------------------------------------------------------- -3.02 10/06/1999 - * Added global function PythonOK to test if the Python engine is - created and valid. - * Extended the VCL Generator. Now we support the methods call. ----------------------------------------------------------------------- -3.03 13/06/1999 - * Fixed bug in method TPythonModule.Initialize - The last fix from version 3.01 caused a bug ! - the event OnInitialize MUST be fired before the module was created - because it's the place where you add the Module methods ! - I restored it as it was and I added a new event : OnAfterInitialize - which lets you define vars inside the module after is has been created. - * Added method InitializeForNewInterpreter to the TPythonModule which - lets you initialize the module again in a new interpreter. - Calling the method initialize could not work because it tested - if the module was already created. - * Added Demo11 which shows you the use of threads inside Python and Delphi. - * Added property ThreadExecMode to TPythonThread class. ----------------------------------------------------------------------- -3.04 25/06/1999 - * Added dynamic creation of the TRecentFiles component in PyDelphi - in order to avoid its installation. - * Added support of varArray and sequences in the VariantAsPyObject - and PyObjectAsVariant conversion methods of TPythonEngine. - Now a varArray is converted in a Python list of values, and a - Python sequence (a list, a tuple or the like) is converted to - an array of variant. - * Extended Demo10 : added Locate and lookup support in example2 - * VCL Generator now supports generation for Delphi 4 ----------------------------------------------------------------------- -3.05 15/07/1999 - * Fixed a bug with TPythonDelphiVar found by Robert Ruehlmann : - could not get type of object (print type(DelphiVar)) ----------------------------------------------------------------------- -3.06 01/09/1999 - * Extended Demo10 : added Range support in example2 - * Fixed a bug in Demo10 if we wanted to iterate on an - empty table. - * Fixed a bug in PyObjectAsVariant introduced in 3.04 ----------------------------------------------------------------------- -3.07 14/09/1999 - * In TPythonEngine.Destroy, use Py_Finalize first, before - the finalization of modules, because Python frees objects - stored in modules and this must happen prior to the destruction - of their associated types. - * Rewrote the TPythonDelphiVar using a Delphi class - * Replaced the variant storage in a TPythonDelphiVar with - a Python object. That way you can store any Python object. - * Added two new events to TPythonDelphiVar that let you work - with a Python object instead of a Variant: - OnExtGetValue and OnExtSetValue - * Added new property ValueObject to TPythonDelphiVar, which - lets you access the object stored inside as a PPyObject. - * Updated tutorial.txt - * Updated Demo4 ----------------------------------------------------------------------- -3.08 16/09/1999 - * Added method IsVariantOk to TPythonDelphiVar wich checks if - a variant is one of the standard types (integer, string...) - * Fixed small bug in PyObjectAsVariant method of TPythonEngine, - it didn't return a variant of type varNull if no compatible - type was found, but returned instead a variant whose value - was varNull. - * Changed DateTime support as tuple to reflect the Python format - (year, month, day, hour, min, sec, DayOfWeek, JulianDay, DayLight) - according to a fix proposed by Jose Alberto Hernandis Talens - (jhernandis@arrakis.es). - * Added methods SetToList and ListToSet to TPythonEngine that - let you convert a Delphi set to a Python list, or the opposite. - * Added method IsDelphiObject to TPythonEngine which lets you - test a Python object, in order to know if the underlying object - is a Delphi class (that inherits from TPyObject). - * Fixed a bug found in TPythonEngine.FindFunction: - if the function was not found, Python raised an exception that - was visible only on the next execution of a script. - * Fixed a bug in the finalization of the Python engine: - GetPythonEngine calls TPythonEngine.Initialized to check if Python - is properly initialized, but Initialized calls Py_IsInitialized to - check it, and this functions returns falls after a call to - Py_Finalize. - But Py_Finalize clears all modules and their attributes, which - may call your object destructor, which will use some Python API - but it will raise an exception because it will detect that - Python is no more initialized ! - So, I've added a property to TPythonEngine (Finalizing) that - GetPythonEngine will check before Initialized. If it's true - (it is the case only when calling Py_Finalize), then no exception - is raised. - * Added a public method Finalize to TPythonEngine, that lets - you finalize Python yourself, instead of waiting that - the TPythonEngine object is destroyed by the form. - * Extended Demo10 - * Checked compatibility with Delphi 5. - It's fine : there was nothing to do ;-) - * Added a package for Delphi 5 ----------------------------------------------------------------------- -3.09 29/09/1999 - * Added event OnPathInitialization to TPythonEngine that will let - you define the Python path in the Windows Registry if it was not - already done. - * Updated tutorial.txt and added a warning in the Demo8 - * Added property DocString to the TPythonType that lets you define - a documentation string for your type. - * Added property DocString to the TPythonModule that lets you define - a documentation string for your module. - * Extracted the VCL Generator in an external project. - * Added DocStrings to all types, modules and methods of - the Demo10. Look at example2. - * Added a test with IsDelphiObject in the function - PythonToDelphi. - * Introduced events in VCL Objects of Demo10 ----------------------------------------------------------------------- -3.10 11/10/1999 - * in function pyio_write, we forbid the printing of any other thread - than the main thread, because we could not get to a stable state - in multi-threading. - * Added a docstring for the CreateXXX functions that instantiate - a type XXX. - * Added more events in Demo10 - * Added a new property __properties__ to the types mapping the - VCL objects in Demo10, which returns a list of - all available properties. It's like the __methods__ property - but for the properties. - * Added alias "__members__" to "__properties__" - * Added properties InstanceCount, CreateHits, DeleteHits to - the TPythonType, which keep track of the instances allocation. - * Added function GetTypesStats to the pyio module, which will - gather the stats of each type in a list of tuples. - Look at Demo10, example5. - * Added method CheckError to TPythonEngine. - It simply checks if a Python error occurred and if yes, it - prints the Python error and raises a Delphi exception. - * NEW ! NEW ! NEW ! : - Added PythonAtom unit from Olivier Deckmyn (olivier.deckmyn@mail.dotcom.fr) - It lets you elegantly access any Python object as an Ole object !!! - You can look at the Demo12 and PythonAtom.hlp - * In Demo10, splitted file pyDatabase.pas in pyDB.pas and pyDBTables.pas - to reflect the VCL unit names. - * NEW ! NEW ! NEW ! : - Added new component TPythonDatabase that implements the VCL units - DB and DBTables for Database access. Look at Demo13. - * Added Demo13 that shows the use of the TPythonDatabase component. - It it the same demo as Demo10, but with the new component. - * Added new package PythonVCL_d3.pkg for the TPythonDatabase component. - * Added new package PythonVCL_d4.pkg for the TPythonDatabase component. - * Added new package PythonVCL_d5.pkg for the TPythonDatabase component. - * Updated readme.txt and tutorial.txt ----------------------------------------------------------------------- -3.11 14/10/1999 - * Added Demo14 that builds a DLL module from the database components - that will give you access to the database stuff from any Python application, - even from the Python console. - * Updated readme.txt and tutorial.txt - * Added new property "Traceback" to TPythonEngine, which lets you - browse the traceback after the execution of a Python script that - raised an exception. This property is a TPythonTraceback object - that contains a list of Items (TTracebackItem). Each item - contains the filename, lineno and context informations. - This list is automatically refreshed when using TPythonEngine - execution methods, but if you use Python core API, you may call - the Refresh methods at any time (but after the PyErr_Print function), - or you should better call the CheckError method of TPythonEngine. - * TPythonEngine.CheckError refreshes automatically the Traceback. - * In design mode, each new droped EngineClient will automatically find - a TPythonEngine and link to it through the Engine property. ----------------------------------------------------------------------- -3.12 24/11/1999 - * In TPythonEngine.RemoveClient, we call TPythonEngine.Finalize, if running, - in order to finalize the Python virtual machine BEFORE any TEngineClient - is destroyed by Delphi, because if it occurrs prior to Py_Finalize, the destruction - of a Python object which uses an already destroyed TEngineClient would cause - a memory crash ! - * In PyObjectDestructor, we check if PythonOk before call the object destructor. - This avoids crashes with Dlls. - * Made some cleaning in all demos to work properly with Delphi5 - * Updated readme.txt and tutorial.txt - * Made an installer that handles all the installation of Python for Delphi - in all versions of Delphi (3 to 5). ----------------------------------------------------------------------- -3.13 29/11/1999 - * Enhanced checking of date in TPythonEngine.PyObjectAsVariant - * Added Demo15 - * Updated tutorial.txt - * Changed representation string of a TPythonDelphiVar - * Removed "Evaluate" button in all demos, except in Demo02. - * In PyDelphi, used TPythonEngine.Traceback and fixed name collapse between - form and type. ----------------------------------------------------------------------- -3.14 08/12/1999 - * TPythonGUIInputOutput now supports any kind of TCustomMemo, it means that you - can use a TMemo or a TRichEdit. - * Changed Demo1 that uses a TMemo instead of a TReachEdit - * Updated tutorial.txt - * Changed Demo10 and Demo13: added example6 that shows how to subclass any - Python object with a Proxy class. - * Added file deployment.txt that gives some hints on deploying a Delphi application - using Python. - * Added Demo15, that presents 2 examples of interaction between Delphi and Python. - These examples were posted on the Python for Delphi mailing list. ----------------------------------------------------------------------- -3.15 25/02/2000 - * Enhanced method TPythonEngine.VariantAsPyObject: added support for multi-dimensional - variant arrays (limited to 3 dimensions) - * Added demo17 that shows the use of variant arrays of 2 dimensions. - * Renamed TCallType constants to : - TCallType = (ctSTDCALL, ctCDECL); - in order to avoid a name conflict in C++ Builder. - * Added C++ Builder compilation support, thanks to Sergey A. Kosmakov (sergek@etr.ru) - * Added Demo18 for C++ Builder: shows how to use the python15.dll in a console app. - * Added Demo19 for C++ Builder: it's a replicate of Demo05 - * Added Demo20 for C++ Builder: it's a replicate of Demo08 - * Updated tutorial.txt - * Added file C++ Builder Notes.txt - * Updated definition.inc ----------------------------------------------------------------------- -3.16 29/11/2000 - * Fixed a small bug in CheckRegistry: if the registry key - containing the path was not defined, it tried to write something - even if the event OnPathInitialization was undefined. - Under NT, if not administrator, it would raise an exception as - it's forbidden to write under the HKEY_LOCAL_MACHINE without the - admin rights. - * Changed Dietmar's email: dbudelsky@web.de - * Added method TPythonEngine.SetProgramArgs which will set the command line arguments transmitted - to the application in the sys.argv list. - * Added C++ Builder 5 packages - * Added new property UseWindowsConsole to TPythonEngine, that lets you use a Windows Text console - instead of a TMemo. If you set it to True, then don't use the RedirectIO ! - The main advantage is that it works very well with multi-threading ! - It works only if the property is set prior to loading the Python DLL. - * Gene Chiaramonte (gchiaramonte@mail.com) fixed a bug in PythonAtom: the order of method arguments - had to be reversed ! - * Sigve Tjora (public@tjora.no) fixed a reference counting bug in PythonAtom. - * Sigve Tjora (public@tjora.no) made some interesting enhancements in PythonAtom: - - allow pythonAtoms to be passed as arguments to python methods. - Probably PythonDelphi variables can be used to, but it has not been tested. - - allow results from pythonAtom methods to be used as arguments to other pythonAtom methods. - - * Sigve Tjora Updated demo12 to demonstrate the use of its new feature. - * Mark Derricutt (mark@talios.com) added an "Events" collection for defining Python methods - in a TPythonModule. This will ease the declaration of new methods !!! - * Added Demo21 which introduces the new Events collection feature. - * Added Demo22 which presents the new UseWindowsConsole property of TPythonEngine, and - uses the new possibility to extract command line arguments. - We execute a threaded program, which runs fine with the Windows console. - With threaded programs, you must always take care that the calling thread finishes after all - created threads ! This is easily done using the threading module and its "join" method. - Note for Python 1.5.2 version : - if you're using the "threading" module, you should do a TPythonEngine.Finalize in the - OnClose event of your form, otherwise you'll get an access violation ! I don't know why ? - It works fine with the new 1.6 or 2.0 versions. - * Added Demo23 which is basically the same as Demo22, but uses the Delphi Log (since Delphi4) window - for displaying Python output instead of using the Windows console. The main advantage is that you - can scroll the log window, and save its content to a file, but the drawback is that you must - run Delphi ! - * Updated tutorial.txt - * allowed the possibility of doing Initialize/Finalize several times in TPythonEngine, in order - to clear the engine memory. - * Added property UseLastKnownVersion to TPythonEngine. If true, PythonEngine will attempt to load - automatically the latest known Python dll. - * Python for Delphi works fine with the latest version 1.6, and with the version 2.0 - But I couldn't generate a python20.lib file for the C++ Builder users ! So, just use the component - which uses dynamic linking, and avoid the static linking of the Dll. - * Python for Delphi installs correctly under Windows 2000. - * Fixed a bug in TPythonModule.GetVar. If the var was not found, it would raise a Python exception - the next time you execute a script. - * Igor E. Poteryaev (jah@mail.ru) updated some new API definitions matching the new version 2.0 - * Added new methods to the TPyObject class for supporting new API introduced in version 2.0 - * Added 2 properties to TPythonEngine: GlobalVars and LocalVars. - You can set a Python dictionary that will be used by the TPythonEngine.Run_CommandAsObject - method. Set properties will increment the reference count of the object. - * Sigve Tjora subclassed TPythonEngine (TAtomPythonEngine) in a new unit AtomPythonEngine.pas, - because he had to use the PythonAtom.pas unit, and we don't want to use Com code in the - PythonEngine.pas unit. The unit is added to the Python_d?.dpk package. - * Stefan Franke [franke@meso.net] fixed a bug in PythonAtom.pas: - when you called a Python function that returned a result and if you didn't assign the returned - value to a Delphi variable, you would get an access violation. - * Fixed a bug in PyObjectAsVariant: if the Python object was a class instance, that didn't implement - the sequence API, it would raise a Python exception. Now, we check that the sequence API is - properly implemented, and return a Null variant if not. - * Added Demo25 made by Sigve Tjora for demonstrating the use of the TAtomPythonEngine. - ----------------------------------------------------------------------- -3.17b1 09/07/2001 - * Added compatibility with Python 2.1 - * Yuri Filimonov (fil65@mail.ru) fixed a bug in the asm code of Py_BuildValue: the EBX register was - not correctly restored. - * Added compatibility with Delphi6 - * Added unit VarPyth.pas that replaces the PythonAtom.pas, using the new variant custom types of D6. - * In PythonEngine.pas, added functions: - PyObject_DelItem - PyObject_IsInstance - PyObject_IsSubclass - PySequence_Contains - GetMainModule - * Extracted the definition of the PYTHON symbols from PythonEngine.pas to Definition.inc - * Added Demo25 that runs several unit tests for validating the new VarPyth.pas functionality. - It's a good start to look at all that's possible... ----------------------------------------------------------------------- -3.17b2 22/07/2001 - * Fixed a bug in TPythonEngine.PyObjectAsVariant thanks to cipherhaze@yahoo.com.au: - the Python strings containing a zero were truncated when beeing converted - to a variant. - - * in PythonEngine.pas: - - added method TPythonEngine.PySequence_DelSlice - - added var TPythonInterface.Py_OptimizeFlag - - added var TPythonInterface.Py_InteractiveFlag - - added var TPythonInterface.Py_NoSiteFlag - - added var TPythonInterface.Py_TabcheckFlag - - added var TPythonInterface.Py_UnicodeFlag - - added property TPythonEngine.PyFlags that lets you enable some Python flags very easily, - like Verbose mode, or Optimize, thanks to a thread started in the mailing list. - - * in VarPyth.pas: - - added function VarAsPython --> cast a variant into a Python variant. - - added function GetAtom --> compatibility mode with former PythonAtom.pas - you can use the VarPyth unit instead of PythonAtom, and get the same behaviour of PythonAtom - when instanciating the Python variants with the function GetAtom. - Note however, that you must replace all your OleVariant types with Variant. - You can test it on Demo12: in the uses statement, replace PythonAtom with VarPyth, - and declare myAtom as a Variant, instead of OleVariant. That's all! - But if you're instanciating the Python variants with VarPythonCreate, you'll get the new - behaviour, so you can benefit from the 2 worlds, simultaneously! - - added function len --> return the length of a collection. Same as the len function of Python - and same as using the Length property or Length() method. - So, len(obj) = obj.Length = obj.Length() - - added function _type --> return the type object of a Python object - - added function VarIsSameType --> checks if 2 python variants have the same Python type. - - added function VarIsTrue --> return true if the variant is different from zero or None. - This is the same as casting a variant to a boolean. - - added function Ellipsis that can be used in GetSlice or SetSlice, if you don't want to specifiy - explicitly the length of sequence. So, foo.GetSlice(2, Ellipsis) is equivalent with foo[2:] - - added function BuiltinModule that returns the __builtin__ module object, that contains all - the builtin functions that you can use directly: - _hash := BuiltinModule.hash(foo) - - added special method DelSlice for sequence objects, that does the same as: del list[x:y] ----------------------------------------------------------------------- -3.17 27/08/2001 (final) - * Added file py21.lib in the Components folder, it's the lib file for Python 2.1 that allows you - to use the C native APIs of the Python dll. - * Updated the C++ demos to use the py21.lib file - * Updated include files with Python 2.1 version. - * Updated file C++ Builder Notes.txt - * Fixed a bug thanks to Gene Chiaramonte: when running an application with no component for Python output, - an exception was raised while closing the form that hosted PythonEngine, because it tried to restore the initial streams, - whereas no redirection was done. - * Added function NewPythonTuple to VarPyth.pas - * Updated Demo25: added a test for the dates. - * Finished update for changes from version 2.1: - - added enum bsRichCompare to set TBasicServices - - added virtual method RichCompare to TPyObject - - added property TypeFlags to TPythonType for setting new behaviours like tpfHaveRichCompare. ----------------------------------------------------------------------- -3.18 02/11/2001 - * mitchchapman@earthlink.net fixed a bug in the VarPyth.pas unit: a crash occurred with some - variants used by ref, with an integer value corresponding to the ID of the VarPython custom - variant type. - * Added access to the variable Py_NotImplemented that should be used in the new coercion model of - version 2.1 - * Added Kylix support!!! But I have 1 issue: - - the varargs functions don't work in Kylix (cf PyArg_Parse and PyArg_ParseTuple) - * Started converting the demos to cross-platform usage: Demo01, 02, 03, 07, 09 and 25 - * Added new beta version 2.2 to the list of the known versions, and started implementing modifications: - changed the record definitions of the PythonType object, and Code object, that caused a problem - for parsing the traceback. Be sure to define the symbol PYTHON22 before including the definition.inc - because I won't set it as a default until the 2.2 becomes official. - Warning! The date module has introduced a new time_struct for storing a date/time value - in new beta version 2.2. - Maybe the traceback has changed also. - * Added file "Kylix Notes.txt" - * Made the code compatible with the last service pack update for Delphi 6. ----------------------------------------------------------------------- -3.19 16/11/2001 - * Fixed Kylix port issue: the PyArg_Parse and PyArg_ParseTuple now work properly - thanks to Stefan.Hoffmeister@Econos.de - * Finished converting the demos to cross-platform usage: Demo04, 05, 06, 08, 11, 16, 17, 21, 22, 23. - Note that the remaining demos are simply not portable (they use TTable or PythonAtom). - * Continued implementation of the news from version 2.2 of Python. - * Fixed some problems when using the PYTHONXX defines, thanks to Andy Bulka (abulka@netspace.net.au). ----------------------------------------------------------------------- -3.20 08/01/2002 - * Fixed a ifdef bug in PythonEngine.pas - * Fixed a bug in VarPyth.pas: when setting a property of a Python object, the assigned value - was converted from/to a variant, even when it was a VarPython variant! - * Added APIs for Long objects, and compatibility between Python long objects and Int64 variants. - * Used new Python2.2 APIs for true division (/) and floor division (div) inside VarPyth. - You can now override these behaviours inside your TPyObject classes. - * Added Iter and IterNext new services of Python2.2 to TPythonType. - * Added Traverse and Clear new services of Python2.0 to TPythonType (they are used with Garbage collection). - * Added UNICODE support. A Python Unicode string is kept as wide string inside a variant. - A variant is converted into a Python Unicode string only if the symbol PREFER_UNICODE is defined inside the - file definition.inc - Added APIs PyUnicode_FromWideChar, PyUnicode_AsWideChar - Added methods Unicode_check, PyUnicode_AsWideString, PyUnicode_FromWideString - Note that UNICODE was introduced in Python 2.0 - Note that it will work under Kylix, but I deactivated it as I've got a bug with the WideString conversions. - * Added function VarPythonEval to VarPyth.pas, that returns a new Python variant from the evaluation of a Python - expression. This is the same as VarPythonCreate(GetPythonEngine.EvalString(MyExpression)) - * Ready for the new time_struct object of Python 2.2 that replaces the tuple of 9 items, but that remains compatible - with it. - * Updated the list of Python exceptions, with their Delphi mapping, using version 2.2. - * Updated set of Python flags up to Python 2.2 - * Changed the way of loading the latest version of Python when UseLatestKnownVersion is true: - first we always start from the version which PythonForDelphi was compiled for, and if we don't find it we - try to upgrade the version, only if the new version is compatible with the compiled version. - So, if P4D was compiled for Python 1.5.2 it will only look for python15.dll, and won't try to use python22.dll. - If P4D was compiled for Python 2.1.1 it will first look for python21.dll, then for python22.dll as it's compatible. - * Rewrote the way to extract the traceback content by using PyObject_GetAttrString API instead of direct access to - the traceback record object, to avoid compatibility issues between different versions of Python. - * Added PyWeakRef and PyWrapper APIs, from Python 2.2. - * Updated file "Kylix Notes.txt" ----------------------------------------------------------------------- -3.21 06/03/2002 - * Fixed a compilation problem when using PYTHON15 symbol. - * Added a default implementation of TCriticalSection for Delphi3 that misses the unit SyncObjs.pas. - * Added property DllPath to specify a folder where the Python Dll should be searched. You can define this property - at runtime, using the event OnBeforeLoad. - * Fixed a bug with custom variants and Int64, introduced by the UpdatePack2 of Delphi6. - * Modified installer to let the user choose a default version of Python before compiling the packages. - * Fixed the WideString/Unicode bug in Kylix. In fact, it was not due to Borland but to Python itself! Python on Linux is supposed - to use UCS2 strings, whereas it actually uses UCS4 strings!!! - * Added a new define HAS_MODIFIED_DISPINVOKE to Definition.inc, to distinguish between Delphi6, Kylix1 and Kylix2, as Kylix2 uses - a modified interface of the method DispInvoke of the custom variants, that has a PVarData parameter instead of a - (var xxx : TVarData). - * Updated file "Kylix Notes.txt" - * Modified DispInvoke of the VarPyth unit. - * PythonForDelphi is up and running with the latest versions of Delphi and Kylix (and Python), - but note that there's a problem with Kylix2 (I used the OpenEdition): all compiles and works fine, but the IDE - crashes when a form hosting PythonForDelphi components is closed! I don't know why, as it works fine with Kylix1 - and all Delphi versions! I'll have to investigate further... ----------------------------------------------------------------------- -3.22 22/03/2002 - * Removed a warning when compiling PythonGUIInputOutput.pas, thanks to Mitch Chapman (mitchchapman@earthlink.net) - * Updated Demo25, and allowed it to work with Python2.0 or higher. ----------------------------------------------------------------------- -3.23 20/10/2002 - * Delphi7 Ready. - * Fixed a nasty bug that occurred in some cases, but that should have always occurred. To allow multiple Finalize/Initialize - sequences, I moved the ClearEngine loop from the Finalize method to the Destroy method of TPythonEngine. - It was wrong, because when the TPythonEngine was destroyed it tried to call the ClearEngine method of each - of its clients, that were usually already destroyed! The problem appears only when there are a lot of Python components, - otherwise it seems that the memory allocated for the client component is still available for the process - and thus doesn't cause an access violation. This bug was originally discovered by Dietmar. - * Fixed a memory leak in unit VarPyth.pas, in function VarPythonEval - * Fixed a memory leak in Demo25. - * Problem with Kylix3: I can't get the package to compile because it fails with an internal error. - However if you use the Python units inside a project it will compile without any problem! Anyway, I still - have issues with the components in design time, because Delphi IDE freezes when closing a form hosting the - components. So, it may be a workaround for both problems to dynamically create the Python components. ----------------------------------------------------------------------- -3.24 29/01/2003 - * Fixed nasty bug that would freeze Kylix2 IDE (and maybe Delphi6/7 in some cases): - in unit PythonGUIInputOutput.pas, method TPythonGUIInputOutput.Notification did not call inherited! - * Fixed bug in PythonEngine.pas, in VariantAsPyObject when called by VarPyth.TPythonVariantType.VarDataToPythonObject. - It caused a variant memory error when doing a dict.SetValue('key', ''); (empty string). - Bug reported by Andy Bulka [abulka@netspace.net.au] - * Added Python 2.3 compatibility: - - new bool type: PyBool_Check, PyBool_FromLong - - new date, time, datetime, delta... types from new datetime module - - new property DatetimeConversionMode in TPythonEngine allowing to decide how a variant containing - a datetime should be converted into a Python object. - Presently there are only 2 modes: the default is dcmToTuple (a tuple containing year, month, day...) - and starting with Python2.3 you get dcmToDatetime that will use the new datetime objects of the - datetime module. I could not set it as default to avoid breaking existing code. - - new exceptions: PyExc_FutureWarning, PyExc_PendingDeprecationWarning, PyExc_UnicodeDecodeError, - PyExc_UnicodeEncodeError, PyExc_UnicodeTranslateError - - - new APIs (note that some of them were missing since previous Python versions): - PyType_IsSubtype, PyObject_TypeCheck, PyBaseString_Check - PyObject_GC_Malloc, PyObject_GC_New, PyObject_GC_NewVar, PyObject_GC_Resize, - PyObject_GC_Del, PyObject_GC_Track, PyObject_GC_UnTrack - PyType_IS_GC, PyObject_IS_GC - PySlice_GetIndicesEx, PySlice_Check - PyString_DecodeEscape, PyString_Repr - - - new behaviour: - - With Python2.3 the following functions return True if the Python object is the expected type or - one of its descendants: - PyString_Check - PyFloat_Check - PyInt_Check - PyLong_Check - PyTuple_Check - PyList_Check - PyDict_Check - PyModule_Check - PyUnicode_Check - - To check if a Python object is really (and only) the expected type then use the new functions instead: - PyString_CheckExact - PyFloat_CheckExact - PyInt_CheckExact - PyLong_CheckExact - PyTuple_CheckExact - PyList_CheckExact - PyDict_CheckExact - PyModule_CheckExact - PyUnicode_CheckExact - - * in unit VarPyth.pas, added functions: - - VarIsSubtypeOf - VarIsPythonDateTime - VarIsPythonDate - VarIsPythonTime - VarIsPythonDateTimeTZ - VarIsPythonDateTimeDelta - VarIsPythonTimeTZ - VarIsPythonTZInfo - VarIsBool - VarIsEnum - DatetimeModule - - - updated Demo25 to reflect last additions made to VarPyth.pas - - ----------------------------------------------------------------------- -3.25 5/04/2003 - - * Added compatibility with Python 2.3b2 that refactored the new datetime module. - - * Allowed TPyObject instances to be created without a TPythonType, in order to use them outside - P4D context (give nil as argument). This is a suggestion made by Gert Steyn [gert@ise.co.za] - - * Fixed a bug in TPythonType.TypeFlagsAsInt where some flags where forgotten - (tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC) - thanks to jacoboy1234 [fan_jacob@hotmail.com] - - * Added APIs PyObject_GenericGetAttr, PyObject_GenericSetAttr, - PyType_GenericAlloc, PyType_GenericNew, PyType_Ready, PyObject_Free - - * Added new class TMembersContainer allowing TPythonType to define members of a type - and added class method RegisterMembers to TPyObject, allowing type objects to define - their members, to be used when subclassing an existing type. - - * Added new class TGetSetContainer allowing TPythonType to define properties with - Get/Set accessor functions, and added class method RegisterGetSets to TPyObject, - allowing type objects to define their properties, to be used when - subclassing an existing type. - - * Allowed any TPythonType (and related TPyObject class) to become a base type - that may be subclassed within Python. - To use this feature, simply select tpfBaseType in the TypeFlags property of TPythonType, - then override TPyObject.RegisterMembers in your Python/Delphi class and expose each - of your instance member as a MemberDef (call AType.AddMember(...)). - You can override TPyObject.RegisterGetSets in you need to expose properties - with Get/Set accessor functions. - - You should not override GetAttr and SetAttr anymore and you should not - select the Basic services flags [bsGetAttr, bsSetAttr]. - Instead, simply select the flags [bsGetAttrO, bsSetAttrO] and the class - TPyObject does simply call PyObject_GenericGetAttr in GetAttrO - and PyObject_GenericSetAttr in SetAttrO. - The Python Generic Get/Set functions will use new slots introduced in - the type object for specifying a list of members (class fields), - a list of get/set functions (like properties in Delphi) and a list - of methods. That way a subclass can introduce its own members/get,set/methods - and call the others coming from the base classes. - - You can override the new Init method of TPyObject if you want to perform the same kind - of initialization that you would do in the __init__ method of a Python class. - Note however that by default the CreateWith constructor of TPyObject will be called - when instanciating a new subtype, allowing you to get constructor arguments as you - already did with regular types. - - Note that for a subtype instance, the memory allocated will come from - Python heap and not from Delphi. So, we have a reserved space inside the subtype - instance where we plug our Delphi class definition. This is tricky but it works! - - Note that TPyObject now has a new attribute IsSubType set to True when a subtype - is instanciated. - - Note that if tpfBaseType is set, you can now instanciate a type by calling its type - object instead of relying on the CreateXXX function. Ex: p = spam.Point(3, 2) - In that case Python acts as it would create a subtype instance by using the - tp_new slot of your type, but the type pointer given is the one of your TPythonType. - So, your TPyObject instance will have memory allocated by Python (prop PythonAlloc - is true) and the property IsSubType will be set to False. - - Note that to enable this double behaviour, I had to change the way a TPyObject is - allocated: I removed the first two fields (ob_refcnt and ob_type) and replaced them - with public properties, and redefined NewInstance and FreeInstance to - allocate a bigger chunk of memory (with Sizeof(PyObject) more) and offseted the - Self pointer to start after the PyObject header (containing the space reserved - for the ob_refcnt and ob_type fields). So, when the ob_refcnt and ob_type properties - access their associated data, they pick it from this extra hidden header. - Note that when using GetSelf, it will return a pointer to the the start of this - hidden header. And the Adjust method will correct Self to move after this header. - Finally, in FreeInstance, we free the memory only if PythonAlloc is False. - - A B C - +-------------------++------------------------------------------------------+ - | PyObject header || TPyObject class | - +----------+--------++-----------------+------------+----------+------------+ - |ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc | - |integer |pointer ||pointer |TPythonType |Boolean |Boolean | - |4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte | - +----------+--------++-----------------+------------+----------+------------+ - - ^ ^ - | | - ptr returned ptr returned by Adjust - by GetSelf - - - a Python object must start at A. - - a Delphi class class must start at B - - TPyObject.InstanceSize will return C-B - - Sizeof(TPyObject) will return B-A - - The total memory allocated for a TPyObject instance will be C-A, - even if its InstanceSize is C-B. - - When turning a Python object pointer into a Delphi instance pointer, PythonToDelphi - will offset the pointer from A to B. - - When turning a Delphi instance into a Python object pointer, GetSelf will offset - Self from B to A. - - Properties ob_refcnt and ob_type will call GetSelf to access their data. - - - Subclassing TPyObject in Delphi (TPyPoint = class(TPyObject)) - - A B C D - +-------------------++------------------------------------------------------+-----------------+ - | PyObject header || TPyObject class | TPyPoint class | - +----------+--------++-----------------+------------+----------+------------+--------+--------+ - |ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |x |y | - |integer |pointer ||pointer |TPythonType |Boolean |Boolean |integer |integer | - |4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |4 bytes |4 bytes | - +----------+--------++-----------------+------------+----------+------------+--------+--------+ - - - TPyPoint.InstanceSize will return D-B - - The total memory allocated for a TPyPoint instance will be D-A - - The Python type object will have D-A in its tp_basicsize slot. - - in RegisterMembers, calling - PythonType.AddMember('x', mtInt, Integer(@TPyPoint(nil).x), mfDefault, 'x coordinate'); - will produce an offset of C-A, instead of C-B, because AddMember will add - automatically B-A to the offset. - - - - Subclassing TPyPoint in Python (class MyPoint(spam.Point)) - - - A B C D E - +-------------------++------------------------------------------------------+-----------------+---------+ - | PyObject header || TPyObject class | TPyPoint class | MyPoint | - +----------+--------++-----------------+------------+----------+------------+--------+--------+---------+ - |ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |x |y |Dict | - |integer |pointer ||pointer |TPythonType |Boolean |Boolean |integer |integer |pointer | - |4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |4 bytes |4 bytes |4 bytes | - +----------+--------++-----------------+------------+----------+------------+--------+--------+---------+ - - - The total memory allocated for a MyPoint instance will be E-A - - The Python type object will have E-A in its tp_basicsize slot. - - The Python type object will have D-A in its tp_dictoffset slot (it is the tp_basicsize of - the inherited type, accessible through tp_base). - - The memory allocation is done by Python, that also initializes parts A-B and D-E, - leaving us an available space between B and D. That's why we can't have the - ob_refcnt and ob_type fields inside the TPyObject class definition, as they would - appear in the free space available for the parent types and would not be used - by Python. This would not be an issue, except for calculating the exact member offsets. - - So, hiding the PyObject header and ensuring this always comes first, makes it consistent - in all cases for the member offsets to remain valid. - - - * Added Demo26 to show how you can build base types (This is an adaptation of Demo8), - and updated Tutorial.txt for giving some explanations to the new way of building - types allowing subclassing. - - * Allowed a TPythonType to be dynamically created after everything has already been - setup. It means that the module hosting the type will effectively have a variable - referencing the new Type object and a CreateXXX function for creating new instances - of that type. ----------------------------------------------------------------------- -3.26 6/09/2004 - - * Added compatibility with new version 2.4 of Python (Alpha presently) - * Added new document "Deploying P4D.PDF" explaining how you can deploy your own version of Python (using a private folder). - * Fixed a bug in PythonEngine.pas: when trying to convert a variant containing an empty string to a Python object, - the application could crash with a Memory error exception. - * Fixed a small memory leak when instanciating TPythonEngine at runtime, without an Owner, then TPythonEngine would leak - and internal TPythonModule used for redirecting I/O. (thanks to t.handler@n-tree.com) - * Fixed a problem in demo 16 / Example 1 (missing a __str__ override in the wrapper class) - ----------------------------------------------------------------------- -3.27 01/12/2004 - * added method flush when redirecting IO. This was fix made by Qi Wenmin (dumm@libr.3322.org): -In my work I find a little problem with the RedirectIO feature. I enable the RedirectIO and add a stream handler of logging package to the logger. When I launch the script in Delphi, the engine reports the stream handler has no flush() method. So I make some change with PythonEngine.pas, add the following codes into the code constant in the TPythonEngine.DoRedirectIO method: - - * fixed a bug when the datetime module was not deployed, P4D would raise an exception while executing - RedirectIO. - - * added new event OnSysPathInit to TPythonEngine. This event is fired immediately after Py_Initialize and - will provide the list object stored in sys.path, containing all the folders used by Python to find - an imported module. - This will allow you to extend the path when you have a custom installation that is not allowed to touch - the windows registry/filesystem. - Example: - -procedure TForm1.PythonEngine1SysPathInit(Sender : TObject; PathList : PPyObject); -var - folder : PPyObject; -begin - with GetPythonEngine do - begin - folder := PyString_FromString('c:\myapp\mymodules'); - PyList_Append(PathList, folder); - Py_XDecRef(folder); - end; -end; - - * fixed a bug: when using a Python iterator, eventhough you caught the stop exception, a 'Stop iteration' message was displayed in the output. - - * added function iter to VarPyth.pas that will return an iterator object for the specified container argument. - Example: -var - _iter : Variant; - _value : Variant; -begin - _iter := iter(VarPythonCreate([1, 2, 3, 4], stTuple)); - try - while True do - begin - _value := iter.next(); - [...] - end; - except - on E: EPyStopIteration do - begin - // End of sequence - end; - end; -end; - - * added PyDict_Copy api - - * added overloaded ExecStrings/EvalStrings methods that let you provide your own global/local dictionaries. - Note that you can still use the TPythonEngine properties LocalVars and GlobalVars. - - * added demo27 showing the possibilities of container indexing: -#index: -s[0] -#slice -s[0:2] -#ellipsis -s[...] -#extended slice -s[0:2:2] -#multidimensional slice: -s[10, 10:20, 20:100:5, ...] - - * added demo28 showing how to implement an iterator over a sequence (a simple TStringList wrapper) - - * added support for Delphi 2005 ----------------------------------------------------------------------- -3.28 23/04/2005 - - * Fixed a bug in PyObjectAsVariant thanks to Kiriakos Vlahos [kvlahos@london.edu] - Testing for Boolean values should be done before Integer values, as Boolean inherit from Integers. - - * Fixed a bug in ArrayToPyTuple, ArrayToPyList and ArrayToPyDict when giving empty string as argument - thanks to Dietmar Budelsky. - - * Added demo 29 showing how to exchange images between Delphi and Python Imaging Library (PIL). - - * In PythonEngine.pas, added APIs: - - PyObject_Call - - PyErr_SetInterrupt - - * Added new feature to VarPyth: you can now invoke functions or methods using named parameters. - A big advantage of named parameters over regular parameters is that the order of parameters is not important - and help invoking functions with many optional parameters, as you can only specify the one you need. - Note that any Python function can be invoked with or without named parameters, and that you can mix regular and named parameters. - -Python code: -def MakeList(a, b, c): - return [a, b, c] - -Delphi code: -var - _main : Variant; - L : Variant; -begin - _main := MainModule; - L := _main.MakeList(1, 2, 3); // L = [1, 2, 3] (this is the old way) - L := _main.MakeList(1, c := 3, b := 2); // L = [1, 2, 3] Note that you can mix regular and named parameters. - L := _main.MakeList(c := 3, a := 1, b := 2); // L = [1, 2, 3] Only named parameters - - * Added Demo30 to show how you can use named parameters. - - * Added Project PythonIDE thanks to a donation of Kiriakos Vlahos [kvlahos@london.edu]. - PyScripter was not designed to compete with other Python IDE tools - but rather to serve the purpose of providing a strong scripting - solution for Delphi Applications. However it is a reasonably - good stand-alone Python IDE. - - Features: - - - Easy Integration with Delphi applications - - Syntax Highlighting - - Brace Highlighting - - Python source code utilities ((un)tabify, (un)comment, (un)indent) - - Code Explorer - - File Explorer with filter - - Easy configuration and browsing of the Python Path - - Access to Python manuals through the Help menu - and context sensitive help (press F1 on a Python keyword - inside the editor) - - Integrated Python Interpreter - - Command History - - Alt-UP : previous command - - Alt-Down : next command - - Esc : clear command - - Code Completion - - Call Tips - - Integrated Python Debugging - - Debug Windows - - Call Stack - - Variables Window - - Watches Window - - BreakPoints Window - - Modern UI with docked forms - - Persistent configurable IDE options - - Note that P4D only contains PythonIDE source code, but you can download a compiled version from - http://mmm-experts.com/Downloads.aspx?ProductId=4 - - If you want to rebuild it by yourself, you'll need to look at PythonIDE\Readme.txt for the required - component packages. - - * Flagged GetAtom of PythonAtom.pas and TAtomPythonEngine of AtomPythonEngine.pas as deprecated when - using Delphi 6 or later. - You should replace TAtomPythonEngine by TPythonEngine and PythonAtom.pas by VarPyth.pas. - - Note that VarPyth and PythonAtom act differently. So, simply changing the unit may compile but - your application may crash at runtime because PythonAtom converts Python sequences into variant arrays - for instance, whereas VarPyth will keep the Python sequence object and let you act on it. - See discussions in the yahoo group and Andy's tutorial about latest techniques: - http://www.atug.com/andypatterns/PythonDelphiLatest.htm - - Converting TAtomPythonEngine is easy: open the form or datamodule hosting the component, - View as text (Alt + F12), replace TAtomPythonEngine by TPythonEngine, View as Form (Alt + F12), - in the unit, replace TAtomPythonEngine by TPythonEngine nad replace AtomPythonEngine by PythonEngine (in the uses). - Save. - - Note that eventhough you get a deprecated warning, it still works as it is and you're not required to do the change. - It's only better to do it for the future and for the additional benefits of VarPyth... - - * Updated file 'Deploying P4D.pdf' to refer to the Python tool that helps collect all module dependencies. - ----------------------------------------------------------------------- -3.29 28/08/2005 - - * Fixed bug in TPythonType, reported by Roar Larsen [roar@tordivel.no], where a Access Violation would occur - when exceeding 10 methods/getsets/members in a new base type (tpfBaseType option). - - * Fixed bug found by daydaysy [ildg@163.com] where VarIsPythonClass would - return False when checking a new style Python class inheriting from object (class Foo(object): pass). - - * Used exported API for function PyImport_ExecCodeModule instead of duplicating code - - * Added APIs PyObject_GetIter, PyIter_Next and PyIter_Check to TPythonEngine - - * Added changes sent by Chris Nicolai <nicolaitanes@gmail.com>: - added PyThreadState_SetAsyncExc -- throw an exception into _another_ thread!! - added new PyThreadState members from Python2.3 - - * Addew new virtual class procedure SetupType to TPyObject, allowing the class to - setup its associated Python type. This is very useful when building a hierarchy of classes, - and thus avoiding copy&paste of the type services for each TPythonType. Instead, setup the type - in the base class, and introduce in the subclasses the new services when they're implemented. - - * Added methods AddMethodWithKeywords/AddDelphiMethodWithKeywords to TPythonModule and TPythonType, - allowing you to create functions receiving keyword parameters: foo(param1=val1, param2=val2...) - - * Added function VarPythonIsIterator to VarPyth.pas (and rewrote functions len and iter) - - * Added new component TPyDelphiWrapper originally written and donated by Kiriakos Vlahos [kvlahos@london.edu] - It allows you to interact with Delphi VCL objects from Python. It works with Delphi5 or above. - It also helps expose your own Delphi classes to Python more easily with Delphi 7 or later. - - Look at the documentation embedded at the beginning of the WrapDelphi.pas unit. - - * Added Demos 31 and 32 that show how you can benefit from WrapDelphi. - - * Added support for Free Pascal Compiler (http://www.freepascal.org/) - and Lazarus Project (http://www.lazarus.freepascal.org/) - Thanks to Michiel du Toit (micdutoit@hsbfn.com) - - * Added new folder "Modules" containing the folder "Delphi" which contains a Dll project for building - a Python .pyd module in order to expose the VCL to a regular Python interpreter. - Modules also constains a very simple Python script relying on Delphi.pyd for displaying a simple form. - Note that you must ensure that Delphi.pyd is accessible from the Python path, before trying to run - TestApp.py - ----------------------------------------------------------------------- -3.30 18/12/2005 - - * Added function VarModuleHasObject to VarPyth.pas (done by Dietmar) to check if a module contains a specific object. - * Fixed Bug in P4D that would prevent a script from printing unicode strings. - * Made breaking change to TPythonEngine: the pyio module which is used to redirect input/output - is not imported any more (pyio = __import__("pyio")) to avoid polluting the list of - imported module (change made by Kiriakos Vlahos). - * Included new release 1.3 of PyScripter source code. - * Updated WrapDelphi: - - Added new unit WrapDelphiWindows (to define a couple of symbols only) - - Added new unit WrapDelphiComCtrls - - Added new unit WrapDelphiGrids - - Added new unit WrapDelphiGraphics - - Added new unit WrapDelphiButtons - - Wrapped TSize - - Wrapped TCanvas, TGraphic, TBitmap, TMetaFile, TIcon, TPicture - - Wrapped TKeyPressEvent, TKeyEvent - - Made a breaking change when dealing with property sets: - now we expect a sequence of strings. Each string should have the name as the enumeration in the set. - Ex: MainForm.Anchors = ['akLeft', 'akTop'] - Of course, a set property will now return a list of strings. - In the past, it would have returned an integer containing all the bits of the set, - and it would have accepted to assign either the same kind of integer value or - a string like "[akLeft, akTop]". - - Made a breaking change when dealing with property enumerations: - return a string representing its value instead of the ordinal value. - - You don't need to call explicitely RegisterClass for your registered Python types as it will be done - automatically for you in RegisterDelphiWrapper. But it is still usefull if you need to create VCL objects - that have no wrapper, using the CreateComponent helper function. - - Thanks to Fabio Chelly who used WrapDelphi, reported errors and contributed. - ----------------------------------------------------------------------- -3.31 5/3/2006 - - * Added support for Delphi 2006 - * Updated WrapDelphi: - - Wrapped TPageControl - - Wrapped TTabSheet - * Fixed a very rare but nasty bug thanks to Samuel Iseli - Vertec AG [samuel.iseli@vertec.ch] - On some Windows Server 2003 machines, a P4D application using custom Types or Modules would - crash. After investigation, Samuel found out that this was related to a Bios feature - that would prevent code from running when the code was located on a memory page that was - not flagged as executable. This was the case for all the generated callbacks that would - wrap Delphi methods. After looking at Borland's solution regarding the MakeObjectInstance code - we knew that we had do a VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE). - Samuel wrote a simple memory allocator using pages of virtual alloc, and replaced the old - GetMem/FreeMem calls. And we could also get rid of the list of created callbacks as we have - now our own custom allocator, which should speed up application's exit as we can free pages - instead of blocks. - * Simplified PythonEngine.pas to take into account an excellent suggestion of Samuel Iseli: - the TPythonType was registering callbacks for each type's service, where the type's method - would simply forward the work to the TPyObject instance. Instead of using callbacks, - we can now use simple static functions which should also speed up a P4D application a little. - * Added version 1.5 of PyScripter source code. - - ----------------------------------------------------------------------- -3.32 8/10/2006 - - * Added support for loading the Python 2.5. No change was introduced yet to take into account - the 2.5 specificity. - I had to disable the following 2 APIs which are not exported anymore: PyRange_New and PySymtableEntry_Type. - I removed the exception PyExc_OverflowWarning. - I added EPyBaseException exception and changed the hierarchy to reflect latest changes: - -BaseException # New in Python 2.5 -|- KeyboardInterrupt -|- SystemExit -|- Exception - |- (all other current built-in exceptions) - - - * Introduced a potential breaking change to P4D: the conditional symbol PREFER_UNICODE is now defined - by default. Which means that any string stored in a variant will be converted to a Python unicode string. - If you don't want that, then make sure that this symbol is not defined in definition.inc - Note also that PyString_Check has been modified to accept unicode strings. If you want to - discriminate, use PyString_CheckExact. - * Kiriakos made changes to TPythonInputOutput to allow wide strings in I/O and thus support - international chars. It introduces 2 news events OnSendUniData/OnReceiveUniData. - This new behaviour will be activated only if you define the PREFER_UNICODE symbol and set - the new UnicodeIO property. - * Fixed bug into the new callback allocator thanks to Samuel Iseli. In some very rare cases, - the empty space of a memory page was wrong and could crash the application. - * Fixed a bug into TPythonEngine.PyObject_AsVariant that prevented a date to be converted - to a real date variant. It was considered as a float, thanks to Oliver Bock <oliver@g7.org>. - * Fixed a bug in TPythonEngine.PyObjectAsString when the submitted object is a unicode string. - * Added api PySeqIter_New to TPythonEngine - * Added api PyObject_CallMethodStr and PyObject_CallMethodWithArgs to TPythonEngine - thanks to Dietmar Budelsky. - * Added methods Repaint and Invalidate to the TControl wrapper - * Added package files for C++Builder 6 thanks to Philippe BOURGAULT - * Created a Wiki at http://py4d.pbwiki.com/ thanks to a suggestion of Oliver Bock - This will allow any person involved with P4D to collaborate on building - a useful documentation (at last ;-) - * Added methods ClientToScreen and ScreenToClient to the TControl wrapper thanks to Joachim. - * Added changes made by Samuel Iseli to WrapDelphiGrids: - I added an indexed property for setting column widths (ColWidths[i]) and methods to get / set cell contents of stringgrid to the gridwrapper. - I thought it was easier to do the cell get/set with separate methods GetCell(col,row), SetCell(col, row, value) instead of trying to imitate the Delphi 2dim array property (Cells[col, row]). - * Made fields fDefaultIterType and fDefaultContainerType of TPyDelphiWrapper protected as a - request made by Samuel Iseli. - * Added new property "Version" to TPythonEngine returning the current version of P4D as a string as a - request made by Roar Larsen. diff --git a/doc_original/Deployment.txt b/doc_original/Deployment.txt deleted file mode 100644 index adc9391..0000000 --- a/doc_original/Deployment.txt +++ /dev/null @@ -1,19 +0,0 @@ -See document "Deploying P4D.PDF" first. - -When you want to distribute your Delphi application using Python, -here's what you have to do: -- install the whole Lib directory of the standard Python distribution -(i.e. c:\program files\Python\Lib) -This folder is necessary for the exceptions.py module that defines the Exception -objects, if you're using them. -Note that the file exceptions.py does not exist any more with versions of Python -equal or greater than 2.0 -- optionally install the whole DLLs directory of the standard Python distribution -(i.e. c:\program files\Python\DLLs) -- install the python15.dll in the system folder -- In your application, use the OnPathInitialization of the TPythonEngine -and define the path with the Lib and DLLs folders you have installed. Add your -own folders that contain your python modules. -Note that each folder must be separated with a semi-colon (;) in the path string. - -That's all ! diff --git a/doc_original/Readme.txt b/doc_original/Readme.txt deleted file mode 100644 index 6b99b7f..0000000 --- a/doc_original/Readme.txt +++ /dev/null @@ -1,137 +0,0 @@ -############################################################## -## This is the Python for Delphi project ## -############################################################## - -AUTHORS: -~~~~~~~~ -Dr. Dietmar Budelsky - dbudelsky@web.de - -Morgan Martinet - 4723, Brebeuf - H2J 3L2 MONTREAL (QC) - CANADA - - e-mail: p4d@mmm-experts.com - - -This project is the result of the merging of their two separate projects. - -PURPOSE: -~~~~~~~~ - Provide an interface to the Python language in Delphi. - -COPYRIGHT: -~~~~~~~~~~ - This source code is distributed with no WARRANTY, for no reason or use. - Everyone is allowed to use and change this code free for his own tasks - and projects, as long as this header and its copyright text is intact. - For changed versions of this code, which are public distributed the - following additional conditions have to be fullfilled: - 1) The header has to contain a comment on the change and the author of it. - 2) A copy of the changed source has to be sent to one of the above E-Mail - addresses or our then valid address, if this is possible to the - author. - The second condition has the target to maintain an up to date central - version of the components. If this condition is not acceptable for - confidential or legal reasons, everyone is free to derive components - or to generate a diff file to our or other original sources. - -FILES: -~~~~~~ - Readme.txt This file. - Python.txt Infos about Python, and further references. - Changes.txt List of all changes since the first release. - Tutorial.txt A simple tutorial to use the PythonEngine - To do.txt A to do list. - Deploying P4D.pdf Notes on the Deployment of your applications using Python for Delphi. - C++ Builder Notes.txt Notes on using C++Builder with the Python for Delphi components. - PythonAtom.hlp A help file explaining the use of TPythonAtom - Demos A folder containing several demos of Python for Delphi. - Components\Python.* The "Python for Delphi" packages. - Components\Sources\Core The source folder of the core "Python for Delphi". - Lib Library of Python modules. - PythonIDE A Python developpment environment written in Delphi. - See PythonIDE\Readme.txt for the required components. - Modules Contains the Delphi\Delphi.dpr project that creates the Modules\Delphi.pyd Python module - that allows you to interact with Delphi VCL objects from Python. - -INSTALLATION: -~~~~~~~~~~~~~ - install the Python for Windows distribution (http://www.python.org/). - - 1) Install the core components - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - For Delphi 3, install the "Python_d3" package located in the Components folder - and add the folder "...\Components\Sources\Core". - - For Delphi 4, install the "Python_d4" package located in the Components folder - and add the folder "...\Components\Sources\Core". - - For Delphi 5, install the "Python_d5" package located in the Components folder - and add the folder "...\Components\Sources\Core". - - For Delphi 6, install the "Python_d6" package located in the Components folder - and add the folder "...\Components\Sources\Core". - - For Delphi 7, install the "Python_d7" package located in the Components folder - and add the folder "...\Components\Sources\Core". - - 2) Install the VCL components (this is optional) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - For Delphi 3, install the "PythonVCL_d3" package located in the Components folder - and add the folder "...\Components\Sources\VCL". - - For Delphi 4, install the "PythonVCL_d4" package located in the Components folder - and add the folder "...\Components\Sources\VCL". - - For Delphi 5, install the "PythonVCL_d5" package located in the Components folder - and add the folder "...\Components\Sources\VCL". - - For Delphi 6, install the "PythonVCL_d6" package located in the Components folder - and add the folder "...\Components\Sources\VCL". - - For Delphi 7, install the "PythonVCL_d7" package located in the Components folder - and add the folder "...\Components\Sources\VCL". - - 3) Build PythonIDE (This is optional) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - You can download the latest build of this application from - http://mmm-experts.com/Downloads.aspx?ProductId=4 - - If you want to rebuild PythonIDE by yourself, you must look at PythonIDE\Readme.txt - for the required component packages to install first. - - - 3) Build Modules\Delphi\Delphi.dpr (This is optional) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Once the project is build you can either extend the Python path with ..\Modules or - copy ..Modules\Delphi.pyd to C:\Python24\DLLs, to be able to import the Delphi module - from Python. - - Note that you can try this module by invoking the ..\Modules\TestApp.py script. - -NOTE: -~~~~~ - Don't forget to look at the tutorial file (tutorial.txt) which introduces the - demos. - - Visit the site http://starship.python.net/crew/mhammond/ and get the last version - of Pythonwin. It's a really good Python IDE, that you must have for serious - Python programming and debugging ! - -UPDATE: -~~~~~~~ - You'll find the latest version at http://mmm-experts.com/ - -DISTRIBUTION: -~~~~~~~~~~~~~ - You are free to distribute your applications built with Python for Delphi, - but don't forget to install the python15.dll in the window\system folder of - your client, or install the Python for windows distribution (it needs more - space on the harddisk, but it's better because there are all Python modules - and the help). diff --git a/doc_original/Tutorial.txt b/doc_original/Tutorial.txt deleted file mode 100644 index a3a3824..0000000 --- a/doc_original/Tutorial.txt +++ /dev/null @@ -1,840 +0,0 @@ -Using Python components. -Here's a simple tutorial, each step is linked to a demo project (demoXXX) -located in the Demos folder. - --------------------------------------------------------------- -1) A simple Python evaluator: (Kylix ready) --------------------------------------------------------------- - Create a new Form - Drop a TMemo (or a TRichEdit) - Drop a TPythonGUIInputOutput for displaying Python's messages - Drop a TMemo for the source code - Drop a TPythonEngine - Connect the attribute IO of the TPythonEngine to the TPythonGUIInputOutput. - Connect the attribute Output of TPythonGUIInputOutput to the TRichEdit. - Drop a TButton and call it "Execute script" - Double-click on the button and add: - PythonEngine1.ExecStrings( Memo1.Lines ); - That's all ! - Compile and execute. - Write in the Memo1: print 2+2 - Click on the Execute button - You should see in the Output window: 4 - --------------------------------------------------------------- -2) Evaluate a Python expression (Kylix ready) --------------------------------------------------------------- - WARNING !!! The evaluation of an expression works only for arithmetic expressions - and not for instructions ! The use of variables and functions is of course allowed - but constructs like for, def, class, print, import... are not allowed. - Use Exec... instead (like ExecStrings). - - Create a new Form - Drop a TMemo (or a TRichEdit) - Drop a TPythonGUIInputOutput for displaying Python's messages - Drop a TMemo for the source code - Drop a TPythonEngine - Connect the attribute IO of the TPythonEngine to the TPythonGUIInputOutput. - Connect the attribute Output of TPythonGUIInputOutput to the TRichEdit. - Drop a TButton and call it "Evaluate script" - Double-click on the button and add: - var - Result : PPyObject; - begin - with PythonEngine1 do - begin - Result := EvalStrings( Memo1.Lines ); - if Assigned(Result) then - begin - ShowMessage(Format('Eval: %s',[PyObjectAsString(Result)])); - Py_DECREF(Result); - end - else - ShowMessage('Could not evaluate the script'); - // Or you could simply use: - // ShowMessage('Eval: ' + EvalStringsAsStr( Memo1.Lines ) ); - end; - That's all ! - Compile and execute. - Write in the Memo1: print 2+2 - Click on the Execute button - You should see in the Output window: 4 - --------------------------------------------------------------- -3) Defining Python/Delphi vars (simple case): (Kylix ready) --------------------------------------------------------------- - Warning ! If you access the Python/Delphi vars with - the variant interface, you'll have to use simple types - like integers, floats or strings. - If you want to use any Python object type, don't use - variants, but use the Extended interface OnExtGetData, OnExtSetData - and the ValueObject property. But in this case, be careful with the - reference counting ! Study carefully the Demo4 example. - - - Drop a TPythonDelphiVar - Connect its Engine attribute to PythonEngine1 - Change the name of the variable in the VarName attribute and set it to "test". - Drop a Button and call it "Show var content" - Double-click on it, and add: - ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString ); - - Run the application, and type in the source window: - varname.Value = 10 - print varname, varname.Value - Click on the Execute button - Click on the "Show var content button" - - So, you can read/write the variable's content in both Python and Delphi ! - --------------------------------------------------------------- -4) Defining Python/Delphi vars (advanced case): (Kylix ready) --------------------------------------------------------------- - Warning ! If you access to the Python/Delphi vars with - the variant interface, you'll have to use simple types - like integers, floats or strings. - If you want to use any Python object type, don't use - variants, but use the Extended interface OnExtGetData, OnExtSetData - and the ValueObject property. But in this case, be careful with the - reference counting ! Study carefully the Demo4 example. - - Use what you did at 3) - Drop a TEdit component - Click on the PythonDelphiVar1 object, show its events - Double-click on the OnGetData attribute, and add: - Data := Edit1.Text; - Double-click on the OnSetData attribute, and add: - Edit1.Text := Data; - Double-click on the OnChange attribute, and add: - with Sender as TPythonDelphiVar do - ShowMessage( 'Var test changed: ' + ValueAsString ); - Add the following line to the private section: - FMyPythonObject : PPyObject; - Drop a TPythonDelphiVar - Connect its Engine attribute to PythonEngine1 - Change the name of the variable in the VarName attribute and set it to "object". - Double-click on the OnExtGetData attribute, and add: - with GetPythonEngine do - begin - Data := FMyPythonObject; - Py_XIncRef(Data); // This is very important - end; - Double-click on the OnExtSetData attribute, and add: - with GetPythonEngine do - begin - Py_XDecRef(FMyPythonObject); // This is very important - FMyPythonObject := Data; - Py_XIncRef(FMyPythonObject); // This is very important - end; - - Run the application, and type in the source window: - print "Current value of var test is: ", varname - varname.Value = "New value set by Python" - print "-----------------------------------------------------" - class C: - def __init__(Self, Arg): - Self.Arg = Arg - def __str__(Self): - return "<C instance contains: " + str(Self.Arg) + ">" - print "Current value of var object is: ", object - object.Value = C("Hello !") - print "New value is:", object - Click on the Execute button, and look at the Edit1 component. - --------------------------------------------------------------- -5) Defining a new Module: (Kylix ready) --------------------------------------------------------------- - Drop a TPythonModule - Connect its Engine attribute to PythonEngine1 - Change the ModuleName attribute to "spam" - Select its events, and Double-click on "OnInitialization" and add: - with Sender as TPythonModule do - AddMethod( 'foo', spam_foo, 1, 'foo' ); - Before the PythonModule1Initialization procedure, add: - function spam_foo( self, args : PPyObject ) : PPyObject; cdecl; - begin - with GetPythonEngine do - begin - ShowMessage( 'args of foo: '+PyObjectAsString(args) ); - Result := Py_None; - Py_IncRef(Result); - end; - end; - - Run the application, and type in the source window: - import spam - print spam.foo( "Hello", 1 ) - Click on the Execute button, and look at the Message dialog. - --------------------------------------------------------------- -6) Defining a new Type: (Kylix ready) --------------------------------------------------------------- - A new type is more complex, because you must define a record - that contains the objects attributes. It must always contain - the two attributes at first: - ob_refcnt : Integer; - ob_type : PPyTypeObject; - Drop a TPythonType - Connect its Engine attribute to PythonEngine1 - Change the TypeName attribute to "MyObject" - You must define procedures that will handle all kind of access - to the object: Destructor, Get attribute, Set attribute, print... - You must define its own methods - You'll need a function in a module that will create an - instance of that object. - You must set the attributes of the Type record. - Add the Objects's methods to the PythonType. - - Look at the demo6 for more information about this. - There's a complete implementation of a new type - object "Point", which contains two attributes (x and y), - and one method (OffsetBy). - The object is created by the function CreatePoint of - the spam module. - --------------------------------------------------------------- -7) Using Delphi methods as Python functions (Kylix ready) --------------------------------------------------------------- - This demo is the same as the previous one (6) but it introduces - the use of Delphi methods instead of global functions for the - python functions of Modules or Types. - - Note: Look at (21) for the new Events feature, which will ease the - declaration of new Python functions. - --------------------------------------------------------------- -8) Using Delphi classes for new Python types (Kylix ready) --------------------------------------------------------------- - Warning for Python version below 2.0: - Python must be correctly installed otherwise this demo - will fail. It needs indeed the file exceptions.py - located in the lib folder of the Python distribution - in order to initialize correctly the Exceptions as - Python objects instead of strings. - If you want to distribute your application with the - Python Dll, don't forget to copy this file (and maybe the - whole lib folder) and use the event OnPathInitialization - of TPythonEngine to initialize properly your Python - environment. - - Note: Look at (21) for the new Events feature, which will ease the - declaration of new Python methods. - - Note: Loot at (26) if you're interested in building a new type that - may be subclassed inside Python. - - Note: Look at (32) if you're using Delphi7 or later as it can make - your life much easier when trying to expose a regular Delphi - class to Python. See also the WrapDelphi.pas unit. - - Look at demo8, it's a default template that yous should follow - if you want to build new Python types. - Create a new project. - Drop a TRichEdit - Drop a TPythonGUIInputOutput for displaying Python's messages - Drop a TPythonEngine on the form. - Connect the attribute IO of the TPythonEngine to the TPythonGUIInputOutput. - Connect the attribute Output of TPythonGUIInputOutput to the TRichEdit. - Drop a TMemo - Drop a TButton - Double click on it and add: - PythonEngine1.ExecStrings( Memo1.Lines ); - Drop a TPythonModule - Change its property "ModuleName" to "spam" - Connect it to the PythonEngine1 - Double-click on the property "Errors" - Add an error - name it "PointError" - set it to etClass - Add an error - name it "EBadPoint" - set it to etClass - Double-click on "ParentClass" - Set Name to "PointError" - Drop a TPythonType - Connect it to the PythonEngine1 - Change the property "TypeName" to "Point" - Connect the property "Module" to the PythonModule1 - Define the services you'll use in the property "Services" - Double-click on its event "OnInitialization" and add: - PythonType1.PyObjectClass := TPyPoint; - Add this code to the interface section of the unit: - // This is a Delphi class implementing a new Python type - // it must derive from TPyObject or one of its descendants. - // Then it must override some methods, like the constructors, - // the RegisterMethods and the type services' virtual methods. - TPyPoint = class(TPyObject) - x, y : Integer; - - // Constructors & Destructors - constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override; - - // Type services - //////////////// - - // Basic services - function GetAttr(key : PChar) : PPyObject; override; - function SetAttr(key : PChar; value : PPyObject) : Integer; override; - function Repr : PPyObject; override; - - // Class methods - class procedure RegisterMethods( PythonType : TPythonType ); override; - - // Methods of TPyPoint - procedure OffsetBy( dx, dy : Integer ); - - // Interface methods - function DoOffsetBy( args : PPyObject ) : PPyObject; cdecl; - function DoRaiseError( args : PPyObject ) : PPyObject; cdecl; - end; - - Add this code to the implementation section of the unit: - - // We override the constructors - - constructor TPyPoint.Create( APythonType : TPythonType ); - begin - inherited; - x := 0; - y := 0; - end; - - // Don't call the Create constructor of TPyPoint, because - // we call the inherited constructor CreateWith that calls - // the Create constructor first, and because the constructors - // are virtual, TPyPoint.Create will be automatically be called. - - constructor TPyPoint.CreateWith( PythonType : TPythonType; args : PPyObject ); - begin - inherited; - with GetPythonEngine do - begin - if PyArg_ParseTuple( args, 'ii:CreatePoint', [@x, @y] ) = 0 then - exit; - end; - end; - - // Then we override the needed services - - function TPyPoint.GetAttr(key : PChar) : PPyObject; - begin - with GetPythonEngine do - begin - if key = 'x' then - Result := PyInt_FromLong( x ) - // Or Result := PyInt_FromLong( x ) - else if key = 'y' then - Result := PyInt_FromLong( y ) - // Or Result := PyInt_FromLong( y ) - else - Result := inherited GetAttr(key); - end; - end; - - function TPyPoint.SetAttr(key : PChar; value : PPyObject) : Integer; - begin - Result := 0; - with GetPythonEngine do - begin - if key = 'x' then - begin - if PyArg_Parse( value, 'i:Point.SetAttr', [@x] ) = 0 then - Result := -1; - end - else if key = 'y' then - begin - if PyArg_Parse( value, 'i:Point.SetAttr', [@y] ) = 0 then - Result := -1; - end - else - Result := inherited SetAttr(key, value); - end; - end; - - function TPyPoint.Repr : PPyObject; - begin - with GetPythonEngine do - Result := PyString_FromString( PChar(Format('(%d, %d)',[x, y])) ); - // or Result := PyString_FromString( PChar(Format('(%d, %d)',[x, y])) ); - end; - - // Class methods - // We register the methods of our type - - class procedure TPyPoint.RegisterMethods( PythonType : TPythonType ); - begin - inherited; - with PythonType do - begin - AddMethod( 'OffsetBy', @TPyPoint.DoOffsetBy, 'Point.OffsetBy( dx, dy )' ); - AddMethod( 'RaiseError', @TPyPoint.DoRaiseError, 'Point.RaiseError()' ); - end; - end; - - // Methods of TPyPoint - // They do the real actions on the object - // It's better to split the functions that interface - // Delphi to Python and the functions that do the - // real implementation. - - procedure TPyPoint.OffsetBy( dx, dy : Integer ); - begin - Inc( x, dx ); - Inc( y, dy ); - end; - - // Interface methods - // They will be called directly by Python, so we extract the - // python arguments and we call the method that will really do - // the action. - - function TPyPoint.DoOffsetBy( args : PPyObject ) : PPyObject; - var - dx, dy : Integer; - begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // first we extract the arguments - if PyArg_ParseTuple( args, 'ii:Point.Offset', [@dx, @dy] ) <> 0 then - begin - // if it's ok, then we call the method that does the job - // with the correct arguments - OffsetBy( dx, dy ); - // Finally, we return nothing - Result := ReturnNone; - end - else // the arguments were not right - Result := nil; - end; - end; - - // Here's an example of how you can raise errors defined - // in the module linked to our type. - function TPyPoint.DoRaiseError( args : PPyObject ) : PPyObject; - begin - with GetPythonEngine do - begin - // We adjust the transmitted self argument - Adjust(@Self); - // This is a simple call: - //GetModule.RaiseError( 'PointError', 'this is an example of raising an error !' ); - // This is an advanced call: - // We provide the instance vars as a dictionary, so that we can intercept the - // error with "except" and extract informations from the error object. - // ArrayToPyDict needs a list of pairs: varName (string), varValue (anything) - GetModule.RaiseErrorObj( 'EBadPoint', 'this is an example of raising an error !', - ArrayToPyDict( ['a', 1, 'b', 2, 'c', 3] ) ); - Result := nil; - end; - end; - - Compile and execute this application, then type in the memo - the following text and execute it: - import spam - p = spam.CreatePoint(2, 5) - print p - p.OffsetBy( 3, 3 ) - print p.x, p.y - print dir(spam) - print spam.Point - print "p = ", p, " --> ", - if type(p) is spam.Point: - print "p is a Point" - else: - print "p is not a point" - p = 2 - print "p = ", p, " --> ", - if type(p) is spam.Point: - print "p is a Point" - else: - print "p is not a point" - p = spam.CreatePoint(2, 5) - try: - print "raising an error of class EBadPoint" - p.RaiseError() # it will raise spam.EBadPoint - except spam.PointError, what: #it shows you that you can intercept a parent class - print "Catched an error derived from PointError" - print "Error class = ", what.__class__, " a =", what.a, " b =", what.b, " c =", what.c - - # You can raise error from a Python script to ! - print "------------------------------------------------------------------" - print "Errors in a Python script" - try: - raise spam.EBadPoint, "this is a test !" - except: - pass - - try: - err = spam.EBadPoint() - err.a = 1 - err.b = 2 - err.c = 3 - raise err - except spam.PointError, what: #it shows you that you can intercept a parent class - print "Catched an error dirived from PointError" - print "Error class = ", what.__class__, " a =", what.a, " b =", what.b, " c =", what.c - - - --------------------------------------------------------------- -9) Making a Python module as a Dll (Kylix ready) --------------------------------------------------------------- - The demo9 contains 2 delphi projects: one for the application - and one for the dll. The dll extension is renamed as ".pyd". - The application script does an "import demodll" that will try - to find first an internal module, then a "demodll.dll" or a - "demodll.pyd". - Python executes a procedure named initXXX in the dll, where - XXX must be the name of the module (in this case it will be - "demodll"). So, your dll must export only one procedure like this: - procedure initXXX; cdecl; - - In the function initXXX of our DLL, we create an instance of - TPythonEngine and we define its property "AutoFinalize" to False, - because TPythonEngine must absolutely not call the function - Py_Finalize. After you call its method LoadDll. - Then we create an instance of TPythonModule, we setup its name, - the engine used, add the methods and finally call Initialize. - At last, you add a finalize section in order to free the two instances. - - WARNING !!! Python cares about letter case, so check if the - resulting Dll is "demodll.pyd", all in lowercase, otherwise - the "import demodll" statement won't find the module. - --------------------------------------------------------------- -10) Mapping Delphi VCL components inside Python. --------------------------------------------------------------- - Full mapping of TTable and TQuery that lets you access - Database from inside Python as you would do it with Delphi. - - Look at the demo, I tried to put some comments and I think it is - self-explicit. - - It shows you how you can use Delphi class inheritence for - making new Python types and avoid duplication of code. - - It shows you how to use some special object services like - sequences. - - It shows you how you can subclass any Python object, using - a Proxy class (see example 6). - --------------------------------------------------------------- -11) Using Threads inside Python. (Kylix ready) --------------------------------------------------------------- - Demonstrates how you can execute python code that interacts with - Delphi in threads. - --------------------------------------------------------------- -12) Using PythonAtom. (Deprecated since Delphi 6, See VarPyth instead) --------------------------------------------------------------- - Look at Demo12 - - Simply add the PythonAtom in the uses clause, declare a new var of type OleVariant - and call the function getAtom( any Python object ). It will return a new OleVariant - that will let you access properties or methods very simply, as you would do with Word ! - - var - pObject : PPyObject; - myAtom : OleVariant; - myString : String; - begin - pObject := ... a python object ...(using a TPythonDelphiVar.ValueObject for example); - myAtom := getAtom(pObject); // This is the magic object - myAtom.myMethod(); - myString := myAtom.myProperty.myProperty2; - myAtom.myProperty.myProperty3:='Olivier'; - ShowMessage(myAtom.myMethod2('Olivier')); - ShowMessage(myAtom.myListProperty[3]); - // Or anything ! Note that type conversion are automatic ! - end; - - Note that if you use TPythonDelphiVar.ValueObject, you must decrement the reference on - the returned object ! - --------------------------------------------------------------- -13) Using TPythonDatabase. --------------------------------------------------------------- - Look at Demo13 - - This demo is based on the Demo10, but uses the TPythonDatabase - component that was built from the Demo10, in order to let - you easily access a Database from Python. - --------------------------------------------------------------- -14) Making a Dll with TPythonDatabase --------------------------------------------------------------- - - Here's how you can make a Dll that will contain the Database components - in order to let you access a database from any Python application, even - from the Python console ! - - Please, compile the database.dpr project prior to Project1.dpr ! - - If you want to use this module, from anywhere, you must copy the file - database.pyd in a folder that's in Python's path, like ...\Python\Lib - - WARNING !!! Python cares about letter case, so check if the - resulting Dll is "database.pyd", all in lowercase, otherwise - the "import database" statement won't find the module. - --------------------------------------------------------------- -15) Using a TDataset descendant with Python, except TTable and TQuery. --------------------------------------------------------------- - - If you're using a special Dataset object, like TClientDataset or - a FlashFiler table, this demo is for you ! - Note, that this will only allow you to use the TDataset interface and - not the methods introduced in the TDataset subclass ! If you need to, - then study the unit pyDBTables.pas and do the same as we do for a - TTable or a TQuery ! - - Add the pyDB unit to your uses clause. - In the module event OnAfterInitialization, of your dedicated module, - or simply just before you execute your instructions, do the following things: - - - Instanciate your Delphi dataset subclass: ds := TClientDataset.Create(nil); - - Initialize it properly: ds.DatabaseName := 'DBDemos'; - ds.TableName := 'animals.dbf'; - ds.Active := True; - - Create the Python interface: obj := NewDataset(ds, True) - where 'True' means that the Python wrapper will own the delphi dataset object and - free it. It avoids memory crashes if the TDataset subclass is destroyed - before the Python engine is finalized. If you encounter such a problem, - you can use the PythonEngine1.Finalize explicit method before any object is - destroyed in your form. - - Define a var containing our object : PythonModule1.SetVar( 'Dataset', obj ); - where PythonModule1 is the TPythonModule object you want to use - 'Dataset' is the var name in the module that will contain our dataset object - obj contains the Python object interface - - Don't forget to decrement 'obj': GetPythonEngine.Py_XDecRef(obj); - - This demo shows you how to add a function to your module, that will allow your - Python script to create its own instances of the Dataset subclass (look at the - DoCreateTable function). - --------------------------------------------------------------- -16) Using a TDelphiVar or Module methods ? (Kylix ready) --------------------------------------------------------------- - - Here are examples of 2 differents solutions that let you read/write properties stored - in your Delphi application (this examples were posted on the Python for Delphi - mailing list) : - - The first example uses a DelphiVar that contains a dictionary. - - The second example uses a new modules (props) that publishes 3 functions - GetProperty, SetProperty and GetPropertyList - - In both examples, I show you how you can simplify any implementation with a - Proxy class that will use either the DelphiVar or the module functions. - - --------------------------------------------------------------- -17) Using variant arrays of 2 dimensions (Kylix ready) --------------------------------------------------------------- - - This demo creates a variant array of 2 dimensions, then - converts it to a Python object (a list of sub lists) with - the method VariantAsPyObject. - The Python list is then converted back to a variant array with - PyObjectAsVariant, but notice that it is not an array of 2 dimensions, - but an array of variant arrays. - Because when PyObjectAsVariant converts a Python sequence it returns - a variant array and this method is recursive. So, if we have another - sequence as an item, we'll get an array that will be stored in the - array. - This way lets you have any depth of sub-sequences, but you can only - convert 1, 2 or 3 dimensions variant arrays to Python sequences. - --------------------------------------------------------------- -18) C++ Builder: using the Python Dll in a console application --------------------------------------------------------------- - -Create a new project application using the console -Edit the project options and adds the folder <INSTALLDIR>\Components\Include to -the Include directory. -Adds #include <python.h> at the beginning of your source -followed by: using namespace Py; -Drop the py15.lib to your project folder and add it to the project -Write Python code and compile ! - --------------------------------------------------------------- -19) C++ Builder: this is a replicate of the Delphi Demo05 --------------------------------------------------------------- - --------------------------------------------------------------- -20) C++ Builder: this is a replicate of the Delphi Demo08 --------------------------------------------------------------- - --------------------------------------------------------------- -21) Using Events in TPythonModule or TPythonType (Kylix ready) --------------------------------------------------------------- - -This demo is inspired of the demos 7 and 8, but uses the new feature of the TPythonModule -and TPythonType: now there's a collection property called Events, which lets you add -easily your own Module functions, or Type methods. -Simply double click on the Events property, then add a new CollectionItem, name your event, add -a DocString if you want to document your function, and double click on the OnExecute event, -then write the code to implement your function. That's all ! -Note the difference with a TPythonType: you don't use the Adjust procedure, put simply use the -PythonToDelphi function to convert the PSelf argument to a Delphi instance pointer. - --------------------------------------------------------------- -22) Using Threading, Windows Console and Command line arguments (Kylix ready) --------------------------------------------------------------- -When doing multithreading, be sure that the calling thread finishes after all created threads, -otherwise your application will hang ! This is easily done by using the threading module of the -standard Python distribution, and calling the "join" method of the thread objects. - -If you want to display messages in your threads, you can't use the PythonForDelphi redirection to -a memo, as the VCL is not thread safe ! -So, a simple way is to use the new TPythonEngine.UseWindowsConsole property which will use a -Windows threadsafe console. - -In this demo, we use the sys.argv list which contains the command line arguments. - -Note for Python 1.5.2: -if you're using the threading module, you should do a TPythonEngine.Finalize in the -OnClose event of your form, otherwise you'll get an access violation ! I don't know why ? -Because it works fine with new 1.6 version ! - --------------------------------------------------------------- -23) Using Threading and Delphi log window. (Kylix ready) --------------------------------------------------------------- -This is the same demo as Demo22, but we use the Delphi log window for displaying Python output, -instead of the Windows console. -The main advantage is that you can scroll the log window, and save its content to a file, -but the drawback is that you must run Delphi ! - -To do it, you must drop a TPythonInputOutput component (instead of the TPythonGUIInputOutput), -connect it to the TPythonEngine through the IO property, double-click on the TPythonInputOutput.OnSendData -event and write: - -procedure TForm1.PythonInputOutput1SendData(Sender: TObject; - const Data: String); -begin - OutputDebugString( PChar(Data) ); -end; - --------------------------------------------------------------- -24) Using TAtomPythonEngine (Deprecated since Delphi 6, See VarPyth instead) --------------------------------------------------------------- -This demo describes how you can make Delphi methods that are going to be -used from python without even thinking about conversion and reference -counting by the use of PythonAtoms and AtomPythonEngine. The Demo is a -modified version of Demo 5, but the techniques described here can be used -in aspects of python/delphi programming as well. - -The demo describes the use of the PyObjectAsVariant method defined in -AtomPythonEngine. It returns PythonAtoms when the Python object isn't of a -standard variant type (string, integer, array etc.). AtomPythonEngine is a -drop in for PythonEngine with all functionality inherited except for the -PyObjectAsVariant that is extended as stated above. - -The VariantAsPyObject of PythonEngine is also shown to work on -PythonAtoms. - --------------------------------------------------------------- -25) Using VarPyth.pas (Kylix ready) --------------------------------------------------------------- -Here's a unit test for demonstrating most of what you can do with the -new custom variant that wraps up the Python objects. - --------------------------------------------------------------- -26) Demo8 revisited to allow the new Python type to be subclassed --------------------------------------------------------------- -Warning! Type subclassing is allowed only in Python 2.2 and later. - - Note: Look at (32) if you're using Delphi7 or later as it can make - your life much easier when trying to expose a regular Delphi - class to Python. See also the WrapDelphi.pas unit. - -You should not override GetAttr and SetAttr anymore and you should not -select the Basic services flags [bsGetAttr, bsSetAttr]. -Instead, simply select the flags [bsGetAttrO, bsSetAttrO] and the class -TPyObject does simply call PyObject_GenericGetAttr in GetAttrO -and PyObject_GenericSetAttr in SetAttrO. -The Python Generic Get/Set functions will use new slots introduced in -the type object for specifying a list of members (class fields), -a list of get/set functions (like properties in Delphi) and a list -of methods. That way a subclass can introduce its own members/get,set/methods -and call the others coming from the base classes. - -So, now You can override the class methods RegisterMembers and RegisterGetSets -for allowing your type to be subclassed and offer attributes and -methods to its subclasses. - -This demo declares two members for x and y fields, and one get/set for -accessing the name fields which is a Delphi string and thus needs to -be converted from/to Python object. -The old way of registering methods has not changed at all. - --------------------------------------------------------------- -27) Container indexing --------------------------------------------------------------- -#index: -s[0] -#slice -s[0:2] -#ellipsis -s[...] -#extended slice -s[0:2:2] -#multidimensional slice: -s[10, 10:20, 20:100:5, ...] - --------------------------------------------------------------- -28) Iterator (Kylix ready) --------------------------------------------------------------- - -This demo implements a new container type wrapping a TStringList -and shows how to return an iterator that will browse the container's content. - --------------------------------------------------------------- -29) Using Python Imaging Library (PAL) --------------------------------------------------------------- - -This demo shows how to exchange images between Delphi and the -Python Imaging Library. -This demo relies on VarPyth.pas and thus on Delphi 6 or above. -You need also the library that you can get at: -http://www.pythonware.com/products/pil/ - --------------------------------------------------------------- -30) Using Named Parameters (Kylix ready) --------------------------------------------------------------- - -This demo shows how you can use named parameters when invoking Python functions or methods. -This requires VarPyth. -Look at the code in TForm1.Button1Click - --------------------------------------------------------------- -31) Using WrapDelphi to access Delphi Form attributes (Requires Delphi5 or later) --------------------------------------------------------------- - -This Demo shows how you expose a Delphi Form to Python, or your -own custom Delphi classes. -Note that it will use its full potential with Delphi7 or later. - --------------------------------------------------------------- -32) Demo08 revisited using WrapDelphi (Requires Delphi7 or later) --------------------------------------------------------------- - -This Demo shows how you can expose a Delphi class much simpler -using WrapDelphi. - --------------------------------------------------------------- -33) Using Threads inside Python II. --------------------------------------------------------------- -Enhanced Demo 11 showing how to properly interrupt running -threads. --------------------------------------------------------------- - - -That's all folks !!! -Hope this helps to build cool Python/Delphi applications. - -Morgan - diff --git a/doc_original/deploying p4d.pdf b/doc_original/deploying p4d.pdf deleted file mode 100644 index 735dfd1..0000000 Binary files a/doc_original/deploying p4d.pdf and /dev/null differ diff --git a/python4lazarus/Definition.Inc b/python4lazarus/Definition.Inc index 3cee703..6407265 100644 --- a/python4lazarus/Definition.Inc +++ b/python4lazarus/Definition.Inc @@ -22,198 +22,26 @@ (**************************************************************************) ///////////////////////////////////////////////////////////////////////////// -// Select a Python version by commenting out the corresponding line, or -// modify the default Python version below, in the Python versions section. +// Delphi, C++ Builder versions ///////////////////////////////////////////////////////////////////////////// -//{$DEFINE PYTHON25} -//{$DEFINE PYTHON26} -//{$DEFINE PYTHON27} -//{$DEFINE PYTHON32} -//{$DEFINE PYTHON33} -//{$DEFINE PYTHON34} -//{$DEFINE PYTHON35} -//{$DEFINE PYTHON36} -//{$DEFINE PYTHON37} -//{$DEFINE PYTHON38} - -///////////////////////////////////////////////////////////////////////////// -// Python for Delphi settings. Comment out the setting you want to enable. -///////////////////////////////////////////////////////////////////////////// - -{$DEFINE PREFER_UNICODE} // this will convert a variant containing an OleStr to a UniCode Python string. - -///////////////////////////////////////////////////////////////////////////// -// OS symbols. Note that MSWINDOWS is defined from Delphi6/Kylix. -///////////////////////////////////////////////////////////////////////////// - -{$IFNDEF MSWINDOWS} - {$IFDEF WIN32} - {$DEFINE MSWINDOWS} - {$ENDIF} -{$ENDIF} - -///////////////////////////////////////////////////////////////////////////// -// Delphi, C++ Builder and Kylix versions -///////////////////////////////////////////////////////////////////////////// - -{$IFDEF VER90} // Delphi 2.0 - {$DEFINE DELPHI2} -{$ENDIF} -{$IFDEF VER93} // C++ Builder 1.0 - {$DEFINE CBUILDER1} -{$ENDIF} -{$IFDEF VER100} // Delphi 3.0 - {$DEFINE DELPHI3} -{$ENDIF} -{$IFDEF VER110} // C++ Builder 3.0 - {$DEFINE CBUILDER3} - {$DEFINE DELPHI3_OR_HIGHER} - {$ObjExportAll On} -{$ENDIF} -{$IFDEF VER120} // Delphi 4.0 - {$DEFINE DELPHI4} - {$DEFINE DELPHI4_OR_HIGHER} -{$ENDIF} -{$IFDEF VER125} // C++ Builder 4.0 - {$DEFINE CBUILDER4} - {$DEFINE DELPHI4_OR_HIGHER} - {$ObjExportAll On} -{$ENDIF} -{$IFDEF VER130} // Delphi 5.0 - {$DEFINE DELPHI5} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$IFDEF BCB} { Borland C++Builder 5.0 } - {$DEFINE CBUILDER3} - {$DEFINE CBUILDER4} - {$DEFINE CBUILDER5} - {$ObjExportAll On} - {$ENDIF} -{$ENDIF} -{$IFDEF VER140} // Delphi 6.0 - {$DEFINE DELPHI6} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$IFDEF BCB} { Borland C++Builder 6.0 } - {$DEFINE CBUILDER3} - {$DEFINE CBUILDER4} - {$DEFINE CBUILDER5} - {$DEFINE CBUILDER6} - {$ObjExportAll On} - {$ENDIF} -{$ENDIF} -{$IFDEF VER150} // Delphi 7.0 - {$DEFINE DELPHI7} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} -{$ENDIF} -{$IFDEF VER160} // Delphi 8 - {$DEFINE DELPHI8} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} -{$ENDIF} -{$IFDEF VER170} // Delphi 2005 - {$DEFINE DELPHI2005} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} -{$ENDIF} -{$IFDEF VER180} // Delphi 2006 - {$DEFINE DELPHI2006} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} -{$ENDIF} -{$IFDEF VER190} // Delphi 2007 - {$DEFINE DELPHI2007} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} -{$ENDIF} -{$IFDEF VER200} // Delphi 2009 - {$DEFINE DELPHI2009} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} -{$ENDIF} {$IFDEF VER210} // Delphi 2010 {$DEFINE DELPHI2010} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$ENDIF} {$IFDEF VER220} // Delphi XE {$DEFINE DELPHIXE} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$ENDIF} {$IFDEF VER230} // Delphi XE2 {$DEFINE DELPHIXE2} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} {$ENDIF} {$IFDEF VER240} // Delphi XE3 {$DEFINE DELPHIXE3} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -221,15 +49,6 @@ {$ENDIF} {$IFDEF VER250} // Delphi XE4 {$DEFINE DELPHIXE4} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -238,15 +57,6 @@ {$ENDIF} {$IFDEF VER260} // Delphi XE5 {$DEFINE DELPHIXE5} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -256,15 +66,6 @@ {$ENDIF} {$IFDEF VER270} // Delphi XE6 {$DEFINE DELPHIXE6} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -275,15 +76,6 @@ {$ENDIF} {$IFDEF VER280} // Delphi XE7 {$DEFINE DELPHIXE7} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -295,15 +87,6 @@ {$ENDIF} {$IFDEF VER290} // Delphi XE8 {$DEFINE DELPHIXE8} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -316,15 +99,6 @@ {$ENDIF} {$IFDEF VER300} // Delphi 10 {$DEFINE DELPHI10} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -334,19 +108,10 @@ {$DEFINE DELPHIXE6_OR_HIGHER} {$DEFINE DELPHIXE7_OR_HIGHER} {$DEFINE DELPHIXE8_OR_HIGHER} - {$DEFINE DELPHIX10_OR_HIGHER} + {$DEFINE DELPHI10_OR_HIGHER} {$ENDIF} {$IFDEF VER310} // Delphi 10.1 - {$DEFINE DELPHI10.1} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} + {$DEFINE DELPHI10_1} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -357,19 +122,10 @@ {$DEFINE DELPHIXE7_OR_HIGHER} {$DEFINE DELPHIXE8_OR_HIGHER} {$DEFINE DELPHI10_OR_HIGHER} - {$DEFINE DELPHI10.1_OR_HIGHER} + {$DEFINE DELPHI10_1_OR_HIGHER} {$ENDIF} {$IFDEF VER320} // Delphi 10.2 - {$DEFINE DELPHI10.2} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} + {$DEFINE DELPHI10_2} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -380,20 +136,11 @@ {$DEFINE DELPHIXE7_OR_HIGHER} {$DEFINE DELPHIXE8_OR_HIGHER} {$DEFINE DELPHI10_OR_HIGHER} - {$DEFINE DELPHI10.1_OR_HIGHER} - {$DEFINE DELPHI10.2_OR_HIGHER} + {$DEFINE DELPHI10_1_OR_HIGHER} + {$DEFINE DELPHI10_2_OR_HIGHER} {$ENDIF} {$IFDEF VER330} // Delphi 10.3 - {$DEFINE DELPHI10.3} - {$DEFINE DELPHI4_OR_HIGHER} - {$DEFINE DELPHI5_OR_HIGHER} - {$DEFINE DELPHI6_OR_HIGHER} - {$DEFINE DELPHI7_OR_HIGHER} - {$DEFINE DELPHI8_OR_HIGHER} - {$DEFINE DELPHI2005_OR_HIGHER} - {$DEFINE DELPHI2006_OR_HIGHER} - {$DEFINE DELPHI2007_OR_HIGHER} - {$DEFINE DELPHI2009_OR_HIGHER} + {$DEFINE DELPHI10_3} {$DEFINE DELPHI2010_OR_HIGHER} {$DEFINE DELPHIXE_OR_HIGHER} {$DEFINE DELPHIXE2_OR_HIGHER} @@ -404,116 +151,86 @@ {$DEFINE DELPHIXE7_OR_HIGHER} {$DEFINE DELPHIXE8_OR_HIGHER} {$DEFINE DELPHI10_OR_HIGHER} - {$DEFINE DELPHI10.1_OR_HIGHER} - {$DEFINE DELPHI10.2_OR_HIGHER} - {$DEFINE DELPHI10.3_OR_HIGHER} -{$ENDIF} -///////////////////////////////////////////////////////////////////////////// -// Python versions -///////////////////////////////////////////////////////////////////////////// - -// Here we select a default Python version, if no version was explicitely specified. -// Note that the installer will let the user specify its default Python version, and -// thus will edit this file. - -{$IFNDEF PYTHON38} - {$IFNDEF PYTHON37} - {$IFNDEF PYTHON36} - {$IFNDEF PYTHON35} - {$IFNDEF PYTHON34} - {$IFNDEF PYTHON33} - {$IFNDEF PYTHON32} - {$IFNDEF PYTHON27} - {$IFNDEF PYTHON26} - {$IFNDEF PYTHON25} - {---<START OF DEFAULT PYTHON VERSION>---} - {$DEFINE PYTHON27} - {---<END OF DEFAULT PYTHON VERSION>---} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} - {$ENDIF} + {$DEFINE DELPHI10_1_OR_HIGHER} + {$DEFINE DELPHI10_2_OR_HIGHER} + {$DEFINE DELPHI10_3_OR_HIGHER} {$ENDIF} - -{$IFDEF PYTHON25} - {$DEFINE PYTHON25_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON26} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON27} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON32} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} - {$DEFINE PYTHON32_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON33} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} - {$DEFINE PYTHON32_OR_HIGHER} - {$DEFINE PYTHON33_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON34} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} - {$DEFINE PYTHON32_OR_HIGHER} - {$DEFINE PYTHON33_OR_HIGHER} - {$DEFINE PYTHON34_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON35} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} - {$DEFINE PYTHON32_OR_HIGHER} - {$DEFINE PYTHON33_OR_HIGHER} - {$DEFINE PYTHON34_OR_HIGHER} - {$DEFINE PYTHON35_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON36} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} - {$DEFINE PYTHON32_OR_HIGHER} - {$DEFINE PYTHON33_OR_HIGHER} - {$DEFINE PYTHON34_OR_HIGHER} - {$DEFINE PYTHON35_OR_HIGHER} - {$DEFINE PYTHON36_OR_HIGHER} -{$ENDIF} -{$IFDEF PYTHON37} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} - {$DEFINE PYTHON32_OR_HIGHER} - {$DEFINE PYTHON33_OR_HIGHER} - {$DEFINE PYTHON34_OR_HIGHER} - {$DEFINE PYTHON35_OR_HIGHER} - {$DEFINE PYTHON36_OR_HIGHER} - {$DEFINE PYTHON37_OR_HIGHER} +{$IFDEF VER340} // Delphi 10.4 + {$DEFINE DELPHI10_4} + {$DEFINE DELPHI2010_OR_HIGHER} + {$DEFINE DELPHIXE_OR_HIGHER} + {$DEFINE DELPHIXE2_OR_HIGHER} + {$DEFINE DELPHIXE3_OR_HIGHER} + {$DEFINE DELPHIXE4_OR_HIGHER} + {$DEFINE DELPHIXE5_OR_HIGHER} + {$DEFINE DELPHIXE6_OR_HIGHER} + {$DEFINE DELPHIXE7_OR_HIGHER} + {$DEFINE DELPHIXE8_OR_HIGHER} + {$DEFINE DELPHI10_OR_HIGHER} + {$DEFINE DELPHI10_1_OR_HIGHER} + {$DEFINE DELPHI10_2_OR_HIGHER} + {$DEFINE DELPHI10_3_OR_HIGHER} + {$DEFINE DELPHI10_4_OR_HIGHER} + {$IF RTLVERSION1042} + {$DEFINE DELPHI10_4_2} //Delphi 10.4.2 + {$ENDIF RTLVERSION1042} +{$ENDIF} +{$IFDEF VER350} // Delphi 11 + {$DEFINE DELPHI11} + {$DEFINE DELPHI2010_OR_HIGHER} + {$DEFINE DELPHIXE_OR_HIGHER} + {$DEFINE DELPHIXE2_OR_HIGHER} + {$DEFINE DELPHIXE3_OR_HIGHER} + {$DEFINE DELPHIXE4_OR_HIGHER} + {$DEFINE DELPHIXE5_OR_HIGHER} + {$DEFINE DELPHIXE6_OR_HIGHER} + {$DEFINE DELPHIXE7_OR_HIGHER} + {$DEFINE DELPHIXE8_OR_HIGHER} + {$DEFINE DELPHI10_OR_HIGHER} + {$DEFINE DELPHI10_1_OR_HIGHER} + {$DEFINE DELPHI10_2_OR_HIGHER} + {$DEFINE DELPHI10_3_OR_HIGHER} + {$DEFINE DELPHI10_4_OR_HIGHER} + {$DEFINE DELPHI11_OR_HIGHER} {$ENDIF} -{$IFDEF PYTHON38} - {$DEFINE PYTHON25_OR_HIGHER} - {$DEFINE PYTHON26_OR_HIGHER} - {$DEFINE PYTHON27_OR_HIGHER} - {$DEFINE PYTHON32_OR_HIGHER} - {$DEFINE PYTHON33_OR_HIGHER} - {$DEFINE PYTHON34_OR_HIGHER} - {$DEFINE PYTHON35_OR_HIGHER} - {$DEFINE PYTHON36_OR_HIGHER} - {$DEFINE PYTHON37_OR_HIGHER} - {$DEFINE PYTHON38_OR_HIGHER} +{$IFDEF VER360} // Delphi 12 + {$DEFINE DELPHI2010_OR_HIGHER} + {$DEFINE DELPHIXE_OR_HIGHER} + {$DEFINE DELPHI12} + {$DEFINE DELPHIXE2_OR_HIGHER} + {$DEFINE DELPHIXE3_OR_HIGHER} + {$DEFINE DELPHIXE4_OR_HIGHER} + {$DEFINE DELPHIXE5_OR_HIGHER} + {$DEFINE DELPHIXE6_OR_HIGHER} + {$DEFINE DELPHIXE7_OR_HIGHER} + {$DEFINE DELPHIXE8_OR_HIGHER} + {$DEFINE DELPHI10_OR_HIGHER} + {$DEFINE DELPHI10_1_OR_HIGHER} + {$DEFINE DELPHI10_2_OR_HIGHER} + {$DEFINE DELPHI10_3_OR_HIGHER} + {$DEFINE DELPHI10_4_OR_HIGHER} + {$DEFINE DELPHI11_OR_HIGHER} + {$DEFINE DELPHI12_OR_HIGHER} +{$ENDIF} +{$IFDEF VER370} // Delphi 13 + {$DEFINE DELPHI2010_OR_HIGHER} + {$DEFINE DELPHIXE_OR_HIGHER} + {$DEFINE DELPHI13} + {$DEFINE DELPHIXE2_OR_HIGHER} + {$DEFINE DELPHIXE3_OR_HIGHER} + {$DEFINE DELPHIXE4_OR_HIGHER} + {$DEFINE DELPHIXE5_OR_HIGHER} + {$DEFINE DELPHIXE6_OR_HIGHER} + {$DEFINE DELPHIXE7_OR_HIGHER} + {$DEFINE DELPHIXE8_OR_HIGHER} + {$DEFINE DELPHI10_OR_HIGHER} + {$DEFINE DELPHI10_1_OR_HIGHER} + {$DEFINE DELPHI10_2_OR_HIGHER} + {$DEFINE DELPHI10_3_OR_HIGHER} + {$DEFINE DELPHI10_4_OR_HIGHER} + {$DEFINE DELPHI11_OR_HIGHER} + {$DEFINE DELPHI12_OR_HIGHER} + {$DEFINE DELPHI13_OR_HIGHER} {$ENDIF} ///////////////////////////////////////////////////////////////////////////// @@ -526,19 +243,54 @@ {$IFDEF FPC} {$MODE DELPHI} + {$IFDEF CPU64} + {$DEFINE CPU64BITS} {$DEFINE CPUX64} {$ENDIF CPU64} - {$IFDEF CPU32} + + {$IFDEF CPU86} {$DEFINE CPUX86} - {$ENDIF CPU32} + {$ENDIF CPU86} + {$IFDEF DARWIN} + {$DEFINE OSX} {$DEFINE MACOS} - {$DEFINE ALIGN_STACK} {$IFDEF CPU32} {$DEFINE MACOS32} {$ENDIF CPU32} + {$IFDEF CPU64} + {$DEFINE MACOS64} + {$DEFINE OSX64} + {$ENDIF CPU64} {$ENDIF DARWIN} + + {$IFDEF CPUARM} + {$DEFINE CPUARM32} + {$ENDIF} + + {$IFDEF CPUAARCH64} + {$DEFINE CPUARM} + {$DEFINE CPUARM64} + {$ENDIF} + + {$IFDEF UNIX} + {$DEFINE POSIX} + {$ENDIF UNIX} + + {$IFDEF ANDROID} + {$DEFINE POSIX} + {$ENDIF ANDROID} {$ENDIF FPC} +{$IFDEF DELPHIXE_OR_HIGHER} + {$DEFINE EXTENDED_RTTI} +{$ENDIF DELPHIXE_OR_HIGHER} + +{$IFDEF DELPHIXE4_OR_HIGHER} + {$LEGACYIFEND ON} +{$ENDIF DELPHIXE4_OR_HIGHER} +{$IFDEF MACOS} + {$DEFINE DARWIN} +{$ENDIF MACOS} diff --git a/python4lazarus/MethodCallBack.pas b/python4lazarus/MethodCallBack.pas index 07f2c96..022e21d 100644 --- a/python4lazarus/MethodCallBack.pas +++ b/python4lazarus/MethodCallBack.pas @@ -17,6 +17,7 @@ (* Morgan Martinet (p4d@mmm-experts.com) *) (* Samuel Iseli (iseli@vertec.ch) *) (* Andrey Gruzdev (andrey.gruzdev@gmail.com) *) +(* Lucas Belo (lucas.belo@live.com) *) (**************************************************************************) (* This source code is distributed with no WARRANTY, for no reason or use.*) (* Everyone is allowed to use and change this code free, as long as this *) @@ -32,7 +33,7 @@ interface uses SysUtils; type - TCallType = (ctSTDCALL, ctCDECL); + TCallType = (ctSTDCALL, ctCDECL, ctARMSTD); TCallBack = procedure of object; function GetCallBack( self: TObject; method: Pointer; @@ -127,6 +128,9 @@ implementation PtrCalcType = NativeInt; {$ENDIF} + EMProtectError = class(Exception) + end; + {$IFNDEF MSWINDOWS} {$IFDEF FPC} function mmap(Addr: Pointer; Len: Integer; Prot: Integer; Flags: Integer; FileDes: Integer; Off: Integer): Pointer; cdecl; @@ -151,6 +155,9 @@ procedure GetCodeMem(var ptr: PByte; size: integer); var page: PCodeMemPage; block: PCodeMemBlock; + {$IFNDEF MSWINDOWS} + flags: integer; + {$ENDIF} begin //---allocates Block from executable memory // executable memory is requested in pages via VirtualAlloc @@ -174,13 +181,40 @@ procedure GetCodeMem(var ptr: PByte; size: integer); ptr := nil; exit; end; - mprotect(page, PageSize, PROT_READ or PROT_WRITE or PROT_EXEC); - {$ENDIF} + { + macOS for M1 has a bug (Apple Feedback FB8994773) in which mprotect + rejects a permission change from NONE -> RWX, resulting a "Permission + Denied" error. + Solution: give RW permission, make memory changes, then change RW to X + } + {$IF DEFINED(OSX) AND DEFINED(CPUARM64)} + flags := PROT_READ or PROT_WRITE; + {$ELSE} + flags := PROT_READ or PROT_WRITE or PROT_EXEC; + {$IFEND} + if mprotect(page, PageSize, flags) <> 0 then + raise EMProtectError.CreateFmt('MProtect error: %s', [ + SysErrorMessage({$IFDEF FPC}GetLastOSError{$ELSE}GetLastError{$ENDIF}())]); + {$ENDIF} page^.next:=CodeMemPages; CodeMemPages:=page; // init pointer to end of page page^.CodeBlocks:=Pointer(PtrCalcType(page) + PageSize); + {$IF DEFINED(OSX) AND DEFINED(CPUARM64)} + end else begin + { + macOS for M1 has a bug (Apple Feedback FB8994773) in which mprotect + rejects a permission change from NONE -> RWX. + Solution: give RW permission, make memory changes, then change RW to X + } + //RW permission to the entire page for new changes... + if mprotect(page, PageSize, PROT_READ or PROT_WRITE) <> 0 then + raise EMProtectError.CreateFmt('MProtect error: %s', [ + SysErrorMessage({$IFDEF FPC}GetLastOSError{$ELSE}GetLastError{$ENDIF}())]); end; + {$ELSE} + end; + {$IFEND} //---blocks are assigned starting from the end of the page block:=Pointer(PtrCalcType(page^.codeBlocks) - (size + sizeof(PCodeMemBlock))); @@ -258,6 +292,34 @@ function CodeMemPageCount: integer; end; end; +procedure DeleteCallBack( Proc: Pointer); +begin + FreeCodeMem(Proc); +end; + +procedure FreeCallBacks; +var + page, nextpage: PCodeMemPage; +begin + // free each allocated page + page := CodeMemPages; + while page <> nil do + begin + nextpage := page^.Next; + + // free the memory + {$IFDEF MSWINDOWS} + VirtualFree(page, 0, MEM_RELEASE); + {$ELSE} + //FreeMem(page); + munmap(page,PageSize); + {$ENDIF} + + page := nextpage; + end; + CodeMemPages := nil; +end; + function GetOfObjectCallBack( CallBack: TCallBack; argnum: Integer; calltype: TCallType): Pointer; begin @@ -266,15 +328,17 @@ function GetOfObjectCallBack( CallBack: TCallBack; argnum, calltype); end; -{$IFDEF CPUX64} -{$DEFINE 64_BIT_CALLBACK} -{$ELSE} -{$IFDEF MACOS} -{$DEFINE ALIGNED_32_BIT_CALLBACK} -{$ELSE} -{$DEFINE SIMPLE_32_BIT_CALLBACK} -{$ENDIF MACOS} -{$ENDIF CPUX64} +{$IFNDEF CPUARM} + {$IFDEF CPUX64} + {$DEFINE 64_BIT_CALLBACK} + {$ELSE} + {$IFDEF MACOS} + {$DEFINE ALIGNED_32_BIT_CALLBACK} + {$ELSE} + {$DEFINE SIMPLE_32_BIT_CALLBACK} + {$ENDIF MACOS} + {$ENDIF CPUX64} +{$ENDIF CPUARM} {$IFDEF SIMPLE_32_BIT_CALLBACK} // win32 inplementation @@ -565,35 +629,138 @@ function GetCallBack( self: TObject; method: Pointer; end; {$ENDIF} -procedure DeleteCallBack( Proc: Pointer); +{$IFDEF CPUARM32} +function GetCallBack(Self: TObject; Method: Pointer; ArgNum: Integer; + CallType: TCallType): Pointer; +const + S1: array[0..123] of byte = ( +//big-endian +//offset <start>: + {+ 0:} $80, $40, $2d, $e9, // push {r7, lr} + {+ 4:} $0d, $70, $a0, $e1, // mov r7, sp + {+ 8:} $1e, $04, $2d, $e9, // push {r1, r2, r3, r4, sl} + {+ c:} $5c, $40, $9f, $e5, // ldr r4, [pc, #92] ; 70 <loop+0x1c> + {+ 10:} $00, $00, $54, $e3, // cmp r4, #0 + {+ 14:} $04, $d0, $4d, $c0, // subgt sp, sp, r4 + {+ 18:} $04, $50, $a0, $c1, // movgt r5, r4 + {+ 1c:} $04, $50, $85, $c2, // addgt r5, r5, #4 + {+ 20:} $04, $60, $a0, $c1, // movgt r6, r4 + {+ 24:} $04, $60, $46, $c2, // subgt r6, r6, #4 + {+ 28:} $09, $00, $00, $cb, // blgt 54 <loop> + {+ 2c:} $0f, $00, $2d, $e9, // push {r0, r1, r2, r3} + {+ 30:} $3c, $00, $9f, $e5, // ldr r0, [pc, #60] ; 74 <loop+0x20> + {+ 34:} $0e, $00, $bd, $e8, // pop {r1, r2, r3} + {+ 38:} $38, $a0, $9f, $e5, // ldr sl, [pc, #56] ; 78 <loop+0x24> + {+ 3c:} $3a, $ff, $2f, $e1, // blx sl + {+ 40:} $00, $00, $54, $e3, // cmp r4, #0 + {+ 44:} $04, $d0, $8d, $c0, // addgt sp, sp, r4 + {+ 48:} $04, $40, $9d, $e4, // pop {r4} ; (ldr r4, [sp], #4) + {+ 4c:} $1e, $04, $bd, $e8, // pop {r1, r2, r3, r4, sl} + {+ 50:} $80, $80, $bd, $e8, // pop {r7, pc} +//offset + 00000054 <loop>: + {+ 54:} $05, $a0, $97, $e7, // ldr sl, [r7, r5] + {+ 58:} $06, $a0, $8d, $e7, // str sl, [sp, r6] + {+ 5c:} $04, $50, $45, $e2, // sub r5, r5, #4 + {+ 60:} $04, $60, $46, $e2, // sub r6, r6, #4 + {+ 64:} $00, $00, $56, $e3, // cmp r6, #0 + {+ 68:} $f9, $ff, $ff, $aa, // bge 54 <loop> + {+ 6c:} $1e, $ff, $2f, $e1, // bx lr +//offset + 00000070 <literal pool> + {+ 70:} $00, $00, $00, $00, // stack space for stack parameters + {+ 74:} $00, $00, $00, $00, // Self + {+ 78:} $00, $00, $00, $00 // Method +); +const + ARM_INSTRUCTION_SIZE = 4; + ARM_ARGUMENT_COUNT_IN_REGISTERS = 4; +var + P, Q: PByte; + LLiteralPool: TArray<pointer>; + I: Integer; begin - FreeCodeMem(Proc); + GetCodeMem(Q, SizeOf(S1)); + P := Q; + Move(S1, P^, SizeOf(S1)); + + LLiteralPool := TArray<pointer>.Create( + Pointer((ArgNum - ARM_ARGUMENT_COUNT_IN_REGISTERS) * ARM_INSTRUCTION_SIZE), + Self, + Method); + + Inc(P, Length(S1) - (Length(LLiteralPool) * SizeOf(pointer))); + for I := Low(LLiteralPool) to High(LLiteralPool) do begin + Move(LLiteralPool[I], P^, SizeOf(pointer)); + Inc(P, SizeOf(pointer)); + end; + + Result := Pointer(Q); //set arm mode end; +{$ENDIF CPUARM32} -procedure FreeCallBacks; +{$IFDEF CPUARM64} +function GetCallBack(Self: TObject; Method: Pointer; ArgNum: Integer; + CallType: TCallType): Pointer; +const + S1: array[0..79] of byte = ( +//big-endian +//offset <_start>: + $fd, $7b, $bf, $a9, // stp x29, x30, [sp, #-16]! + $fd, $03, $00, $91, // mov x29, sp + $e0, $07, $bf, $a9, // stp x0, x1, [sp, #-16]! + $e2, $0f, $bf, $a9, // stp x2, x3, [sp, #-16]! + $e4, $17, $bf, $a9, // stp x4, x5, [sp, #-16]! + $e6, $1f, $bf, $a9, // stp x6, x7, [sp, #-16]! + $0a, $00, $00, $10, // adr x10, #0 <_start+0x18> + $40, $15, $40, $f9, // ldr x0, [x10, #40] + $49, $19, $40, $f9, // ldr x9, [x10, #48] + $e7, $2f, $c1, $a8, // ldp x7, x11, [sp], #16 + $e5, $1b, $c1, $a8, // ldp x5, x6, [sp], #16 + $e3, $13, $c1, $a8, // ldp x3, x4, [sp], #16 + $e1, $0b, $c1, $a8, // ldp x1, x2, [sp], #16 + $20, $01, $3f, $d6, // blr x9 + $fd, $7b, $c1, $a8, // ldp x29, x30, [sp], #16 + $c0, $03, $5f, $d6, // ret + $00, $00, $00, $00, // .word 0x00000000 //Self + $00, $00, $00, $00, // .word 0x00000000 + $00, $00, $00, $00, // .word 0x00000000 //Method + $00, $00, $00, $00 // .word 0x00000000 +); var - page, nextpage: PCodeMemPage; + P, Q: PByte; + LLiteralPool: TArray<pointer>; + I: Integer; begin - // free each allocated page - page := CodeMemPages; - while page <> nil do - begin - nextpage := page^.Next; + GetCodeMem(Q, SizeOf(S1)); + P := Q; + Move(S1, P^, SizeOf(S1)); - // free the memory - {$IFDEF MSWINDOWS} - VirtualFree(page, 0, MEM_RELEASE); - {$ELSE} - //FreeMem(page); - munmap(page,PageSize); - {$ENDIF} + LLiteralPool := TArray<pointer>.Create(Self, Method); - page := nextpage; + Inc(P, Length(S1) - (Length(LLiteralPool) * SizeOf(pointer))); + for I := Low(LLiteralPool) to High(LLiteralPool) do begin + Move(LLiteralPool[I], P^, SizeOf(pointer)); + Inc(P, SizeOf(pointer)); end; - CodeMemPages := nil; + + {$IF DEFINED(OSX) AND DEFINED(CPUARM64)} + { + macOS for M1 has a bug (Apple Feedback FB8994773) in which mprotect + rejects a permission change from NONE -> RWX. + Solution: give RW permission, make memory changes, then change RW to X + } + //X permission to the entire page for executions... + if mprotect(CodeMemPages, PageSize, PROT_EXEC) <> 0 then + raise EMProtectError.CreateFmt('MProtect error: %s', [ + SysErrorMessage({$IFDEF FPC}GetLastOSError{$ELSE}GetLastError{$ENDIF}())]); + {$IFEND} + + Result := Pointer(Q); //set arm mode end; +{$ENDIF CPUARM64} initialization + finalization FreeCallBacks; + end. diff --git a/python4lazarus/PythonAction.pas b/python4lazarus/PythonAction.pas index cfa5caa..184f931 100644 --- a/python4lazarus/PythonAction.pas +++ b/python4lazarus/PythonAction.pas @@ -124,7 +124,7 @@ function TPythonAction.PythonClear(pself, args: PPyObject): PPyObject; ClearMethods; with GetPythonEngine, RegisteredMethods do begin - Result := PyInt_FromLong(Count); + Result := PyLong_FromLong(Count); end; end; @@ -146,7 +146,7 @@ function TPythonAction.PythonRegister(pself, args: PPyObject): PPyObject; begin Py_XINCREF(func); Add(func); - Result := PyInt_FromLong(Count); + Result := PyLong_FromLong(Count); end; end; @@ -168,7 +168,7 @@ function TPythonAction.PythonUnregister(pself, args: PPyObject): PPyObject; begin Py_XDECREF(func); Remove(func); - Result := PyInt_FromLong(Count); + Result := PyLong_FromLong(Count); end; end; diff --git a/python4lazarus/PythonEngine.pas b/python4lazarus/PythonEngine.pas index b0706c5..7d7141e 100644 --- a/python4lazarus/PythonEngine.pas +++ b/python4lazarus/PythonEngine.pas @@ -2,8 +2,8 @@ (* *) (* Module: Unit 'PythonEngine' Copyright (c) 1997 *) (* *) -(* Version: 3.0 Dr. Dietmar Budelsky *) -(* Sub-Version: 0.33 dbudelsky@web.de *) +(* Dr. Dietmar Budelsky *) +(* dbudelsky@web.de *) (* Germany *) (* *) (* Morgan Martinet *) @@ -12,6 +12,9 @@ (* CANADA *) (* e-mail: p4d@mmm-experts.com *) (* *) +(* PyScripter *) +(* e-mail: pyscripter@gmail.com *) +(* *) (* Project page: https://github.com/pyscripter/python4delphi *) (**************************************************************************) (* Functionality: Delphi Components that provide an interface to the *) @@ -31,9 +34,7 @@ (* Stefan Hoffmeister (Stefan.Hoffmeister@Econos.de) *) (* Michiel du Toit (micdutoit@hsbfn.com) - Lazarus Port *) (* Chris Nicolai (nicolaitanes@gmail.com) *) -(* Kiriakos Vlahos (kvlahos@london.edu) *) (* Andrey Gruzdev (andrey.gruzdev@gmail.com) *) -(* Alexey Torgashin (support@uvviewsoft.com) *) (**************************************************************************) (* This source code is distributed with no WARRANTY, for no reason or use.*) (* Everyone is allowed to use and change this code free for his own tasks *) @@ -59,17 +60,10 @@ { TODO -oMMM : implement tp_as_buffer slot } { TODO -oMMM : implement Attribute descriptor and subclassing stuff } -{$IFNDEF FPC} - {$IFNDEF DELPHI7_OR_HIGHER} - Error! Delphi 7 or higher is required! - {$ENDIF} -{$ENDIF} - -{$IF defined(LINUX) or (defined(BSD) and not defined(DARWIN)) or defined(SOLARIS) or defined(HAIKU)} - {$define _so_files} +{$IF defined(UNIX) and not defined(DARWIN)} +{$define _so_files} {$ENDIF} - interface uses @@ -109,44 +103,47 @@ interface DllName : String; RegVersion : String; APIVersion : Integer; - CanUseLatest : Boolean; end; const {$ifdef windows} - PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp = + PYTHON_KNOWN_VERSIONS: array[1..10] of TPythonVersionProp = ( - (DllName: 'python27.dll'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'python33.dll'; RegVersion: '3.3'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'python34.dll'; RegVersion: '3.4'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'python35.dll'; RegVersion: '3.5'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'python36.dll'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'python37.dll'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'python38.dll'; RegVersion: '3.8'; APIVersion: 1013; CanUseLatest: True) + (DllName: 'python34.dll'; RegVersion: '3.4'; APIVersion: 1013), + (DllName: 'python35.dll'; RegVersion: '3.5'; APIVersion: 1013), + (DllName: 'python36.dll'; RegVersion: '3.6'; APIVersion: 1013), + (DllName: 'python37.dll'; RegVersion: '3.7'; APIVersion: 1013), + (DllName: 'python38.dll'; RegVersion: '3.8'; APIVersion: 1013), + (DllName: 'python39.dll'; RegVersion: '3.9'; APIVersion: 1013), + (DllName: 'python310.dll'; RegVersion: '3.10'; APIVersion: 1013), + (DllName: 'python311.dll'; RegVersion: '3.11'; APIVersion: 1013), + (DllName: 'python312.dll'; RegVersion: '3.12'; APIVersion: 1013), + (DllName: 'python313.dll'; RegVersion: '3.13'; APIVersion: 1013) ); {$endif} {$ifdef _so_files} - PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp = + PYTHON_KNOWN_VERSIONS: array[1..9] of TPythonVersionProp = ( - (DllName: 'libpython2.7.so'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.3m.so'; RegVersion: '3.3'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.4m.so'; RegVersion: '3.4'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.5m.so'; RegVersion: '3.5'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.6m.so'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.7m.so'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.8m.so'; RegVersion: '3.8'; APIVersion: 1013; CanUseLatest: True) + (DllName: 'libpython3.5m.so'; RegVersion: '3.5'; APIVersion: 1013), + (DllName: 'libpython3.6m.so'; RegVersion: '3.6'; APIVersion: 1013), + (DllName: 'libpython3.7m.so'; RegVersion: '3.7'; APIVersion: 1013), + (DllName: 'libpython3.8.so'; RegVersion: '3.8'; APIVersion: 1013), + (DllName: 'libpython3.9.so'; RegVersion: '3.9'; APIVersion: 1013), + (DllName: 'libpython3.10.so'; RegVersion: '3.10'; APIVersion: 1013), + (DllName: 'libpython3.11.so'; RegVersion: '3.11'; APIVersion: 1013), + (DllName: 'libpython3.12.so'; RegVersion: '3.12'; APIVersion: 1013), + (DllName: 'libpython3.13.so'; RegVersion: '3.13'; APIVersion: 1013) ); {$endif} {$ifdef darwin} - PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp = + PYTHON_KNOWN_VERSIONS: array[1..6] of TPythonVersionProp = ( - (DllName: 'libpython2.7.dylib'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.3.dylib'; RegVersion: '3.3'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.4.dylib'; RegVersion: '3.4'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.5.dylib'; RegVersion: '3.5'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.6.dylib'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.7.dylib'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True), - (DllName: 'libpython3.8.dylib'; RegVersion: '3.8'; APIVersion: 1013; CanUseLatest: True) + (DllName: 'libpython3.8.dylib'; RegVersion: '3.8'; APIVersion: 1013), + (DllName: 'libpython3.9.dylib'; RegVersion: '3.9'; APIVersion: 1013), + (DllName: 'libpython3.10.dylib'; RegVersion: '3.10'; APIVersion: 1013), + (DllName: 'libpython3.11.dylib'; RegVersion: '3.11'; APIVersion: 1013), + (DllName: 'libpython3.12.dylib'; RegVersion: '3.12'; APIVersion: 1013), + (DllName: 'libpython3.13.dylib'; RegVersion: '3.13'; APIVersion: 1013) ); {$endif} @@ -158,6 +155,8 @@ interface METH_VARARGS = $0001; METH_KEYWORDS = $0002; + METH_CLASS = $0010; + METH_STATIC = $0020; // Masks for the co_flags field of PyCodeObject CO_OPTIMIZED = $0001; @@ -172,23 +171,54 @@ interface Py_NE = 3; Py_GT = 4; Py_GE = 5; + + {$IFDEF CPUARM} + DEFAULT_CALLBACK_TYPE: TCallType = TCallType.ctARMSTD; + {$ELSE} + DEFAULT_CALLBACK_TYPE: TCallType = TCallType.ctCDECL; + {$ENDIF CPUARM} + type // Delphi equivalent used by TPyObject TRichComparisonOpcode = (pyLT, pyLE, pyEQ, pyNE, pyGT, pyGE); + + +// C long is 8 bytes in non-Windows 64-bit operating systems +// Same Delphi's LongInt but not fpc LongInt which is always 4 bytes +// Hence the following +{$IFDEF MSWINDOWS} + C_Long = Integer; + C_ULong = Cardinal; +{$ELSE} + C_Long = NativeInt; + C_ULong = NativeUInt; +{$ENDIF} + +// wchar_t is 4 bytes on Linux/OS X/Android but 2 bytes on Windows +{$IFDEF POSIX} + PWCharT = PUCS4Char; + PPWCharT = ^PUCS4Char; + WCharTString = UCS4String; +{$ELSE} + PWCharT = PWideChar; + PPWCharT = PPWideChar; + WCharTString = UnicodeString; +{$ENDIF} + const -{Type flags (tp_flags) introduced in version 2.0 +{ +Type flags (tp_flags) -These flags are used to extend the type structure in a backwards-compatible -fashion. Extensions can use the flags to indicate (and test) when a given -type structure contains a new feature. The Python core will use these when -introducing new functionality between major revisions (to avoid mid-version -changes in the PYTHON_API_VERSION). +These flags are used to change expected features and behavior for a +particular type. Arbitration of the flag bit positions will need to be coordinated among -all extension writers who publically release their extensions (this will -be fewer than you might expect!).. +all extension writers who publicly release their extensions (this will +be fewer than you might expect!). -Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs. +Most flags were removed as of Python 3.0 to make room for new flags. (Some +flags are not for backwards compatibility but to indicate the presence of an +optional feature; these flags remain of course.) Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value. @@ -196,140 +226,80 @@ interface given type object has a specified feature. } -// PyBufferProcs contains bf_getcharbuffer - Py_TPFLAGS_HAVE_GETCHARBUFFER = (1 shl 0); - -// PySequenceMethods contains sq_contains - Py_TPFLAGS_HAVE_SEQUENCE_IN = (1 shl 1); - -// Objects which participate in garbage collection (see objimp.h) - Py_TPFLAGS_GC = (1 shl 2); - -// PySequenceMethods and PyNumberMethods contain in-place operators - Py_TPFLAGS_HAVE_INPLACEOPS = (1 shl 3); - -// PyNumberMethods do their own coercion */ - Py_TPFLAGS_CHECKTYPES = (1 shl 4); +// Set if the type object is dynamically allocated + Py_TPFLAGS_HEAPTYPE = (C_ULong(1) shl 9); - Py_TPFLAGS_HAVE_RICHCOMPARE = (1 shl 5); +// Set if the type allows subclassing + Py_TPFLAGS_BASETYPE = (C_ULong(1) shl 10); -// Objects which are weakly referencable if their tp_weaklistoffset is >0 -// XXX Should this have the same value as Py_TPFLAGS_HAVE_RICHCOMPARE? -// These both indicate a feature that appeared in the same alpha release. +// Set if the type is 'ready' -- fully initialized + Py_TPFLAGS_READY = (C_ULong(1) shl 12); - Py_TPFLAGS_HAVE_WEAKREFS = (1 shl 6); +// Set while the type is being 'readied', to prevent recursive ready calls + Py_TPFLAGS_READYING = (C_ULong(1) shl 13); -// tp_iter is defined - Py_TPFLAGS_HAVE_ITER = (1 shl 7); +// Objects support garbage collection (see objimp.h) + Py_TPFLAGS_HAVE_GC = (C_ULong(1) shl 14); -// New members introduced by Python 2.2 exist - Py_TPFLAGS_HAVE_CLASS = (1 shl 8); +// Set if the type implements the vectorcall protocol (PEP 590) */ + _Py_TPFLAGS_HAVE_VECTORCALL = (C_ULong(1) shl 11); -// Set if the type object is dynamically allocated - Py_TPFLAGS_HEAPTYPE = (1 shl 9); +// Objects behave like an unbound method + Py_TPFLAGS_METHOD_DESCRIPTOR = (C_ULong(1) shl 17); -// Set if the type allows subclassing - Py_TPFLAGS_BASETYPE = (1 shl 10); +// Objects support type attribute cache + Py_TPFLAGS_HAVE_VERSION_TAG = (C_ULong(1) shl 18); + Py_TPFLAGS_VALID_VERSION_TAG = (C_ULong(1) shl 19); -// Set if the type is 'ready' -- fully initialized - Py_TPFLAGS_READY = (1 shl 12); +// Type is abstract and cannot be instantiated + Py_TPFLAGS_IS_ABSTRACT = (C_ULong(1) shl 20); -// Set while the type is being 'readied', to prevent recursive ready calls - Py_TPFLAGS_READYING = (1 shl 13); +// These flags are used to determine if a type is a subclass. + Py_TPFLAGS_LONG_SUBCLASS = (C_ULong(1) shl 24); + Py_TPFLAGS_LIST_SUBCLASS = (C_ULong(1) shl 25); + Py_TPFLAGS_TUPLE_SUBCLASS = (C_ULong(1) shl 26); + Py_TPFLAGS_BYTES_SUBCLASS = (C_ULong(1) shl 27); + Py_TPFLAGS_UNICODE_SUBCLASS = (C_ULong(1) shl 28); + Py_TPFLAGS_DICT_SUBCLASS = (C_ULong(1) shl 29); + Py_TPFLAGS_BASE_EXC_SUBCLASS = (C_ULong(1) shl 30); + Py_TPFLAGS_TYPE_SUBCLASS = (C_ULong(1) shl 31); -// Objects support garbage collection (see objimp.h) - Py_TPFLAGS_HAVE_GC = (1 shl 14); - - Py_TPFLAGS_DEFAULT = Py_TPFLAGS_HAVE_GETCHARBUFFER - or Py_TPFLAGS_HAVE_SEQUENCE_IN - or Py_TPFLAGS_HAVE_INPLACEOPS - or Py_TPFLAGS_HAVE_RICHCOMPARE - or Py_TPFLAGS_HAVE_WEAKREFS - or Py_TPFLAGS_HAVE_ITER - or Py_TPFLAGS_HAVE_CLASS - or Py_TPFLAGS_BASETYPE - ; + Py_TPFLAGS_DEFAULT = Py_TPFLAGS_BASETYPE or Py_TPFLAGS_HAVE_VERSION_TAG; // See function PyType_HasFeature below for testing the flags. // Delphi equivalent used by TPythonType type - TPFlag = (tpfHaveGetCharBuffer, tpfHaveSequenceIn, tpfGC, tpfHaveInplaceOps, - tpfCheckTypes, tpfHaveRichCompare, tpfHaveWeakRefs - ,tpfHaveIter, tpfHaveClass, tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC - ); + TPFlag = (tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC, + tpVectorCall, tpMethodDescriptor, tpHaveVersionTag, + tpValidVersionTag, tpIsAbstract, tpLongSubclass, + tpListSubClass, tpTupleSubclass, tpBytesSubclass, + tpBaseExcSubclass, tpTypeSubclass); TPFlags = set of TPFlag; const - TPFLAGS_DEFAULT = [tpfHaveSequenceIn, tpfHaveInplaceOps, - tpfHaveRichCompare, tpfHaveIter, - tpfHaveClass, tpfBaseType - ]; + TPFLAGS_DEFAULT = [tpfBaseType, tpHaveVersionTag]; + //------- Python opcodes ----------// -Const +const single_input = 256; file_input = 257; eval_input = 258; - p4d_funcdef = 259; - p4d_parameters = 260; - p4d_varargslist = 261; - p4d_fpdef = 262; - p4d_fplist = 263; - p4d_stmt = 264; - p4d_simple_stmt = 265; - p4d_small_stmt = 266; - p4d_expr_stmt = 267; - p4d_augassign = 268; - p4d_print_stmt = 269; - p4d_del_stmt = 270; - p4d_pass_stmt = 271; - p4d_flow_stmt = 272; - p4d_break_stmt = 273; - p4d_continue_stmt = 274; - p4d_return_stmt = 275; - p4d_raise_stmt = 276; - p4d_import_stmt = 277; - p4d_import_as_name = 278; - p4d_dotted_as_name = 279; - p4d_dotted_name = 280; - p4d_global_stmt = 281; - p4d_exec_stmt = 282; - p4d_assert_stmt = 283; - p4d_compound_stmt = 284; - p4d_if_stmt = 285; - p4d_while_stmt = 286; - p4d_for_stmt = 287; - p4d_try_stmt = 288; - p4d_except_clause = 289; - p4d_suite = 290; - p4d_test = 291; - p4d_and_test = 291; - p4d_not_test = 293; - p4d_comparison = 294; - p4d_comp_op = 295; - p4d_expr = 296; - p4d_xor_expr = 297; - p4d_and_expr = 298; - p4d_shift_expr = 299; - p4d_arith_expr = 300; - p4d_term = 301; - p4d_factor = 302; - p4d_power = 303; - p4d_atom = 304; - p4d_listmaker = 305; - p4d_lambdef = 306; - p4d_trailer = 307; - p4d_subscriptlist = 308; - p4d_subscript = 309; - p4d_sliceop = 310; - p4d_exprlist = 311; - p4d_testlist = 312; - p4d_dictmaker = 313; - p4d_classdef = 314; - p4d_arglist = 315; - p4d_argument = 316; - p4d_list_iter = 317; - p4d_list_for = 318; - p4d_list_if = 319; + + // UnicodeObject.h + const + // Return values of the PyUnicode_KIND() macro + + { + PyUnicode_WCHAR_KIND is deprecated. Will be removed in Python 12. + String contains only wstr byte characters. This is only possible + when the string was created with a legacy API and _PyUnicode_Ready() + has not been called yet. + } + PyUnicode_WCHAR_KIND = 0; + + PyUnicode_1BYTE_KIND = 1; + PyUnicode_2BYTE_KIND = 2; + PyUnicode_4BYTE_KIND = 4; // structmember.h const @@ -376,14 +346,11 @@ interface //####################################################### const - ErrInit = -300; CR = #13; LF = #10; TAB = #09; CRLF = CR+LF; - - //####################################################### //## ## //## Global declarations, nothing Python specific ## @@ -414,7 +381,6 @@ interface PPyObject = ^PyObject; PPPyObject = ^PPyObject; PPPPyObject = ^PPPyObject; - PPyIntObject = ^PyIntObject; PPyTypeObject = ^PyTypeObject; PPySliceObject = ^PySliceObject; @@ -429,30 +395,18 @@ interface lenfunc = function( ob1 : PPyObject): NativeInt; cdecl; coercion = function( ob1,ob2 : PPPyObject): integer; cdecl; ssizeargfunc = function( ob1 : PPyObject; i: NativeInt): PPyObject; cdecl; - ssizessizeargfunc = function( ob1 : PPyObject; i1, i2: NativeInt): - PPyObject; cdecl; ssizeobjargproc = function( ob1 : PPyObject; i: NativeInt; ob2 : PPyObject): integer; cdecl; - ssizessizeobjargproc = function( ob1: PPyObject; i1, i2: NativeInt; - ob2: PPyObject): integer; cdecl; objobjargproc = function( ob1,ob2,ob3 : PPyObject): integer; cdecl; pydestructor = procedure(ob: PPyObject); cdecl; - printfunc = function( ob: PPyObject; var f: file; i: integer): integer; cdecl; getattrfunc = function( ob1: PPyObject; name: PAnsiChar): PPyObject; cdecl; setattrfunc = function( ob1: PPyObject; name: PAnsiChar; ob2: PPyObject): integer; cdecl; - cmpfunc = function( ob1,ob2: PPyObject): integer; cdecl; reprfunc = function( ob: PPyObject): PPyObject; cdecl; hashfunc = function( ob: PPyObject): NativeInt; cdecl; // !! in 2.x it is still a LongInt getattrofunc = function( ob1,ob2: PPyObject): PPyObject; cdecl; setattrofunc = function( ob1,ob2,ob3: PPyObject): integer; cdecl; -/// jah 29-sep-2000 : updated for python 2.0 -/// added from object.h - getreadbufferproc = function ( ob1: PPyObject; i: NativeInt; ptr: Pointer): NativeInt; cdecl; - getwritebufferproc= function ( ob1: PPyObject; i: NativeInt; ptr: Pointer): NativeInt; cdecl; - getsegcountproc = function ( ob1: PPyObject; i: NativeInt): NativeInt; cdecl; - getcharbufferproc = function ( ob1: PPyObject; i: NativeInt; const pstr: PAnsiChar): NativeInt; cdecl; objobjproc = function ( ob1, ob2: PPyObject): integer; cdecl; visitproc = function ( ob1: PPyObject; ptr: Pointer): integer; cdecl; traverseproc = function ( ob1: PPyObject; proc: visitproc; ptr: Pointer): integer; cdecl; @@ -466,50 +420,7 @@ interface newfunc = function ( subtype: PPyTypeObject; args, kwds : PPyObject) : PPyObject; cdecl; allocfunc = function ( self: PPyTypeObject; nitems : NativeInt) : PPyObject; cdecl; - PyNumberMethods200 = {$IFNDEF CPUX64}packed{$ENDIF} record - nb_add : binaryfunc; - nb_subtract : binaryfunc; - nb_multiply : binaryfunc; - nb_divide : binaryfunc; - nb_remainder : binaryfunc; - nb_divmod : binaryfunc; - nb_power : ternaryfunc; - nb_negative : unaryfunc; - nb_positive : unaryfunc; - nb_absolute : unaryfunc; - nb_nonzero : inquiry; - nb_invert : unaryfunc; - nb_lshift : binaryfunc; - nb_rshift : binaryfunc; - nb_and : binaryfunc; - nb_xor : binaryfunc; - nb_or : binaryfunc; - nb_coerce : coercion; - nb_int : unaryfunc; - nb_long : unaryfunc; - nb_float : unaryfunc; - nb_oct : unaryfunc; - nb_hex : unaryfunc; - nb_inplace_add : binaryfunc; - nb_inplace_subtract : binaryfunc; - nb_inplace_multiply : binaryfunc; - nb_inplace_divide : binaryfunc; - nb_inplace_remainder : binaryfunc; - nb_inplace_power : ternaryfunc; - nb_inplace_lshift : binaryfunc; - nb_inplace_rshift : binaryfunc; - nb_inplace_and : binaryfunc; - nb_inplace_xor : binaryfunc; - nb_inplace_or : binaryfunc; - nb_floor_divide : binaryfunc; - nb_true_divide : binaryfunc; - nb_inplace_floor_divide : binaryfunc; - nb_inplace_true_divide : binaryfunc; - nb_index : unaryfunc; - end; - PPyNumberMethods200 = ^PyNumberMethods200; - - PyNumberMethods300 = {$IFNDEF CPUX64}packed{$ENDIF} record + PyNumberMethods = {$IFNDEF CPUX64}packed{$ENDIF} record nb_add : binaryfunc; nb_subtract : binaryfunc; nb_multiply : binaryfunc; @@ -547,22 +458,19 @@ interface nb_matrix_multiply : binaryfunc; // new in python 3.5 nb_inplace_matrix_multiply : binaryfunc; // new in python 3.5 end; - PPyNumberMethods300 = ^PyNumberMethods300; + PPyNumberMethods = ^PyNumberMethods; PySequenceMethods = {$IFNDEF CPUX64}packed{$ENDIF} record sq_length : lenfunc; sq_concat : binaryfunc; sq_repeat : ssizeargfunc; sq_item : ssizeargfunc; - sq_slice : ssizessizeargfunc; + was_sq_slice : Pointer; // empty slot in python 3.x sq_ass_item : ssizeobjargproc; - sq_ass_slice : ssizessizeobjargproc; - -/// jah 29-sep-2000 : updated for python 2.0 -/// added from .h - sq_contains : objobjproc; - sq_inplace_concat : binaryfunc; - sq_inplace_repeat : ssizeargfunc; + was_sq_ass_slice : Pointer; // empty slot in python 3.x + sq_contains : objobjproc; + sq_inplace_concat : binaryfunc; + sq_inplace_repeat : ssizeargfunc; end; PPySequenceMethods = ^PySequenceMethods; @@ -573,16 +481,6 @@ interface end; PPyMappingMethods = ^PyMappingMethods; -/// jah 29-sep-2000 : updated for python 2.0 -/// added from .h - PyBufferProcs = {$IFNDEF CPUX64}packed{$ENDIF} record - bf_getreadbuffer : getreadbufferproc; - bf_getwritebuffer : getwritebufferproc; - bf_getsegcount : getsegcountproc; - bf_getcharbuffer : getcharbufferproc; - end; - PPyBufferProcs = ^PyBufferProcs; - Py_complex = {$IFNDEF CPUX64}packed{$ENDIF} record real : double; imag : double; @@ -593,12 +491,6 @@ interface ob_type: PPyTypeObject; end; - PyIntObject = {$IFNDEF CPUX64}packed{$ENDIF} record - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - ob_ival : LongInt; - end; - _frozen = {$IFNDEF CPUX64}packed{$ENDIF} record name : PAnsiChar; code : PByte; @@ -754,21 +646,21 @@ interface ob_refcnt: NativeInt; ob_type: PPyTypeObject; ob_size: NativeInt; // Number of items in variable part - tp_name: PAnsiChar; // For printing + tp_name: PAnsiChar; // For printing tp_basicsize, tp_itemsize: NativeInt; // For allocation // Methods to implement standard operations - tp_dealloc: pydestructor; - tp_print: printfunc; // not available and replaced in Python 3.x - tp_getattr: getattrfunc; - tp_setattr: setattrfunc; - tp_compare: cmpfunc; // not available and replaced in Python 3.x - tp_repr: reprfunc; + tp_dealloc: pydestructor; + tp_vectorcall_offset: NativeInt; + tp_getattr: getattrfunc; + tp_setattr: setattrfunc; + tp_as_async: Pointer; // not implemented + tp_repr: reprfunc; // Method suites for standard classes - tp_as_number: Pointer; //PPyNumberMethods + tp_as_number: PPyNumberMethods; tp_as_sequence: PPySequenceMethods; tp_as_mapping: PPyMappingMethods; @@ -781,9 +673,9 @@ interface tp_setattro: setattrofunc; // Functions to access object as input/output buffer - tp_as_buffer: PPyBufferProcs; + tp_as_buffer: Pointer; // PPyBufferProcs - not implemented // Flags to define presence of optional/expanded features - tp_flags: LongInt; + tp_flags: C_ULong; tp_doc: PAnsiChar; // Documentation string @@ -822,8 +714,9 @@ interface tp_subclasses : PPyObject; tp_weaklist : PPyObject; tp_del : PyDestructor; - tp_version_tag : NativeUInt; // Type attribute cache version tag. Added in version 2.6 + tp_version_tag : Cardinal; // Type attribute cache version tag. Added in version 2.6 tp_finalize : PyDestructor; + tp_vectorcall : Pointer; // not implemented //More spares tp_xxx1 : NativeInt; tp_xxx2 : NativeInt; @@ -837,212 +730,12 @@ interface tp_xxx10 : NativeInt; end; - PPyMethodChain = ^PyMethodChain; - PyMethodChain = {$IFNDEF CPUX64}packed{$ENDIF} record - methods: PPyMethodDef; - link: PPyMethodChain; - end; - - PPyClassObject = ^PyClassObject; - PyClassObject = {$IFNDEF CPUX64}packed{$ENDIF} record - // Start of the Head of an object - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - // End of the Head of an object - cl_bases : PPyObject; // A tuple of class objects - cl_dict : PPyObject; // A dictionary - cl_name : PPyObject; // A string - // The following three are functions or NULL - cl_getattr : PPyObject; - cl_setattr : PPyObject; - cl_delattr : PPyObject; - end; - - PPyInstanceObject = ^PyInstanceObject; - PyInstanceObject = {$IFNDEF CPUX64}packed{$ENDIF} record - // Start of the Head of an object - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - // End of the Head of an object - in_class : PPyClassObject; // The class object - in_dict : PPyObject; // A dictionary - end; - -{ Instance method objects are used for two purposes: - (a) as bound instance methods (returned by instancename.methodname) - (b) as unbound methods (returned by ClassName.methodname) - In case (b), im_self is NULL -} - - PPyMethodObject = ^PyMethodObject; - PyMethodObject = {$IFNDEF CPUX64}packed{$ENDIF} record - // Start of the Head of an object - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - // End of the Head of an object - im_func : PPyObject; // The function implementing the method - im_self : PPyObject; // The instance it is bound to, or NULL - im_class : PPyObject; // The class that defined the method - end; - - - // Bytecode object, compile.h - PPyCodeObject = ^PyCodeObject; - PyCodeObject = {$IFNDEF CPUX64}packed{$ENDIF} record - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - co_argcount : Integer; // #arguments, except *args - co_nlocals : Integer; // #local variables - co_stacksize : Integer; // #entries needed for evaluation stack - co_flags : Integer; // CO_..., see below - co_code : PPyObject; // instruction opcodes (it hides a PyStringObject) - co_consts : PPyObject; // list (constants used) - co_names : PPyObject; // list of strings (names used) - co_varnames : PPyObject; // tuple of strings (local variable names) - co_freevars : PPyObject; // tuple of strings (free variable names) - co_cellvars : PPyObject; // tuple of strings (cell variable names) - // The rest doesn't count for hash/cmp - co_filename : PPyObject; // string (where it was loaded from) - co_name : PPyObject; // string (name, for reference) - co_firstlineno : Integer; // first source line number - co_lnotab : PPyObject; // string (encoding addr<->lineno mapping) - end; - - // from pystate.h - PPyInterpreterState = ^PyInterpreterState; - PPyThreadState = ^PyThreadState; - PPyFrameObject = ^PyFrameObject; - - // Interpreter environments - PyInterpreterState = {$IFNDEF CPUX64}packed{$ENDIF} record - next : PPyInterpreterState; - tstate_head : PPyThreadState; - -// The strucure has changed between versions beyond this point. -// Not safe to use members -// modules : PPyObject; -// sysdict : PPyObject; -// builtins : PPyObject; - - //Spares - is_xxx1 : NativeInt; - is_xxx2 : NativeInt; - is_xxx3 : NativeInt; - is_xxx4 : NativeInt; - is_xxx5 : NativeInt; - is_xxx6 : NativeInt; - is_xxx7 : NativeInt; - is_xxx8 : NativeInt; - is_xxx9 : NativeInt; - end; - - // Thread specific information - PyThreadState = {$IFNDEF CPUX64}packed{$ENDIF} record - {prev : PPyThreadState; introduced in python 3.4} - next : PPyThreadState; - interp : PPyInterpreterState; - interp34 : PPyInterpreterState; - -// The strucure has changed between versions beyond this point. -// Not safe to use members -// -// frame : PPyFrameObject; -// recursion_depth: integer; -// ticker : integer; -// tracing : integer; -// -// sys_profilefn : Pointer; // c-functions for profile/trace -// sys_tracefn : Pointer; -// sys_profilefunc: PPyObject; -// sys_tracefunc : PPyObject; -// -// curexc_type : PPyObject; -// curexc_value : PPyObject; -// curexc_traceback: PPyObject; -// -// exc_type : PPyObject; -// exc_value : PPyObject; -// exc_traceback : PPyObject; -// -// dict : PPyObject; -// tick_counter :Integer; -// gilstate_counter :Integer; -// -// async_exc :PPyObject; { Asynchronous exception to raise } -// thread_id :LongInt; { Thread id where this tstate was created } - //Spares - ts_xxx1 : NativeInt; - ts_xxx2 : NativeInt; - ts_xxx3 : NativeInt; - ts_xxx4 : NativeInt; - ts_xxx5 : NativeInt; - ts_xxx6 : NativeInt; - ts_xxx7 : NativeInt; - ts_xxx8 : NativeInt; - ts_xxx9 : NativeInt; - ts_xxx10 : NativeInt; - ts_xxx11 : NativeInt; - ts_xxx12 : NativeInt; - ts_xxx13 : NativeInt; - ts_xxx14 : NativeInt; - ts_xxx15 : NativeInt; - ts_xxx16 : NativeInt; - ts_xxx17 : NativeInt; - ts_xxx18 : NativeInt; - ts_xxx19 : NativeInt; - - { XXX signal handlers should also be here } - end; - - // from frameobject.h - - PPyTryBlock = ^PyTryBlock; - PyTryBlock = {$IFNDEF CPUX64}packed{$ENDIF} record - b_type : Integer; // what kind of block this is - b_handler : Integer; // where to jump to find handler - b_level : Integer; // value stack level to pop to - end; - - CO_MAXBLOCKS = 0..19; - PyFrameObject = {$IFNDEF CPUX64}packed{$ENDIF} record - // Start of the VAR_HEAD of an object. - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - ob_size : NativeInt; // Number of items in variable part - // End of the Head of an object - f_back : PPyFrameObject; // previous frame, or NULL - f_code : PPyCodeObject; // code segment - f_builtins : PPyObject; // builtin symbol table (PyDictObject) - f_globals : PPyObject; // global symbol table (PyDictObject) - f_locals : PPyObject; // local symbol table (PyDictObject) - f_valuestack : PPPyObject; // points after the last local - (* Next free slot in f_valuestack. Frame creation sets to f_valuestack. - Frame evaluation usually NULLs it, but a frame that yields sets it - to the current stack top. *) - f_stacktop : PPPyObject; - f_trace : PPyObject; // Trace function - f_exc_type, f_exc_value, f_exc_traceback: PPyObject; - f_tstate : PPyThreadState; - f_lasti : Integer; // Last instruction if called - f_lineno : Integer; // Current line number - f_iblock : Integer; // index in f_blockstack - f_blockstack : array[CO_MAXBLOCKS] of PyTryBlock; // for try and loop blocks - f_localsplus : array[0..0] of PPyObject; // locals+stack, dynamically sized - end; - - // From traceback.c - PPyTraceBackObject = ^PyTraceBackObject; - PyTraceBackObject = {$IFNDEF CPUX64}packed{$ENDIF} record - // Start of the Head of an object - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - // End of the Head of an object - tb_next : PPyTraceBackObject; - tb_frame : PPyFrameObject; - tb_lasti : Integer; - tb_lineno : Integer; - end; + // the structure of PyInterpreterState and PyThreadState is considered + // an implementation detail. It has been changing between python versions + // and there is no real use of accessing these structures directly. + PPyInterpreterState = Pointer; + PPyThreadState = Pointer; // Parse tree node interface @@ -1059,22 +752,11 @@ interface PPyCompilerFlags = ^PyCompilerFlags; PyCompilerFlags = {$IFNDEF CPUX64}packed{$ENDIF} record flags : integer; + cf_feature_version : integer; //added in Python 3.8 end; - // From weakrefobject.h - - PPyWeakReference = ^PyWeakReference; - PyWeakReference = {$IFNDEF CPUX64}packed{$ENDIF} record - // Start of the Head of an object - ob_refcnt : NativeInt; - ob_type : PPyTypeObject; - // End of the Head of an object - wr_object : PPyObject; - wr_callback : PPyObject; - hash : NativeInt; - wr_prev : PPyWeakReference; - wr_next : PPyWeakReference; - end; + const + PyCF_ONLY_AST = $0400; // from datetime.h @@ -1371,10 +1053,12 @@ EPyRuntimeError = class (EPyStandardError); EPyNotImplementedError = class (EPyRuntimeError); EPySyntaxError = class (EPyStandardError) public - EFileName: AnsiString; - ELineStr: AnsiString; + EFileName: UnicodeString; + ELineStr: UnicodeString; ELineNumber: Integer; EOffset: Integer; + EEndLineNumber: Integer; + EEndOffset: Integer; end; EPyIndentationError = class (EPySyntaxError); EPyTabError = class (EPyIndentationError); @@ -1552,26 +1236,22 @@ TDynamicDll = class(TComponent) //------------------------------------------------------- type + (*$HPPEMIT 'typedef int __cdecl (*TPyArg_Parse)(void * args, char * format, ...);' *) + TPyArg_Parse = function( args: PPyObject; format: PAnsiChar {;....}) : Integer; cdecl varargs; + {$EXTERNALSYM TPyArg_Parse} - { TPythonInterface } - - TPythonInterface=class(TDynamicDll) - private - DLL_Py_GetBuildInfo: - function : PAnsiChar; cdecl; - DLL_PyCode_Addr2Line: - function ( co: PPyCodeObject; addrq : Integer ) : Integer; cdecl; - DLL_PyImport_ExecCodeModule: - function ( const name : AnsiString; codeobject : PPyObject) : PPyObject; cdecl; + (*$HPPEMIT 'typedef int __cdecl (*TPyArg_ParseTupleAndKeywords)(void * args, void * kw, char * format, char** kwargs, ...);' *) + TPyArg_ParseTupleAndKeywords = function( args: PPyObject; kw: PPyObject; format: PAnsiChar; kwargs: PPAnsiChar {;...}): Integer; cdecl varargs; + {$EXTERNALSYM TPyArg_ParseTupleAndKeywords} - DLL_PyString_FromString: function( str: PAnsiChar): PPyObject; cdecl; - DLL_Py_FlushLine:procedure; cdecl; - procedure DetectPythonVersionFromLibName(const Str: AnsiString); + (*$HPPEMIT 'typedef int __cdecl (*TPy_BuildValue)(char * format, ...);' *) + TPy_BuildValue = function( format: PAnsiChar {;...}): Pointer; cdecl varargs; + {$EXTERNALSYM TPy_BuildValue} + TPythonInterface=class(TDynamicDll) protected FInitialized: Boolean; FFinalizing: Boolean; - FIsPython3000: Boolean; FMajorVersion: integer; FMinorVersion: integer; FBuiltInModuleName: String; @@ -1579,7 +1259,6 @@ TPythonInterface=class(TDynamicDll) procedure AfterLoad; override; function GetQuitMessage : String; override; procedure CheckPython; - function GetUnicodeTypeSuffix : String; public // define Python flags. See file pyDebug.h @@ -1588,21 +1267,15 @@ TPythonInterface=class(TDynamicDll) Py_InteractiveFlag: PInt; Py_OptimizeFlag: PInt; Py_NoSiteFlag: PInt; - Py_UseClassExceptionsFlag: PInt; Py_FrozenFlag: PInt; - Py_TabcheckFlag: PInt; - Py_UnicodeFlag: PInt; Py_IgnoreEnvironmentFlag: PInt; - Py_DivisionWarningFlag: PInt; - //_PySys_TraceFunc: PPPyObject; - //_PySys_ProfileFunc: PPPPyObject; PyImport_FrozenModules: PP_frozen; Py_None: PPyObject; Py_Ellipsis: PPyObject; - Py_False: PPyIntObject; - Py_True: PPyIntObject; + Py_False: PPyObject; + Py_True: PPyObject; Py_NotImplemented: PPyObject; PyExc_AttributeError: PPPyObject; @@ -1626,11 +1299,9 @@ TPythonInterface=class(TDynamicDll) PyExc_Exception: PPPyObject; PyExc_FloatingPointError: PPPyObject; PyExc_LookupError: PPPyObject; - PyExc_StandardError: PPPyObject; PyExc_AssertionError: PPPyObject; PyExc_EnvironmentError: PPPyObject; PyExc_IndentationError: PPPyObject; - PyExc_MemoryErrorInst: PPPyObject; PyExc_NotImplementedError: PPPyObject; PyExc_OSError: PPPyObject; PyExc_TabError: PPPyObject; @@ -1652,19 +1323,14 @@ TPythonInterface=class(TDynamicDll) PyExc_UnicodeEncodeError: PPPyObject; PyExc_UnicodeTranslateError: PPPyObject; + PyCode_Type: PPyTypeObject; PyType_Type: PPyTypeObject; PyCFunction_Type: PPyTypeObject; - PyCObject_Type: PPyTypeObject; - PyClass_Type: PPyTypeObject; - PyCode_Type: PPyTypeObject; PyComplex_Type: PPyTypeObject; PyDict_Type: PPyTypeObject; - PyFile_Type: PPyTypeObject; PyFloat_Type: PPyTypeObject; PyFrame_Type: PPyTypeObject; PyFunction_Type: PPyTypeObject; - PyInstance_Type: PPyTypeObject; - PyInt_Type: PPyTypeObject; PyList_Type: PPyTypeObject; PyLong_Type: PPyTypeObject; PyMethod_Type: PPyTypeObject; @@ -1672,10 +1338,9 @@ TPythonInterface=class(TDynamicDll) PyObject_Type: PPyTypeObject; PyRange_Type: PPyTypeObject; PySlice_Type: PPyTypeObject; - PyString_Type: PPyTypeObject; + PyBytes_Type: PPyTypeObject; PyTuple_Type: PPyTypeObject; PyBaseObject_Type: PPyTypeObject; - PyBuffer_Type: PPyTypeObject; PyCallIter_Type: PPyTypeObject; PyCell_Type: PPyTypeObject; PyClassMethod_Type: PPyTypeObject; @@ -1689,20 +1354,11 @@ TPythonInterface=class(TDynamicDll) _PyWeakref_RefType: PPyTypeObject; _PyWeakref_ProxyType: PPyTypeObject; _PyWeakref_CallableProxyType: PPyTypeObject; - PyBaseString_Type: PPyTypeObject; PyBool_Type: PPyTypeObject; PyEnum_Type: PPyTypeObject; - //PyArg_GetObject: function(args : PPyObject; nargs, i: integer; p_a: PPPyObject): integer; cdecl; - //PyArg_GetLong: function(args : PPyObject; nargs, i: integer; p_a: PLong): integer; cdecl; - //PyArg_GetShort: function(args : PPyObject; nargs, i: integer; p_a: PShort): integer; cdecl; - //PyArg_GetFloat: function(args : PPyObject; nargs, i: integer; p_a: PFloat): integer; cdecl; - //PyArg_GetString: function(args : PPyObject; nargs, i: integer; p_a: PAnsiString): integer; cdecl; - //PyArgs_VaParse: function (args : PPyObject; format: PAnsiChar; va_list: array of const): integer; cdecl; - // Does not work! - // Py_VaBuildValue: function (format: PAnsiChar; va_list: array of const): PPyObject; cdecl; - //PyBuiltin_Init: procedure; cdecl; - + Py_GetBuildInfo: function : PAnsiChar; cdecl; + PyImport_ExecCodeModule: function ( const name : AnsiString; codeobject : PPyObject) : PPyObject; cdecl; PyComplex_FromCComplex: function(c: Py_complex):PPyObject; cdecl; PyComplex_FromDoubles: function(realv,imag : double):PPyObject; cdecl; PyComplex_RealAsDouble: function(op : PPyObject ): double; cdecl; @@ -1711,19 +1367,13 @@ TPythonInterface=class(TDynamicDll) PyCFunction_GetFunction: function(ob : PPyObject): Pointer; cdecl; PyCFunction_GetSelf: function(ob : PPyObject): PPyObject; cdecl; PyCallable_Check: function(ob : PPyObject): integer; cdecl; - PyCObject_FromVoidPtr: function(cobj, destruct : Pointer): PPyObject; cdecl; - PyCObject_AsVoidPtr: function(ob : PPyObject): Pointer; cdecl; - PyClass_New: function (ob1,ob2,ob3 : PPyObject): PPyObject; cdecl; - PyClass_IsSubclass: function (ob1, ob2 : PPyObject): integer cdecl; - Py_InitModule4: function( name: PAnsiChar; methods: PPyMethodDef; doc: PAnsiChar; - passthrough: PPyObject; Api_Version: Integer):PPyObject; cdecl; PyModule_Create2: function(moduledef: PPyModuleDef; Api_Version: Integer):PPyObject; cdecl; PyErr_BadArgument: function: integer; cdecl; PyErr_BadInternalCall: procedure; cdecl; PyErr_CheckSignals: function: integer; cdecl; PyErr_Clear: procedure; cdecl; - PyErr_Fetch: procedure( errtype, errvalue, errtraceback: PPPyObject); cdecl; + PyErr_Fetch: procedure(out errtype, errvalue, errtraceback: PPyObject); cdecl; PyErr_NoMemory: function: PPyObject; cdecl; PyErr_Occurred: function: PPyObject; cdecl; PyErr_Print: procedure; cdecl; @@ -1735,11 +1385,12 @@ TPythonInterface=class(TDynamicDll) PyErr_WarnEx: function (ob: PPyObject; text: PAnsiChar; stack_level: NativeInt): integer; cdecl; PyErr_WarnExplicit: function (ob: PPyObject; text: PAnsiChar; filename: PAnsiChar; lineno: integer; module: PAnsiChar; registry: PPyObject): integer; cdecl; PyImport_GetModuleDict: function: PPyObject; cdecl; - PyInt_FromLong: function( x: LongInt):PPyObject; cdecl; - PyArg_Parse: function( args: PPyObject; format: PAnsiChar {;....}) : Integer; cdecl varargs; - PyArg_ParseTuple: function( args: PPyObject; format: PAnsiChar {;...}): Integer; cdecl varargs; - PyArg_ParseTupleAndKeywords: function( args: PPyObject; kw: PPyObject; format: PAnsiChar; kwargs: PPAnsiChar {;...}): Integer; cdecl varargs; - Py_BuildValue: function( format: PAnsiChar {;...}): PPyObject; cdecl varargs; + + PyArg_Parse: TPyArg_Parse; + PyArg_ParseTuple: TPyArg_Parse; + PyArg_ParseTupleAndKeywords: TPyArg_ParseTupleAndKeywords; + Py_BuildValue: TPy_BuildValue; + Py_Initialize: procedure; cdecl; Py_Exit: procedure( RetVal: Integer); cdecl; PyEval_GetBuiltins: function: PPyObject; cdecl; @@ -1753,6 +1404,7 @@ TPythonInterface=class(TDynamicDll) PyDict_Values: function(mp: PPyObject):PPyObject; cdecl; PyDict_Items: function(mp: PPyObject):PPyObject; cdecl; PyDict_Size: function(mp: PPyObject):NativeInt; cdecl; + PyDict_Update: function (a: PPyObject; b: PPyObject):Integer; cdecl; PyDict_DelItemString: function(dp : PPyObject;key : PAnsiChar ):integer; cdecl; PyDict_New: function: PPyObject; cdecl; PyDict_GetItemString: function( dp: PPyObject; key: PAnsiChar): PPyObject; cdecl; @@ -1764,12 +1416,10 @@ TPythonInterface=class(TDynamicDll) PyRun_String: function( str: PAnsiChar; start: Integer; globals: PPyObject; locals: PPyObject): PPyObject; cdecl; PyRun_SimpleString: function( str: PAnsiChar): Integer; cdecl; - PyString_AsString: function( ob: PPyObject): PAnsiChar; cdecl; - PyString_AsStringAndSize: function( ob: PPyObject; var buffer: PAnsiChar; var size: NativeInt): integer; cdecl; - PySys_SetArgv: procedure( argc: Integer; argv: PPAnsiChar); cdecl; - PySys_SetArgv3000: procedure( argc: Integer; argv: PPWideChar); cdecl; + PyBytes_AsString: function( ob: PPyObject): PAnsiChar; cdecl; + PyBytes_AsStringAndSize: function( ob: PPyObject; var buffer: PAnsiChar; var size: NativeInt): integer; cdecl; + PySys_SetArgv: procedure( argc: Integer; argv: PPWCharT); cdecl; - PyCFunction_New: function(md:PPyMethodDef;ob:PPyObject):PPyObject; cdecl; PyCFunction_NewEx: function(md:PPyMethodDef;self, ob:PPyObject):PPyObject; cdecl; // Removed. Use PyEval_CallObjectWithKeywords with third argument nil // PyEval_CallObject: function(callable_obj, args:PPyObject):PPyObject; cdecl; @@ -1777,34 +1427,26 @@ TPythonInterface=class(TDynamicDll) PyEval_GetFrame:function :PPyObject; cdecl; PyEval_GetGlobals:function :PPyObject; cdecl; PyEval_GetLocals:function :PPyObject; cdecl; - //PyEval_GetOwner:function :PPyObject; cdecl; - PyEval_GetRestricted:function :integer; cdecl; PyEval_InitThreads:procedure; cdecl; PyEval_RestoreThread:procedure( tstate: PPyThreadState); cdecl; PyEval_SaveThread:function :PPyThreadState; cdecl; - PyFile_FromString:function (pc1,pc2:PAnsiChar):PPyObject; cdecl; PyFile_GetLine:function (ob:PPyObject;i:integer):PPyObject; cdecl; - PyFile_Name:function (ob:PPyObject):PPyObject; cdecl; - PyFile_SetBufSize:procedure(ob:PPyObject;i:integer); cdecl; - PyFile_SoftSpace:function (ob:PPyObject;i:integer):integer; cdecl; PyFile_WriteObject:function (ob1,ob2:PPyObject;i:integer):integer; cdecl; PyFile_WriteString:procedure(s:PAnsiChar;ob:PPyObject); cdecl; PyFloat_AsDouble:function (ob:PPyObject):DOUBLE; cdecl; PyFloat_FromDouble:function (db:double):PPyObject; cdecl; + PyFloat_FromString:function (str:PPyObject):PPyObject; cdecl; PyFunction_GetCode:function (ob:PPyObject):PPyObject; cdecl; PyFunction_GetGlobals:function (ob:PPyObject):PPyObject; cdecl; PyFunction_New:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyImport_AddModule:function (name:PAnsiChar):PPyObject; cdecl; - PyImport_GetMagicNumber:function :LONGINT; cdecl; + PyImport_GetMagicNumber:function :C_Long; cdecl; PyImport_ImportFrozenModule:function (key:PAnsiChar):integer; cdecl; PyImport_ImportModule:function (name:PAnsiChar):PPyObject; cdecl; PyImport_Import:function (name:PPyObject):PPyObject; cdecl; - //PyImport_Init:procedure; cdecl; PyImport_ReloadModule:function (ob:PPyObject):PPyObject; cdecl; - PyInstance_New:function (obClass, obArg, obKW:PPyObject):PPyObject; cdecl; - PyInt_AsLong:function (ob:PPyObject):LONGINT; cdecl; PyList_Append:function (ob1,ob2:PPyObject):integer; cdecl; PyList_AsTuple:function (ob:PPyObject):PPyObject; cdecl; PyList_GetItem:function (ob:PPyObject;i:NativeInt):PPyObject; cdecl; @@ -1817,15 +1459,16 @@ TPythonInterface=class(TDynamicDll) PyList_Size:function (ob:PPyObject):NativeInt; cdecl; PyList_Sort:function (ob:PPyObject):integer; cdecl; PyLong_AsDouble:function (ob:PPyObject):DOUBLE; cdecl; - PyLong_AsLong:function (ob:PPyObject):LONGINT; cdecl; + PyLong_AsLong:function (ob:PPyObject):C_Long; cdecl; PyLong_FromDouble:function (db:double):PPyObject; cdecl; - PyLong_FromLong:function (l:longint):PPyObject; cdecl; + PyLong_FromLong:function (l:C_Long):PPyObject; cdecl; PyLong_FromString:function (pc:PAnsiChar;var ppc:PAnsiChar;i:integer):PPyObject; cdecl; - PyLong_FromUnsignedLong:function(val:cardinal) : PPyObject; cdecl; - PyLong_AsUnsignedLong:function(ob:PPyObject) : Cardinal; cdecl; - PyLong_FromUnicode:function(ob:PPyObject; a, b : integer) : PPyObject; cdecl; - PyLong_FromLongLong:function(val:Int64) : PPyObject; cdecl; - PyLong_AsLongLong:function(ob:PPyObject) : Int64; cdecl; + PyLong_FromUnsignedLong:function(val:C_ULong): PPyObject; cdecl; + PyLong_AsUnsignedLong:function(ob:PPyObject): C_ULong; cdecl; + PyLong_FromUnicodeObject:function(ob:PPyObject; base : integer): PPyObject; cdecl; + PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl; + PyLong_FromUnsignedLongLong:function(val:UInt64) : PPyObject; cdecl; + PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl; PyLong_FromVoidPtr:function(p: Pointer): PPyObject; cdecl; PyMapping_Check:function (ob:PPyObject):integer; cdecl; PyMapping_GetItemString:function (ob:PPyObject;key:PAnsiChar):PPyObject; cdecl; @@ -1833,7 +1476,8 @@ TPythonInterface=class(TDynamicDll) PyMapping_HasKeyString:function (ob:PPyObject;key:PAnsiChar):integer; cdecl; PyMapping_Length:function (ob:PPyObject):NativeInt; cdecl; PyMapping_SetItemString:function (ob:PPyObject; key:PAnsiChar; value:PPyObject):integer; cdecl; - PyMethod_Class:function (ob:PPyObject):PPyObject; cdecl; + PyMapping_Keys:function(mp: PPyObject):PPyObject; cdecl; + PyMapping_Values:function(mp: PPyObject):PPyObject; cdecl; PyMethod_Function:function (ob:PPyObject):PPyObject; cdecl; PyMethod_New:function (ob1,ob2,ob3:PPyObject):PPyObject; cdecl; PyMethod_Self:function (ob:PPyObject):PPyObject; cdecl; @@ -1843,13 +1487,10 @@ TPythonInterface=class(TDynamicDll) PyNumber_Add:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_And:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_Check:function (ob:PPyObject):integer; cdecl; - PyNumber_Coerce:function (var ob1,ob2:PPyObject):integer; cdecl; - PyNumber_Divide:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_FloorDivide:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_TrueDivide:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_Divmod:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_Float:function (ob:PPyObject):PPyObject; cdecl; - PyNumber_Int:function (ob:PPyObject):PPyObject; cdecl; PyNumber_Invert:function (ob:PPyObject):PPyObject; cdecl; PyNumber_Long:function (ob:PPyObject):PPyObject; cdecl; PyNumber_Lshift:function (ob1,ob2:PPyObject):PPyObject; cdecl; @@ -1862,17 +1503,16 @@ TPythonInterface=class(TDynamicDll) PyNumber_Rshift:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_Subtract:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyNumber_Xor:function (ob1,ob2:PPyObject):PPyObject; cdecl; - PyOS_InitInterrupts:procedure; cdecl; PyOS_InterruptOccurred:function :integer; cdecl; PyObject_CallObject:function (ob,args:PPyObject):PPyObject; cdecl; PyObject_CallMethod : function ( obj : PPyObject; method, format : PAnsiChar {...}) : PPyObject; cdecl varargs; - PyObject_Compare: function (ob1,ob2:PPyObject):integer; cdecl; PyObject_RichCompare:function (ob1,ob2:PPyObject;opid:integer):PPyObject; cdecl; PyObject_RichCompareBool:function (ob1,ob2:PPyObject;opid:integer):Integer; cdecl; PyObject_GetAttr:function (ob1,ob2:PPyObject):PPyObject; cdecl; PyObject_GetAttrString:function (ob:PPyObject;c:PAnsiChar):PPyObject; cdecl; PyObject_GetItem:function (ob,key:PPyObject):PPyObject; cdecl; PyObject_DelItem:function (ob,key:PPyObject):PPyObject; cdecl; + PyObject_HasAttr:function (ob, attr_name:PPyObject):integer; cdecl; PyObject_HasAttrString:function (ob:PPyObject;key:PAnsiChar):integer; cdecl; PyObject_Hash:function (ob:PPyObject):NativeInt; cdecl; PyObject_IsTrue:function (ob:PPyObject):integer; cdecl; @@ -1893,7 +1533,7 @@ TPythonInterface=class(TDynamicDll) PyObject_Call:function (ob, args, kw:PPyObject):PPyObject; cdecl; PyObject_GenericGetAttr:function (obj, name : PPyObject) : PPyObject; cdecl; PyObject_GenericSetAttr:function (obj, name, value : PPyObject) : Integer; cdecl; - PyObject_GC_Malloc:function (size:NativeUInt):PPyObject; cdecl; + PyObject_Malloc:function (size:NativeUInt):PPyObject; cdecl; PyObject_GC_New:function (t:PPyTypeObject):PPyObject; cdecl; PyObject_GC_NewVar:function (t:PPyTypeObject; size:NativeInt):PPyObject; cdecl; PyObject_GC_Resize:function (t:PPyObject; newsize:NativeInt):PPyObject; cdecl; @@ -1914,25 +1554,23 @@ TPythonInterface=class(TDynamicDll) PySequence_DelSlice:function (ob:PPyObject;i1,i2:NativeInt):integer; cdecl; PySequence_Tuple:function (ob:PPyObject):PPyObject; cdecl; PySequence_Contains:function (ob, value:PPyObject):integer; cdecl; + PySequence_List:function (o:PPyObject):PPyObject; cdecl; PySeqIter_New: function(obj : PPyObject) : PPyObject; cdecl; PySlice_GetIndices:function (ob:PPySliceObject;length:NativeInt;var start,stop,step:NativeInt):integer; cdecl; PySlice_GetIndicesEx:function (ob:PPySliceObject;length:NativeInt;var start,stop,step,slicelength:NativeInt):integer; cdecl; PySlice_New:function (start,stop,step:PPyObject):PPyObject; cdecl; - PyString_Concat:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl; - PyString_ConcatAndDel:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl; - PyString_Format:function (ob1,ob2:PPyObject):PPyObject; cdecl; - PyString_FromStringAndSize:function (s:PAnsiChar;i:NativeInt):PPyObject; cdecl; - PyString_Size:function (ob:PPyObject):NativeInt; cdecl; - PyString_DecodeEscape:function(s:PAnsiChar; len:NativeInt; errors:PAnsiChar; unicode:NativeInt; recode_encoding:PAnsiChar):PPyObject; cdecl; - PyString_Repr:function(ob:PPyObject; smartquotes:integer):PPyObject; cdecl; + PyBytes_Concat:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl; + PyBytes_ConcatAndDel:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl; + PyBytes_FromString:function (s:PAnsiChar):PPyObject; cdecl; + PyBytes_FromStringAndSize:function (s:PAnsiChar;i:NativeInt):PPyObject; cdecl; + PyBytes_Size:function (ob:PPyObject):NativeInt; cdecl; + PyBytes_DecodeEscape:function(s:PAnsiChar; len:NativeInt; errors:PAnsiChar; unicode:NativeInt; recode_encoding:PAnsiChar):PPyObject; cdecl; + PyBytes_Repr:function(ob:PPyObject; smartquotes:integer):PPyObject; cdecl; PySys_GetObject:function (s:PAnsiChar):PPyObject; cdecl; - //PySys_Init:procedure; cdecl; PySys_SetObject:function (s:PAnsiChar;ob:PPyObject):integer; cdecl; PySys_SetPath:procedure(path:PAnsiChar); cdecl; - //PyTraceBack_Fetch:function :PPyObject; cdecl; PyTraceBack_Here:function (p:pointer):integer; cdecl; PyTraceBack_Print:function (ob1,ob2:PPyObject):integer; cdecl; - //PyTraceBack_Store:function (ob:PPyObject):integer; cdecl; PyTuple_GetItem:function (ob:PPyObject;i:NativeInt):PPyObject; cdecl; PyTuple_GetSlice:function (ob:PPyObject;i1,i2:NativeInt):PPyObject; cdecl; PyTuple_New:function (size:NativeInt):PPyObject; cdecl; @@ -1942,52 +1580,49 @@ TPythonInterface=class(TDynamicDll) PyType_GenericAlloc:function(atype: PPyTypeObject; nitems:NativeInt) : PPyObject; cdecl; PyType_GenericNew:function(atype: PPyTypeObject; args, kwds : PPyObject) : PPyObject; cdecl; PyType_Ready:function(atype: PPyTypeObject) : integer; cdecl; - PyUnicode_FromWideChar:function (const w:PWideChar; size:NativeInt):PPyObject; cdecl; - PyUnicode_AsWideChar:function (unicode: PPyObject; w:PWideChar; size:NativeInt):integer; cdecl; + PyUnicode_FromWideChar:function (const w:PWCharT; size:NativeInt):PPyObject; cdecl; + PyUnicode_FromString:function (s:PAnsiChar):PPyObject; cdecl; + PyUnicode_FromStringAndSize:function (s:PAnsiChar;i:NativeInt):PPyObject; cdecl; + PyUnicode_FromKindAndData:function (kind:integer;const buffer:pointer;size:NativeInt):PPyObject; cdecl; + PyUnicode_AsWideChar:function (unicode: PPyObject; w:PWCharT; size:NativeInt):integer; cdecl; + PyUnicode_AsUTF8:function (unicode: PPyObject):PAnsiChar; cdecl; + PyUnicode_AsUTF8AndSize:function (unicode: PPyObject; size: PNativeInt):PAnsiChar; cdecl; PyUnicode_Decode:function (const s:PAnsiChar; size: NativeInt; const encoding : PAnsiChar; const errors: PAnsiChar):PPyObject; cdecl; + PyUnicode_DecodeUTF16:function (const s:PAnsiChar; size: NativeInt; const errors: PAnsiChar; byteoder: PInteger):PPyObject; cdecl; PyUnicode_AsEncodedString:function (unicode:PPyObject; const encoding:PAnsiChar; const errors:PAnsiChar):PPyObject; cdecl; PyUnicode_FromOrdinal:function (ordinal:integer):PPyObject; cdecl; - PyUnicode_FromString:function (s:PAnsiChar):PPyObject; cdecl; - PyUnicode_GetSize:function (unicode:PPyObject):NativeInt; cdecl; + PyUnicode_GetLength:function (unicode:PPyObject):NativeInt; cdecl; PyWeakref_GetObject: function ( ref : PPyObject) : PPyObject; cdecl; PyWeakref_NewProxy: function ( ob, callback : PPyObject) : PPyObject; cdecl; PyWeakref_NewRef: function ( ob, callback : PPyObject) : PPyObject; cdecl; PyWrapper_New: function ( ob1, ob2 : PPyObject) : PPyObject; cdecl; PyBool_FromLong: function ( ok : Integer) : PPyObject; cdecl; - PyThreadState_SetAsyncExc: function(t_id :LongInt; exc :PPyObject) : Integer; cdecl; + PyThreadState_SetAsyncExc: function(t_id:C_ULong; exc:PPyObject) : Integer; cdecl; Py_AtExit:function (proc: AtExitProc):integer; cdecl; - //Py_Cleanup:procedure; cdecl; - Py_CompileStringFlags:function (s1,s2:PAnsiChar;i:integer;flags:PPyCompilerFlags):PPyObject; cdecl; - Py_CompileStringExFlags:function (s1,s2:PAnsiChar;i:integer;flags:PPyCompilerFlags;optimize:integer):PPyObject; cdecl; + Py_CompileStringExFlags:function (str,filename:PAnsiChar;start:integer;flags:PPyCompilerFlags;optimize:integer):PPyObject; cdecl; Py_FatalError:procedure(s:PAnsiChar); cdecl; - Py_FindMethod:function (md:PPyMethodDef;ob:PPyObject;key:PAnsiChar):PPyObject; cdecl; - Py_FindMethodInChain:function (mc:PPyMethodChain;ob:PPyObject;key:PAnsiChar):PPyObject; cdecl; _PyObject_New:function (obt:PPyTypeObject;ob:PPyObject):PPyObject; cdecl; - _PyString_Resize:function (var ob:PPyObject;i:NativeInt):integer; cdecl; + _PyBytes_Resize:function (var ob:PPyObject;i:NativeInt):integer; cdecl; Py_Finalize : procedure; cdecl; PyErr_ExceptionMatches : function ( exc : PPyObject) : Integer; cdecl; PyErr_GivenExceptionMatches : function ( raised_exc, exc : PPyObject) : Integer; cdecl; - PyEval_EvalCode : function ( co : PPyCodeObject; globals, locals : PPyObject) : PPyObject; cdecl; + PyEval_EvalCode : function ( co : PPyObject; globals, locals : PPyObject) : PPyObject; cdecl; Py_GetVersion : function : PAnsiChar; cdecl; Py_GetCopyright : function : PAnsiChar; cdecl; - Py_GetExecPrefix : function : PAnsiChar; cdecl; - Py_GetPath : function : PAnsiChar; cdecl; - Py_SetPythonHome : procedure (home : PAnsiChar); cdecl; - Py_GetPythonHome : function : PAnsiChar; cdecl; - Py_SetPythonHome3000 : procedure (home : PWideChar); cdecl; - Py_GetPythonHome3000 : function : PWideChar; cdecl; - Py_GetPrefix : function : PAnsiChar; cdecl; - Py_GetProgramName : function : PAnsiChar; cdecl; + Py_GetExecPrefix : function : PWCharT; cdecl; + Py_GetPath : function : PWCharT; cdecl; + Py_SetPath : procedure (path: PWCharT); cdecl; + Py_SetPythonHome : procedure (home : PWCharT); cdecl; + Py_GetPythonHome : function : PWCharT; cdecl; + Py_GetPrefix : function : PWCharT; cdecl; + Py_GetProgramName : function : PWCharT; cdecl; PyParser_SimpleParseStringFlags : function ( str : PAnsiChar; start, flags : Integer) : PNode; cdecl; PyNode_Free : procedure( n : PNode ); cdecl; PyErr_NewException : function ( name : PAnsiChar; base, dict : PPyObject ) : PPyObject; cdecl; - Py_Malloc : function ( size : NativeInt ) : Pointer; - PyMem_Malloc : function ( size : NativeInt ) : Pointer; + PyMem_Malloc : function ( size : NativeUInt ) : Pointer; -{New exported Objects in Python 1.5} - Py_SetProgramName : procedure( name: PAnsiChar); cdecl; - Py_SetProgramName3000 : procedure( name: PWideChar); cdecl; + Py_SetProgramName : procedure( name: PWCharT); cdecl; Py_IsInitialized : function : integer; cdecl; Py_GetProgramFullPath : function : PAnsiChar; cdecl; Py_NewInterpreter : function : PPyThreadState; cdecl; @@ -2007,94 +1642,63 @@ TPythonInterface=class(TDynamicDll) PyErr_SetInterrupt : procedure; cdecl; PyGILState_Ensure : function() : PyGILstate_STATE; cdecl; PyGILState_Release : procedure(gilstate : PyGILState_STATE); cdecl; -{Further exported Objects, may be implemented later} -{ - PyCode_New: Pointer; - PyFile_AsFile: Pointer; - PyFile_FromFile: Pointer; - PyFloat_AsString: Pointer; - PyFrame_BlockPop: Pointer; - PyFrame_BlockSetup: Pointer; - PyFrame_ExtendStack: Pointer; - PyFrame_FastToLocals: Pointer; - PyFrame_LocalsToFast: Pointer; - PyFrame_New: Pointer; - PyGrammar_AddAccelerators: Pointer; - PyGrammar_FindDFA: Pointer; - PyGrammar_LabelRepr: Pointer; - PyInstance_DoBinOp: Pointer; - PyInt_GetMax: Pointer; - PyMarshal_Init: Pointer; - PyMarshal_ReadLongFromFile: Pointer; - PyMarshal_ReadObjectFromFile: Pointer; - PyMarshal_ReadObjectFromString: Pointer; - PyMarshal_WriteLongToFile: Pointer; - PyMarshal_WriteObjectToFile: Pointer; - PyMember_Get: Pointer; - PyMember_Set: Pointer; - PyNode_AddChild: Pointer; - PyNode_Compile: Pointer; - PyNode_New: Pointer; - PyOS_GetLastModificationTime: Pointer; - PyOS_Readline: Pointer; - PyOS_strtol: Pointer; - PyOS_strtoul: Pointer; - PyObject_CallFunction: Pointer; - PyObject_Print: Pointer; - PyParser_AddToken: Pointer; - PyParser_Delete: Pointer; - PyParser_New: Pointer; - PyParser_ParseFile: Pointer; - PyParser_ParseString: Pointer; - PyParser_SimpleParseFile: Pointer; - PyRun_AnyFile: Pointer; - PyRun_File: Pointer; - PyRun_InteractiveLoop: Pointer; - PyRun_InteractiveOne: Pointer; - PyRun_SimpleFile: Pointer; - PySys_GetFile: Pointer; - PyToken_OneChar: Pointer; - PyToken_TwoChars: Pointer; - PyTokenizer_Free: Pointer; - PyTokenizer_FromFile: Pointer; - PyTokenizer_FromString: Pointer; - PyTokenizer_Get: Pointer; - Py_Main: Pointer; - _PyParser_Grammar: Pointer; - _PyParser_TokenNames: Pointer; - _PyThread_Started: Pointer; - _Py_c_diff: Pointer; - _Py_c_neg: Pointer; - _Py_c_pow: Pointer; - _Py_c_prod: Pointer; - _Py_c_quot: Pointer; - _Py_c_sum: Pointer; -} - // Not exported in Python 3.8 and implemented as functions - function PyParser_SimpleParseString( str : PAnsiChar; start : Integer) : PNode; cdecl; - function Py_CompileString( s1,s2:PAnsiChar;i:integer) : PPyObject; cdecl; + // Not exported in Python 3.8 and implemented as functions - this has been fixed + // TODO - deal with the following: + // the PyParser_* functions are deprecated in python 3.9 and will be removed in + // Python 3.10 + function PyParser_SimpleParseString(str : PAnsiChar; start : Integer) : PNode; cdecl; + function Py_CompileString(str,filename:PAnsiChar;start:integer) : PPyObject; cdecl; // functions redefined in Delphi - procedure Py_INCREF ( op: PPyObject); - procedure Py_DECREF ( op: PPyObject); - procedure Py_XINCREF ( op: PPyObject); - procedure Py_XDECREF ( op: PPyObject); - - function PyCode_Addr2Line( co: PPyCodeObject; addrq : Integer ) : Integer; cdecl; - function Py_GetBuildInfo: PAnsiChar; cdecl; - function PyImport_ExecCodeModule( const AName : AnsiString; codeobject : PPyObject) : PPyObject; - function PyString_Check( obj : PPyObject ) : Boolean; - function PyString_CheckExact( obj : PPyObject ) : Boolean; + class procedure Py_INCREF(op: PPyObject); static; inline; + class procedure Py_DECREF(op: PPyObject); static; inline; + class procedure Py_XINCREF(op: PPyObject); static; inline; + class procedure Py_XDECREF(op: PPyObject); static; inline; + (* Safely decref `op` and set `op` to NULL, especially useful in tp_clear + * and tp_dealloc implementations. + * + * Note that "the obvious" code can be deadly: + * + * Py_XDECREF(op); + * op = NULL; + * + * Typically, `op` is something like self->containee, and `self` is done + * using its `containee` member. In the code sequence above, suppose + * `containee` is non-NULL with a refcount of 1. Its refcount falls to + * 0 on the first line, which can trigger an arbitrary amount of code, + * possibly including finalizers (like __del__ methods or weakref callbacks) + * coded in Python, which in turn can release the GIL and allow other threads + * to run, etc. Such code may even invoke methods of `self` again, or cause + * cyclic gc to trigger, but-- oops! --self->containee still points to the + * object being torn down, and it may be in an insane state while being torn + * down. This has in fact been a rich historic source of miserable (rare & + * hard-to-diagnose) segfaulting (and other) bugs. + * + * The safe way is: + * + * Py_CLEAR(op); + * + * That arranges to set `op` to NULL _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * There are cases where it's safe to use the naive code, but they're brittle. + * For example, if `op` points to a Python integer, you know that destroying + * one of those can't cause problems -- but in part that relies on that + * Python integers aren't currently weakly referencable. Best practice is + * to use Py_CLEAR() even if you can't think of a reason for why you need to. + *) + class procedure Py_CLEAR(var op: PPyObject); static; inline; + + function PyBytes_Check( obj : PPyObject ) : Boolean; + function PyBytes_CheckExact( obj : PPyObject ) : Boolean; function PyFloat_Check( obj : PPyObject ) : Boolean; function PyFloat_CheckExact( obj : PPyObject ) : Boolean; - function PyInt_Check( obj : PPyObject ) : Boolean; - function PyInt_CheckExact( obj : PPyObject ) : Boolean; function PyLong_Check( obj : PPyObject ) : Boolean; function PyLong_CheckExact( obj : PPyObject ) : Boolean; function PyTuple_Check( obj : PPyObject ) : Boolean; function PyTuple_CheckExact( obj : PPyObject ) : Boolean; - function PyInstance_Check( obj : PPyObject ) : Boolean; function PyClass_Check( obj : PPyObject ) : Boolean; function PyType_CheckExact( obj : PPyObject ) : Boolean; function PyMethod_Check( obj : PPyObject ) : Boolean; @@ -2115,14 +1719,9 @@ TPythonInterface=class(TDynamicDll) function PyWeakref_CheckRef( obj : PPyObject ) : Boolean; function PyWeakref_CheckProxy( obj : PPyObject ) : Boolean; function PyBool_Check( obj : PPyObject ) : Boolean; - function PyBaseString_Check( obj : PPyObject ) : Boolean; function PyEnum_Check( obj : PPyObject ) : Boolean; function PyObject_TypeCheck(obj:PPyObject; t:PPyTypeObject) : Boolean; - function Py_InitModule( const AName : PAnsiChar; md : PPyMethodDef) : PPyObject; - function Py_InitModule3000( const md : PyModuleDef) : PPyObject; - function PyString_FromString( str: PAnsiChar): PPyObject; virtual; abstract; - function PyString_AsDelphiString( ob: PPyObject): AnsiString; virtual; abstract; - procedure Py_FlushLine; cdecl; + function Py_InitModule( const md : PyModuleDef) : PPyObject; // Constructors & Destructors constructor Create(AOwner: TComponent); override; @@ -2133,7 +1732,6 @@ TPythonInterface=class(TDynamicDll) // Public properties property Initialized : Boolean read FInitialized; property Finalizing : Boolean read FFinalizing; - property IsPython3000 : Boolean read FIsPython3000; property MajorVersion : integer read FMajorVersion; property MinorVersion : integer read FMinorVersion; property BuiltInModuleName: String read FBuiltInModuleName write FBuiltInModuleName; @@ -2154,8 +1752,8 @@ TPythonInterface=class(TDynamicDll) TEngineClient = class; TPathInitializationEvent = procedure ( Sender : TObject; var Path : String ) of Object; TSysPathInitEvent = procedure ( Sender : TObject; PathList : PPyObject ) of Object; - TPythonFlag = (pfDebug, pfInteractive, pfNoSite, pfOptimize, pfTabcheck, pfUnicode, pfVerbose, - pfUseClassExceptionsFlag, pfFrozenFlag, pfIgnoreEnvironmentFlag, pfDivisionWarningFlag); + TPythonFlag = (pfDebug, pfInteractive, pfNoSite, pfOptimize, pfVerbose, + pfFrozenFlag, pfIgnoreEnvironmentFlag); TPythonFlags = set of TPythonFlag; @@ -2178,30 +1776,32 @@ TPythonTraceback = class destructor Destroy; override; procedure Clear; - procedure Refresh; + procedure Refresh(pytraceback: PPyObject = nil); + procedure AddItem(const Context, FileName: string; LineNo: Integer); property ItemCount : Integer read GetItemCount; property Items[ idx : Integer ] : TTracebackItem read GetItem; property Limit : Integer read FLimit write FLimit; end; + TPythonType = class; //forward declaration + {$IF not Defined(FPC) and (CompilerVersion >= 23)} [ComponentPlatformsAttribute(pidWin32 or pidWin64)] {$IFEND} TPythonEngine = class(TPythonInterface) private + FVenvPythonExe: string; FInitScript: TStrings; FIO: TPythonInputOutput; FRedirectIO: Boolean; FOnAfterInit: TNotifyEvent; FClients: TList; - FLock: TCriticalSection; FExecModule: AnsiString; FAutoFinalize: Boolean; - FProgramName: AnsiString; - FProgramNameW: UnicodeString; - FPythonHome: AnsiString; - FPythonHomeW: UnicodeString; + FProgramName: WCharTString; + FPythonHome: WCharTString; + FPythonPath: WCharTString; FInitThreads: Boolean; FOnPathInitialization: TPathInitializationEvent; FOnSysPathInit: TSysPathInitEvent; @@ -2221,14 +1821,19 @@ TPythonEngine = class(TPythonInterface) FPyDateTime_TZInfoType: PPyObject; FPyDateTime_TimeTZType: PPyObject; FPyDateTime_DateTimeTZType: PPyObject; + function GetPythonHome: UnicodeString; + function GetProgramName: UnicodeString; + function GetPythonPath: UnicodeString; + procedure SetPythonPath(const Value: UnicodeString); protected + procedure Initialize; + procedure Finalize; procedure AfterLoad; override; procedure BeforeLoad; override; procedure DoOpenDll(const aDllName : String); override; procedure SetInitScript(Value: TStrings); function GetThreadState: PPyThreadState; - function GetInterpreterState: PPyInterpreterState; procedure SetInitThreads(Value: Boolean); function GetClientCount : Integer; function GetClients( idx : Integer ) : TEngineClient; @@ -2249,26 +1854,29 @@ TPythonEngine = class(TPythonInterface) destructor Destroy; override; // Public methods - procedure Initialize; - procedure Finalize; - procedure Lock; - procedure Unlock; - procedure SetPythonHome(const PythonHome: String); + procedure SetPythonHome(const PythonHome: UnicodeString); + procedure SetProgramName(const ProgramName: UnicodeString); function IsType(ob: PPyObject; obt: PPyTypeObject): Boolean; - function GetAttrString(obj: PPyObject; AName: PAnsiChar):PAnsiChar; - function Run_CommandAsString(const command : AnsiString; mode : Integer) : String; - function Run_CommandAsObject(const command : AnsiString; mode : Integer) : PPyObject; inline; - function Run_CommandAsObjectWithDict(const command : AnsiString; mode : Integer; locals, globals : PPyObject) : PPyObject; - procedure ExecString(const command : AnsiString); overload; inline; - procedure ExecStrings( strings : TStrings ); overload; - function EvalString(const command : AnsiString) : PPyObject; overload; inline; - function EvalStringAsStr(const command : AnsiString) : String; inline; - function EvalStrings( strings : TStrings ) : PPyObject; overload; - procedure ExecString(const command : AnsiString; locals, globals : PPyObject ); overload; inline; - procedure ExecStrings( strings : TStrings; locals, globals : PPyObject ); overload; - function EvalString( const command : AnsiString; locals, globals : PPyObject ) : PPyObject; overload; inline; - function EvalStrings( strings : TStrings; locals, globals : PPyObject ) : PPyObject; overload; - function EvalStringsAsStr( strings : TStrings ) : String; + function Run_CommandAsString(const command: AnsiString; mode: Integer; const FileName: string = '<string>'): string; + function Run_CommandAsObject(const command: AnsiString; mode: Integer; const FileName: string = '<string>'): PPyObject; + function Run_CommandAsObjectWithDict(const command: AnsiString; mode: Integer; locals, globals: PPyObject; const FileName: string = '<string>'): PPyObject; + function EncodeString (const str: UnicodeString): AnsiString; {$IFDEF FPC}overload;{$ENDIF} + {$IFDEF FPC} + overload; + function EncodeString (const str: AnsiString): AnsiString; overload; + {$ENDIF} + function EncodeWindowsFilePath(const str: string): AnsiString; + procedure ExecString(const command: AnsiString; const FileName: string = '<string>'); overload; + procedure ExecStrings(strings: TStrings; const FileName: string = '<string>'); overload; + procedure ExecString(const command: AnsiString; locals, globals: PPyObject; const FileName: string = '<string>'); overload; + procedure ExecFile(const FileName: string; locals: PPyObject = nil; globals: PPyObject = nil); overload; + procedure ExecStrings(strings: TStrings; locals, globals: PPyObject; const FileName: string = '<string>'); overload; + function EvalString(const command: AnsiString; const FileName: string = '<string>'): PPyObject; overload; + function EvalStringAsStr(const command: AnsiString; const FileName: string = '<string>'): string; + function EvalStrings(strings: TStrings; const FileName: string = '<string>'): PPyObject; overload; + function EvalString(const command: AnsiString; locals, globals: PPyObject; const FileName: string = '<string>'): PPyObject; overload; + function EvalStrings(strings: TStrings; locals, globals: PPyObject; const FileName: string = '<string>'): PPyObject; overload; + function EvalStringsAsStr(strings: TStrings; const FileName: string = '<string>'): string; function EvalPyFunction(pyfunc, pyargs:PPyObject): Variant; function EvalFunction(pyfunc:PPyObject; args: array of const): Variant; function EvalFunctionNoArgs(pyfunc:PPyObject): Variant; @@ -2281,6 +1889,7 @@ TPythonEngine = class(TPythonInterface) procedure AddClient( client : TEngineClient ); procedure RemoveClient( client : TEngineClient ); function FindClient( const aName : AnsiString ) : TEngineClient; + function FindPythonType( const TypeName : AnsiString ) : TPythonType; function TypeByName( const aTypeName : AnsiString ) : PPyTypeObject; function ModuleByName( const aModuleName : AnsiString ) : PPyObject; function MethodsByName( const aMethodsContainer: AnsiString ) : PPyMethodDef; @@ -2294,11 +1903,11 @@ TPythonEngine = class(TPythonInterface) function ArrayToPyDict( items : array of const) : PPyObject; function StringsToPyList( strings : TStrings ) : PPyObject; function StringsToPyTuple( strings : TStrings ) : PPyObject; - procedure PyListToStrings( list : PPyObject; strings : TStrings ); + procedure PyListToStrings(list: PPyObject; Strings: TStrings; ClearStrings: Boolean = True); procedure PyTupleToStrings( tuple: PPyObject; strings : TStrings ); - function PyUnicode_AsWideString( obj : PPyObject ) : UnicodeString; - function PyUnicode_FromWideString( const AString : UnicodeString) : PPyObject; function ReturnNone : PPyObject; + function ReturnTrue : PPyObject; + function ReturnFalse : PPyObject; function FindModule( const ModuleName : AnsiString ) : PPyObject; function FindFunction(ModuleName,FuncName: AnsiString): PPyObject; function SetToList( data : Pointer; size : Integer ) : PPyObject; @@ -2318,23 +1927,29 @@ TPythonEngine = class(TPythonInterface) function PyTZInfo_Check( obj : PPyObject ) : Boolean; function PyTZInfo_CheckExact( obj : PPyObject ) : Boolean; { end date/time functions } - function PyString_FromString( str: PAnsiChar): PPyObject; override; - function PyString_AsDelphiString( ob: PPyObject): AnsiString; override; - function PyString_AsAnsiString( ob: PPyObject): AnsiString; - function PyString_AsWideString( ob: PPyObject): UnicodeString; + + { String conversion } + function PyUnicodeFromString(const AString : UnicodeString) : PPyObject; overload; + function PyUnicodeFromString(const AString: AnsiString): PPyObject; overload; + function PyUnicodeAsString( obj : PPyObject ) : UnicodeString; + function PyUnicodeAsUTF8String( obj : PPyObject ) : RawByteString; + function PyBytesAsAnsiString( obj : PPyObject ) : AnsiString; // Public Properties property ClientCount : Integer read GetClientCount; property Clients[ idx : Integer ] : TEngineClient read GetClients; property ExecModule : AnsiString read FExecModule write FExecModule; property ThreadState: PPyThreadState read GetThreadState; - property InterpreterState: PPyInterpreterState read GetInterpreterState; property Traceback : TPythonTraceback read FTraceback; property LocalVars : PPyObject read FLocalVars Write SetLocalVars; property GlobalVars : PPyObject read FGlobalVars Write SetGlobalVars; property IOPythonModule: TObject read FIOPythonModule; {TPythonModule} + property PythonHome: UnicodeString read GetPythonHome write SetPythonHome; + property ProgramName: UnicodeString read GetProgramName write SetProgramName; + property PythonPath: UnicodeString read GetPythonPath write SetPythonPath; published property AutoFinalize: Boolean read FAutoFinalize write FAutoFinalize default True; + property VenvPythonExe: string read FVenvPythonExe write FVenvPythonExe; property DatetimeConversionMode: TDatetimeConversionMode read FDatetimeConversionMode write FDatetimeConversionMode default DEFAULT_DATETIME_CONVERSION_MODE; property InitScript: TStrings read FInitScript write SetInitScript; property InitThreads: Boolean read FInitThreads write SetInitThreads default False; @@ -2365,8 +1980,6 @@ TEngineClient = class(TComponent) procedure SetEngine( val : TPythonEngine ); virtual; procedure Loaded; override; - procedure Notification( AComponent: TComponent; - Operation: TOperation); override; procedure ModuleReady(Sender : TObject); virtual; public // Constructors & destructors @@ -2453,7 +2066,7 @@ TMethodsContainer = class(TEngineClient) FMethodCount : Integer; FAllocatedMethodCount : Integer; FMethods : PPyMethodDef; - FModuleDef : PyModuleDef; // for Python 3000 + FModuleDef : PyModuleDef; FEventDefs: TEventDefs; procedure AllocMethods; @@ -2479,6 +2092,12 @@ TMethodsContainer = class(TEngineClient) function AddMethodWithKeywords( AMethodName : PAnsiChar; AMethod : PyCFunctionWithKW; ADocString : PAnsiChar ) : PPyMethodDef; + function AddClassMethodWithKeywords( AMethodName : PAnsiChar; + AMethod : PyCFunctionWithKW; + ADocString : PAnsiChar ) : PPyMethodDef; + function AddStaticMethodWithKeywords( AMethodName : PAnsiChar; + AMethod : PyCFunctionWithKW; + ADocString : PAnsiChar ) : PPyMethodDef; function AddDelphiMethod( AMethodName : PAnsiChar; ADelphiMethod: TDelphiMethod; ADocString : PAnsiChar ) : PPyMethodDef; @@ -2680,7 +2299,8 @@ TPythonModule = class(TMethodsContainer) procedure DefineDocString; procedure Initialize; override; procedure InitializeForNewInterpreter; - procedure AddClient( client : TEngineClient ); + procedure AddClient(Client : TEngineClient); + procedure RemoveClient(Client : TEngineClient); function ErrorByName( const AName : AnsiString ) : TError; procedure RaiseError( const error, msg : AnsiString ); procedure RaiseErrorFmt( const error, format : AnsiString; Args : array of const ); @@ -2711,9 +2331,6 @@ TPythonModule = class(TMethodsContainer) //-- -- //------------------------------------------------------- -type - TPythonType = class; //forward declaration - { A B C +-------------------++------------------------------------------------------+ @@ -2755,7 +2372,7 @@ TPyObject = class // Constructors & Destructors constructor Create( APythonType : TPythonType ); virtual; - constructor CreateWith( APythonType : TPythonType; args : PPyObject ); virtual; + constructor CreateWith(APythonType: TPythonType; args, kwds: PPyObject); virtual; destructor Destroy; override; class function NewInstance: TObject; override; @@ -2795,7 +2412,6 @@ TPyObject = class function NbAdd( obj : PPyObject) : PPyObject; virtual; function NbSubtract( obj : PPyObject) : PPyObject; virtual; function NbMultiply( obj : PPyObject) : PPyObject; virtual; - function NbDivide( obj : PPyObject) : PPyObject; virtual; function NbFloorDivide( obj : PPyObject) : PPyObject; virtual; function NbTrueDivide( obj : PPyObject) : PPyObject; virtual; function NbMatrixMultiply( obj : PPyObject) : PPyObject; virtual; @@ -2805,7 +2421,6 @@ TPyObject = class function NbNegative : PPyObject; virtual; function NbPositive : PPyObject; virtual; function NbAbsolute : PPyObject; virtual; - function NbNonZero : Integer; virtual; function NbBool : Integer; virtual; function NbInvert : PPyObject; virtual; function NbLShift( obj : PPyObject) : PPyObject; virtual; @@ -2813,12 +2428,8 @@ TPyObject = class function NbAnd( obj : PPyObject) : PPyObject; virtual; function NbXor( obj : PPyObject) : PPyObject; virtual; function NbOr( obj : PPyObject) : PPyObject; virtual; - function NbCoerce( obj : PPPyObject) : Integer; virtual; function NbInt : PPyObject; virtual; - function NbLong : PPyObject; virtual; function NbFloat : PPyObject; virtual; - function NbOct : PPyObject; virtual; - function NbHex : PPyObject; virtual; function NbInplaceAdd( obj : PPyObject): PPyObject; virtual; function NbInplaceSubtract( obj : PPyObject): PPyObject; virtual; function NbInplaceMultiply( obj : PPyObject): PPyObject; virtual; @@ -2838,9 +2449,7 @@ TPyObject = class function SqConcat( obj : PPyObject) : PPyObject; virtual; function SqRepeat( val : NativeInt ) : PPyObject; virtual; function SqItem( idx : NativeInt ) : PPyObject; virtual; - function SqSlice( idx1, idx2 : NativeInt ) : PPyObject; virtual; function SqAssItem( idx : NativeInt; obj : PPyObject) : Integer; virtual; - function SqAssSlice( idx1, idx2 : NativeInt; obj : PPyObject): integer; virtual; function SqContains( obj: PPyObject): integer; virtual; function SqInplaceConcat( obj : PPyObject): PPyObject; virtual; function SqInplaceRepeat( i: NativeInt): PPyObject; virtual; @@ -2857,7 +2466,7 @@ TPyObject = class end; TPyObjectClass = class of TPyObject; - TBasicServices = set of (bsPrint, bsGetAttr, bsSetAttr, + TBasicServices = set of (bsGetAttr, bsSetAttr, bsRepr, bsCompare, bsHash, bsStr, bsGetAttrO, bsSetAttrO, bsCall, @@ -2868,35 +2477,29 @@ TPyObjectClass = class of TPyObject; // since version 2.2 bsIter, bsIterNext); TNumberServices = set of (nsAdd, nsSubtract, nsMultiply, - nsDivide, nsRemainder, nsDivmod, + nsRemainder, nsDivmod, nsPower, nsNegative, nsPositive, - nsAbsolute, nsNonZero, nsInvert, + nsAbsolute, nsInvert, nsLShift, nsRShift, nsAnd, - nsXor, nsOr, nsCoerce, - nsInt, nsLong, nsFloat, - nsOct, nsHex, - // since version 2.2 + nsXor, nsOr, + nsInt, nsFloat, nsFloorDivide, nsTrueDivide, // since version 3.0 nsMatrixMultiply, nsBool); // TInplaceNumberServices exists since version 2.0 TInplaceNumberServices = set of (nsInplaceAdd, nsInplaceSubtract, - nsInplaceMultiply, nsInplaceDivide, + nsInplaceMultiply, nsInplaceRemainder, nsInplacePower, nsInplaceLShift, nsInplaceRShift, nsInplaceAnd, nsInplaceXor, nsInplaceOr, - // since version 2.2 nsInplaceFloorDivide, nsInplaceTrueDivide, // since version 3.0 nsInplaceMatrixMultiply); TSequenceServices = set of (ssLength, ssConcat, ssRepeat, - ssItem, ssSlice, ssAssItem, - ssAssSlice, - // since version 2.0 - ssContains, - ssInplaceConcat, + ssItem, ssAssItem, + ssContains, ssInplaceConcat, ssInplaceRepeat ); @@ -2936,7 +2539,7 @@ TPythonType = class(TGetSetContainer) FPrefix : AnsiString; FCreateFuncName : AnsiString; FServices : TTypeServices; - FNumber: Pointer; // points either to PyNumberMethods200 or PyNumberMethods300; + FNumber: PyNumberMethods; FSequence: PySequenceMethods; FMapping: PyMappingMethods; FCurrentDocString: AnsiString; @@ -2957,10 +2560,11 @@ TPythonType = class(TGetSetContainer) procedure SetModule( val : TPythonModule ); procedure SetServices( val : TTypeServices ); procedure SetTypeName( const val : AnsiString ); - function CreateMethod( pSelf, args : PPyObject ) : PPyObject; cdecl; + procedure SetBaseType(AType: TPythonType); + function CreateMethod(pSelf, args, kwds: PPyObject): PPyObject; cdecl; procedure InitServices; procedure SetDocString( value : TStringList ); - function TypeFlagsAsInt : LongInt; + function TypeFlagsAsInt : C_ULong; function GetMembersStartOffset : Integer; override; procedure ModuleReady(Sender : TObject); override; procedure ReallocMethods; override; @@ -2981,12 +2585,13 @@ TPythonType = class(TGetSetContainer) procedure Initialize; override; procedure Finalize; override; function CreateInstance : PPyObject; - function CreateInstanceWith( args : PPyObject ) : PPyObject; + function CreateInstanceWith(args, kwds: PPyObject): PPyObject; procedure AddTypeVar; property TheType : PyTypeObject read FType write FType; property TheTypePtr : PPyTypeObject read GetTypePtr; property PyObjectClass : TPyObjectClass read FPyObjectClass write SetPyObjectClass stored False; + property BaseType: TPythonType write SetBaseType; property InstanceCount : Integer read FInstanceCount; property CreateHits : Integer read FCreateHits; property DeleteHits : Integer read FDeleteHits; @@ -3069,15 +2674,15 @@ TPyVar = class(TPyObject) // Constructors & Destructors constructor Create( APythonType : TPythonType ); override; - constructor CreateWith( APythonType : TPythonType; args : PPyObject ); override; + constructor CreateWith(APythonType: TPythonType; args, kwds: PPyObject); override; destructor Destroy; override; // Type services //////////////// // Basic services - function GetAttr(key : PAnsiChar) : PPyObject; override; - function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override; + function GetAttrO( key: PPyObject) : PPyObject; override; + function SetAttrO( key, value: PPyObject) : Integer; override; function Repr : PPyObject; override; // Class methods @@ -3102,30 +2707,25 @@ TPyVar = class(TPyObject) {$HINTS OFF} TPythonThread = class(TThread) private - f_savethreadstate: PPyThreadState; - fInterpreterState: PPyInterpreterState; fThreadState: PPyThreadState; fThreadExecMode: TThreadExecMode; - -// Do not overwrite Execute! Use ExecuteWithPython instead! + private class {$if FPC_FULLVERSION>=30200} threadvar {$else} var {$endif} + f_savethreadstate: PPyThreadState; + private + // Do not overwrite Execute! Use ExecuteWithPython instead! procedure Execute; override; protected procedure ExecuteWithPython; virtual; abstract; - - procedure Py_Begin_Allow_Threads; - procedure Py_End_Allow_Threads; -// The following procedures are redundant and only for -// compatibility to the C API documentation. - procedure Py_Begin_Block_Threads; - procedure Py_Begin_Unblock_Threads; - public - property InterpreterState: PPyInterpreterState read fInterpreterState - write fInterpreterState - default nil; - property ThreadState: PPyThreadState read fThreadState - write fThreadState; - property ThreadExecMode: TThreadExecMode read fThreadExecMode; + class procedure Py_Begin_Allow_Threads; + class procedure Py_End_Allow_Threads; + // The following procedures are redundant and only for + // compatibility to the C API documentation. + class procedure Py_Begin_Block_Threads; + class procedure Py_Begin_Unblock_Threads; + + property ThreadState : PPyThreadState read fThreadState; + property ThreadExecMode: TThreadExecMode read fThreadExecMode write fThreadExecMode; end; {$HINTS ON} @@ -3163,6 +2763,8 @@ procedure PyObjectDestructor( pSelf : PPyObject); cdecl; procedure FreeSubtypeInst(ob:PPyObject); cdecl; procedure Register; function PyType_HasFeature(AType : PPyTypeObject; AFlag : Integer) : Boolean; +function SysVersionFromDLLName(const DLLFileName : string): string; +procedure PythonVersionFromDLLName(LibName: string; out MajorVersion, MinorVersion: integer); { Helper functions} (* @@ -3214,6 +2816,16 @@ function _IsBufferAscii(buf: PAnsiChar): boolean; inline; Result := true; end; +(*******************************************************) +(** **) +(** Resource strings **) +(** **) +(*******************************************************) +resourcestring +SPyConvertionError = 'Conversion Error: %s expects a %s Python object'; +SPyExcStopIteration = 'Stop Iteration'; +SPyExcSystemError = 'Unhandled SystemExit exception. Code: %s'; + (*******************************************************) (** **) (** Globals **) @@ -3395,7 +3007,8 @@ procedure TDynamicDll.DoOpenDll(const aDllName : String); FDLLHandle := Windows.LoadLibrary(PChar(S)); {$else} //Linux: need here RTLD_GLOBAL, so Python can do "import ctypes" - FDLLHandle := PtrInt(dlopen(PAnsiChar(S), RTLD_LAZY+RTLD_GLOBAL)); + //Haiku: without RTLD_NOW it doesn't seem to detect the library or plugins without running with "LD_PRELOAD ..." + FDLLHandle := PtrInt(dlopen(PAnsiChar(S), {$ifdef haiku}RTLD_NOW{$else}RTLD_LAZY{$endif}+RTLD_GLOBAL)); {$endif} end; end; @@ -3589,34 +3202,12 @@ constructor TPythonInterface.Create(AOwner: TComponent); FAutoUnload := True; end; -procedure TPythonInterface.DetectPythonVersionFromLibName(const Str: AnsiString); -var - NPos: integer; -begin - //Win: "python34.dll" - //Linux: "libpython3.4.so" - NPos := Pos('python', LowerCase(Str)); - if NPos>0 then - begin - Inc(NPos, Length('python')); - FIsPython3000 := Str[NPos]='3'; - FMajorVersion := StrToIntDef(Str[NPos], 3); - Inc(NPos); - if Str[NPos]='.' then - Inc(NPos); - FMinorVersion := StrToIntDef(Str[NPos], 3); - end; -end; - procedure TPythonInterface.AfterLoad; begin inherited; + PythonVersionFromDLLName(DLLName, FMajorVersion, FMinorVersion); - DetectPythonVersionFromLibName(DLLName); - if FIsPython3000 then - FBuiltInModuleName := 'builtins' - else - FBuiltInModuleName := '__builtin__'; + FBuiltInModuleName := 'builtins'; try MapDll; @@ -3644,54 +3235,20 @@ procedure TPythonInterface.CheckPython; raise Exception.Create('Python is not properly initialized' ); end; -// https://github.com/Alexey-T/Python-for-Lazarus/issues/16 -function TPythonInterface.GetUnicodeTypeSuffix : String; -begin - if (fMajorVersion > 3) or ((fMajorVersion = 3) and (fMinorVersion >= 3)) then - Result := '' - else - if APIVersion >= 1011 then - Result := - {$if defined(windows) or defined(darwin) or defined(solaris)} - 'UCS2' - {$else} - 'UCS4' - {$endif} - else - Result := ''; -end; - procedure TPythonInterface.MapDll; -var - UnicodeSuffix: AnsiString; begin - UnicodeSuffix:= GetUnicodeTypeSuffix; - Py_DebugFlag := Import('Py_DebugFlag'); Py_VerboseFlag := Import('Py_VerboseFlag'); Py_InteractiveFlag := Import('Py_InteractiveFlag'); Py_OptimizeFlag := Import('Py_OptimizeFlag'); Py_NoSiteFlag := Import('Py_NoSiteFlag'); Py_FrozenFlag := Import('Py_FrozenFlag'); - if not IsPython3000 then begin - Py_UseClassExceptionsFlag := Import('Py_UseClassExceptionsFlag'); - Py_TabcheckFlag := Import('Py_TabcheckFlag'); - Py_UnicodeFlag := Import('Py_UnicodeFlag'); - end; - if (fMajorVersion < 3) or ((fMajorVersion = 3) and (fMinorVersion <3)) then - Py_DivisionWarningFlag := Import('Py_DivisionWarningFlag'); Py_IgnoreEnvironmentFlag := Import('Py_IgnoreEnvironmentFlag'); - //_PySys_TraceFunc := Import('_PySys_TraceFunc'); - //_PySys_ProfileFunc := Import('_PySys_ProfileFunc'); - Py_None := Import('_Py_NoneStruct'); Py_Ellipsis := Import('_Py_EllipsisObject'); - if IsPython3000 then - Py_False := Import('_Py_FalseStruct') - else - Py_False := Import('_Py_ZeroStruct'); + Py_False := Import('_Py_FalseStruct'); Py_True := Import('_Py_TrueStruct'); Py_NotImplemented := Import('_Py_NotImplementedStruct'); @@ -3718,10 +3275,6 @@ procedure TPythonInterface.MapDll; PyExc_Exception := Import('PyExc_Exception'); PyExc_FloatingPointError := Import('PyExc_FloatingPointError'); PyExc_LookupError := Import('PyExc_LookupError'); - if not IsPython3000 then begin - PyExc_StandardError := Import('PyExc_StandardError'); - PyExc_MemoryErrorInst := Import('PyExc_MemoryErrorInst'); - end; PyExc_AssertionError := Import('PyExc_AssertionError'); PyExc_EnvironmentError := Import('PyExc_EnvironmentError'); PyExc_IndentationError := Import('PyExc_IndentationError'); @@ -3730,7 +3283,7 @@ procedure TPythonInterface.MapDll; PyExc_TabError := Import('PyExc_TabError'); PyExc_UnboundLocalError := Import('PyExc_UnboundLocalError'); PyExc_UnicodeError := Import('PyExc_UnicodeError'); - {$IFDEF windows} + {$IFDEF MSWINDOWS} PyExc_WindowsError := Import('PyExc_WindowsError'); {$ENDIF} PyExc_Warning := Import('PyExc_Warning'); @@ -3747,22 +3300,12 @@ procedure TPythonInterface.MapDll; PyExc_UnicodeTranslateError:= Import('PyExc_UnicodeTranslateError'); PyType_Type := Import('PyType_Type'); PyCFunction_Type := Import('PyCFunction_Type'); - if not IsPython3000 then begin - PyCObject_Type := Import('PyCObject_Type'); // Removed in Python 3.2 - PyClass_Type := Import('PyClass_Type'); - end; PyCode_Type := Import('PyCode_Type'); PyComplex_Type := Import('PyComplex_Type'); PyDict_Type := Import('PyDict_Type'); - if not IsPython3000 then - PyFile_Type := Import('PyFile_Type'); PyFloat_Type := Import('PyFloat_Type'); PyFrame_Type := Import('PyFrame_Type'); PyFunction_Type := Import('PyFunction_Type'); - if not IsPython3000 then - PyInstance_Type := Import('PyInstance_Type'); - if not IsPython3000 then - PyInt_Type := Import('PyInt_Type'); PyList_Type := Import('PyList_Type'); PyLong_Type := Import('PyLong_Type'); PyMethod_Type := Import('PyMethod_Type'); @@ -3770,15 +3313,10 @@ procedure TPythonInterface.MapDll; PyObject_Type := Import('PyObject_Type'); PyRange_Type := Import('PyRange_Type'); PySlice_Type := Import('PySlice_Type'); - if not IsPython3000 then - PyString_Type := Import('PyString_Type') - else - PyString_Type := Import('PyBytes_Type'); + PyBytes_Type := Import('PyBytes_Type'); PyTuple_Type := Import('PyTuple_Type'); PyUnicode_Type := Import('PyUnicode_Type'); PyBaseObject_Type := Import('PyBaseObject_Type'); - if not IsPython3000 then - PyBuffer_Type := Import('PyBuffer_Type'); PyCallIter_Type := Import('PyCallIter_Type'); PyCell_Type := Import('PyCell_Type'); PyClassMethod_Type := Import('PyClassMethod_Type'); @@ -3791,19 +3329,9 @@ procedure TPythonInterface.MapDll; _PyWeakref_RefType := Import('_PyWeakref_RefType'); _PyWeakref_ProxyType := Import('_PyWeakref_ProxyType'); _PyWeakref_CallableProxyType:=Import('_PyWeakref_CallableProxyType'); - if not IsPython3000 then - PyBaseString_Type := Import('PyBaseString_Type'); PyBool_Type := Import('PyBool_Type'); PyEnum_Type := Import('PyEnum_Type'); - //@PyArg_GetObject := Import('PyArg_GetObject'); - //@PyArg_GetLong := Import('PyArg_GetLong'); - //@PyArg_GetShort := Import('PyArg_GetShort'); - //@PyArg_GetFloat := Import('PyArg_GetFloat'); - //@PyArg_GetString := Import('PyArg_GetString'); - //@PyArgs_VaParse := Import('PyArgs_VaParse'); - //@Py_VaBuildValue := Import('Py_VaBuildValue'); - //@PyBuiltin_Init := Import('PyBuiltin_Init'); PyComplex_FromCComplex := Import('PyComplex_FromCComplex'); PyComplex_FromDoubles := Import('PyComplex_FromDoubles'); PyComplex_RealAsDouble := Import('PyComplex_RealAsDouble'); @@ -3812,12 +3340,6 @@ procedure TPythonInterface.MapDll; PyCFunction_GetFunction := Import('PyCFunction_GetFunction'); PyCFunction_GetSelf := Import('PyCFunction_GetSelf'); PyCallable_Check := Import('PyCallable_Check'); - if not IsPython3000 then begin - PyClass_New := Import('PyClass_New'); - PyClass_IsSubclass := Import('PyClass_IsSubclass'); - PyCObject_FromVoidPtr := Import('PyCObject_FromVoidPtr'); // Removed in Python 3.2 - PyCObject_AsVoidPtr := Import('PyCObject_AsVoidPtr'); - end; PyDict_GetItem := Import('PyDict_GetItem'); PyDict_SetItem := Import('PyDict_SetItem'); PyDict_DelItem := Import('PyDict_DelItem'); @@ -3829,11 +3351,11 @@ procedure TPythonInterface.MapDll; PyDict_Size := Import('PyDict_Size'); PyDict_DelItemString := Import('PyDict_DelItemString'); PyDict_Copy := Import('PyDict_Copy'); + PyDict_New := Import('PyDict_New'); + PyDict_Update := Import('PyDict_Update'); + PyDict_SetItemString := Import('PyDict_SetItemString'); PyDictProxy_New := Import('PyDictProxy_New'); - if not IsPython3000 then - Py_InitModule4 := {$IFDEF CPUX64}Import('Py_InitModule4_64'){$ELSE}Import('Py_InitModule4'){$ENDIF} - else - PyModule_Create2 := Import('PyModule_Create2'); + PyModule_Create2 := Import('PyModule_Create2'); PyErr_Print := Import('PyErr_Print'); PyErr_SetNone := Import('PyErr_SetNone'); PyErr_SetObject := Import('PyErr_SetObject'); @@ -3851,305 +3373,232 @@ procedure TPythonInterface.MapDll; PyErr_WarnExplicit := Import('PyErr_WarnExplicit'); PyEval_GetBuiltins := Import('PyEval_GetBuiltins'); PyImport_GetModuleDict := Import('PyImport_GetModuleDict'); - if IsPython3000 then - PyInt_FromLong := Import('PyLong_FromLong') - else - PyInt_FromLong := Import('PyInt_FromLong'); PyArg_Parse := Import('PyArg_Parse'); PyArg_ParseTuple := Import('PyArg_ParseTuple'); PyArg_ParseTupleAndKeywords := Import('PyArg_ParseTupleAndKeywords'); Py_BuildValue := Import('Py_BuildValue'); Py_Initialize := Import('Py_Initialize'); - PyDict_New := Import('PyDict_New'); - PyDict_SetItemString := Import('PyDict_SetItemString'); PyModule_GetDict := Import('PyModule_GetDict'); PyObject_Str := Import('PyObject_Str'); PyRun_String := Import('PyRun_String'); PyRun_SimpleString := Import('PyRun_SimpleString'); PyDict_GetItemString := Import('PyDict_GetItemString'); - if not IsPython3000 then begin - PyString_AsString := Import('PyString_AsString'); - PyString_AsStringAndSize := Import('PyString_AsStringAndSize') - end else begin - PyString_AsString := Import('PyBytes_AsString'); - PyString_AsStringAndSize := Import('PyBytes_AsStringAndSize'); - end; - if not IsPython3000 then - DLL_PyString_FromString := Import('PyString_FromString'); - if not IsPython3000 then - PySys_SetArgv := Import('PySys_SetArgv') - else - PySys_SetArgv3000 := Import('PySys_SetArgv'); + PySys_SetArgv := Import('PySys_SetArgv'); Py_Exit := Import('Py_Exit'); - if IsPython3000 then - PyCFunction_NewEx :=Import('PyCFunction_NewEx') - else - PyCFunction_New :=Import('PyCFunction_New'); - - PyEval_CallObjectWithKeywords:=Import('PyEval_CallObjectWithKeywords'); - PyEval_GetFrame :=Import('PyEval_GetFrame'); - PyEval_GetGlobals :=Import('PyEval_GetGlobals'); - PyEval_GetLocals :=Import('PyEval_GetLocals'); - //@PyEval_GetOwner :=Import('PyEval_GetOwner'); - if not IsPython3000 then - PyEval_GetRestricted :=Import('PyEval_GetRestricted'); - PyEval_InitThreads :=Import('PyEval_InitThreads'); - PyEval_RestoreThread :=Import('PyEval_RestoreThread'); - PyEval_SaveThread :=Import('PyEval_SaveThread'); - if not IsPython3000 then - PyFile_FromString :=Import('PyFile_FromString'); - PyFile_GetLine :=Import('PyFile_GetLine'); - if not IsPython3000 then - PyFile_Name :=Import('PyFile_Name'); - if not IsPython3000 then - PyFile_SetBufSize :=Import('PyFile_SetBufSize'); - if not IsPython3000 then - PyFile_SoftSpace :=Import('PyFile_SoftSpace'); - PyFile_WriteObject :=Import('PyFile_WriteObject'); - PyFile_WriteString :=Import('PyFile_WriteString'); - PyFloat_AsDouble :=Import('PyFloat_AsDouble'); - PyFloat_FromDouble :=Import('PyFloat_FromDouble'); - PyFunction_GetCode :=Import('PyFunction_GetCode'); - PyFunction_GetGlobals :=Import('PyFunction_GetGlobals'); - PyFunction_New :=Import('PyFunction_New'); - PyImport_AddModule :=Import('PyImport_AddModule'); - PyImport_GetMagicNumber :=Import('PyImport_GetMagicNumber'); - PyImport_ImportFrozenModule:=Import('PyImport_ImportFrozenModule'); - PyImport_ImportModule :=Import('PyImport_ImportModule'); - PyImport_Import :=Import('PyImport_Import'); - //PyImport_Init :=Import('PyImport_Init'); - PyImport_ReloadModule :=Import('PyImport_ReloadModule'); - if not IsPython3000 then - PyInstance_New :=Import('PyInstance_New'); - if IsPython3000 then - PyInt_AsLong :=Import('PyLong_AsLong') - else - PyInt_AsLong :=Import('PyInt_AsLong'); - PyList_Append :=Import('PyList_Append'); - PyList_AsTuple :=Import('PyList_AsTuple'); - PyList_GetItem :=Import('PyList_GetItem'); - PyList_GetSlice :=Import('PyList_GetSlice'); - PyList_Insert :=Import('PyList_Insert'); - PyList_New :=Import('PyList_New'); - PyList_Reverse :=Import('PyList_Reverse'); - PyList_SetItem :=Import('PyList_SetItem'); - PyList_SetSlice :=Import('PyList_SetSlice'); - PyList_Size :=Import('PyList_Size'); - PyList_Sort :=Import('PyList_Sort'); - PyLong_AsDouble :=Import('PyLong_AsDouble'); - PyLong_AsLong :=Import('PyLong_AsLong'); - PyLong_FromDouble :=Import('PyLong_FromDouble'); - PyLong_FromLong :=Import('PyLong_FromLong'); - PyLong_FromString :=Import('PyLong_FromString'); - PyLong_FromString :=Import('PyLong_FromString'); - PyLong_FromUnsignedLong :=Import('PyLong_FromUnsignedLong'); - PyLong_AsUnsignedLong :=Import('PyLong_AsUnsignedLong'); - PyLong_FromUnicode :=Import('PyLong_FromUnicode'); - PyLong_FromLongLong :=Import('PyLong_FromLongLong'); - PyLong_AsLongLong :=Import('PyLong_AsLongLong'); - PyLong_FromVoidPtr :=Import('PyLong_FromVoidPtr'); - PyMapping_Check :=Import('PyMapping_Check'); - PyMapping_GetItemString :=Import('PyMapping_GetItemString'); - PyMapping_HasKey :=Import('PyMapping_HasKey'); - PyMapping_HasKeyString :=Import('PyMapping_HasKeyString'); - PyMapping_Length :=Import('PyMapping_Length'); - PyMapping_SetItemString :=Import('PyMapping_SetItemString'); - if not IsPython3000 then - PyMethod_Class :=Import('PyMethod_Class'); - PyMethod_Function :=Import('PyMethod_Function'); - PyMethod_New :=Import('PyMethod_New'); - PyMethod_Self :=Import('PyMethod_Self'); - PyModule_GetName :=Import('PyModule_GetName'); - PyModule_New :=Import('PyModule_New'); - PyNumber_Absolute :=Import('PyNumber_Absolute'); - PyNumber_Add :=Import('PyNumber_Add'); - PyNumber_And :=Import('PyNumber_And'); - PyNumber_Check :=Import('PyNumber_Check'); - if not IsPython3000 then - PyNumber_Coerce :=Import('PyNumber_Coerce'); - if IsPython3000 then - PyNumber_Divide :=Import('PyNumber_TrueDivide') - else - PyNumber_Divide :=Import('PyNumber_Divide'); - PyNumber_FloorDivide :=Import('PyNumber_FloorDivide'); - PyNumber_TrueDivide :=Import('PyNumber_TrueDivide'); - PyNumber_Divmod :=Import('PyNumber_Divmod'); - PyNumber_Float :=Import('PyNumber_Float'); - if not IsPython3000 then - PyNumber_Int :=Import('PyNumber_Int'); - PyNumber_Invert :=Import('PyNumber_Invert'); - PyNumber_Long :=Import('PyNumber_Long'); - PyNumber_Lshift :=Import('PyNumber_Lshift'); - PyNumber_Multiply :=Import('PyNumber_Multiply'); - PyNumber_Negative :=Import('PyNumber_Negative'); - PyNumber_Or :=Import('PyNumber_Or'); - PyNumber_Positive :=Import('PyNumber_Positive'); - PyNumber_Power :=Import('PyNumber_Power'); - PyNumber_Remainder :=Import('PyNumber_Remainder'); - PyNumber_Rshift :=Import('PyNumber_Rshift'); - PyNumber_Subtract :=Import('PyNumber_Subtract'); - PyNumber_Xor :=Import('PyNumber_Xor'); - PyOS_InitInterrupts :=Import('PyOS_InitInterrupts'); - PyOS_InterruptOccurred :=Import('PyOS_InterruptOccurred'); - PyObject_CallObject :=Import('PyObject_CallObject'); - PyObject_CallMethod :=Import('PyObject_CallMethod'); - if not IsPython3000 then - PyObject_Compare :=Import('PyObject_Compare'); - PyObject_RichCompare :=Import('PyObject_RichCompare'); - PyObject_RichCompareBool :=Import('PyObject_RichCompareBool'); - PyObject_GetAttr :=Import('PyObject_GetAttr'); - PyObject_GetAttrString :=Import('PyObject_GetAttrString'); - PyObject_GetItem :=Import('PyObject_GetItem'); - PyObject_DelItem :=Import('PyObject_DelItem'); - PyObject_HasAttrString :=Import('PyObject_HasAttrString'); - PyObject_Hash :=Import('PyObject_Hash'); - PyObject_IsTrue :=Import('PyObject_IsTrue'); - PyObject_Length :=Import('PyObject_Length'); - PyObject_Repr :=Import('PyObject_Repr'); - PyObject_SetAttr :=Import('PyObject_SetAttr'); - PyObject_SetAttrString :=Import('PyObject_SetAttrString'); - PyObject_SetItem :=Import('PyObject_SetItem'); - PyObject_Init :=Import('PyObject_Init'); - PyObject_InitVar :=Import('PyObject_InitVar'); - PyObject_New :=Import('_PyObject_New'); - PyObject_NewVar :=Import('_PyObject_NewVar'); - PyObject_Free :=Import('PyObject_Free'); - PyObject_GetIter :=Import('PyObject_GetIter'); - PyIter_Next :=Import('PyIter_Next'); - PyObject_IsInstance :=Import('PyObject_IsInstance'); - PyObject_IsSubclass :=Import('PyObject_IsSubclass'); - PyObject_Call :=Import('PyObject_Call'); - PyObject_GenericGetAttr :=Import('PyObject_GenericGetAttr'); - PyObject_GenericSetAttr :=Import('PyObject_GenericSetAttr'); - PyObject_GC_Malloc :=Import('_PyObject_GC_Malloc'); - PyObject_GC_New :=Import('_PyObject_GC_New'); - PyObject_GC_NewVar :=Import('_PyObject_GC_NewVar'); - PyObject_GC_Resize :=Import('_PyObject_GC_Resize'); - PyObject_GC_Del :=Import('PyObject_GC_Del'); - PyObject_GC_Track :=Import('PyObject_GC_Track'); - PyObject_GC_UnTrack :=Import('PyObject_GC_UnTrack'); - PySequence_Check :=Import('PySequence_Check'); - PySequence_Concat :=Import('PySequence_Concat'); - PySequence_Count :=Import('PySequence_Count'); - PySequence_GetItem :=Import('PySequence_GetItem'); - PySequence_GetSlice :=Import('PySequence_GetSlice'); - PySequence_In :=Import('PySequence_In'); - PySequence_Index :=Import('PySequence_Index'); - PySequence_Length :=Import('PySequence_Length'); - PySequence_Repeat :=Import('PySequence_Repeat'); - PySequence_SetItem :=Import('PySequence_SetItem'); - PySequence_SetSlice :=Import('PySequence_SetSlice'); - PySequence_DelSlice :=Import('PySequence_DelSlice'); - PySequence_Tuple :=Import('PySequence_Tuple'); - PySequence_Contains :=Import('PySequence_Contains'); - PySlice_GetIndices :=Import('PySlice_GetIndices'); - PySeqIter_New :=Import('PySeqIter_New'); - PySlice_GetIndicesEx :=Import('PySlice_GetIndicesEx'); - PySlice_New :=Import('PySlice_New'); - if not IsPython3000 then begin - PyString_Concat :=Import('PyString_Concat'); - PyString_ConcatAndDel :=Import('PyString_ConcatAndDel'); - PyString_Format :=Import('PyString_Format'); - PyString_FromStringAndSize:=Import('PyString_FromStringAndSize'); - PyString_Size :=Import('PyString_Size'); - PyString_DecodeEscape :=Import('PyString_DecodeEscape'); - PyString_Repr :=Import('PyString_Repr'); - end else begin - PyString_Concat :=Import('PyBytes_Concat'); - PyString_ConcatAndDel :=Import('PyBytes_ConcatAndDel'); - PyString_FromStringAndSize:=Import('PyBytes_FromStringAndSize'); - PyString_Size :=Import('PyBytes_Size'); - PyString_DecodeEscape :=Import('PyBytes_DecodeEscape'); - PyString_Repr :=Import('PyBytes_Repr'); - end; - PySys_GetObject :=Import('PySys_GetObject'); - //PySys_Init :=Import('PySys_Init'); - PySys_SetObject :=Import('PySys_SetObject'); - PySys_SetPath :=Import('PySys_SetPath'); - //PyTraceBack_Fetch :=Import('PyTraceBack_Fetch'); - PyTraceBack_Here :=Import('PyTraceBack_Here'); - PyTraceBack_Print :=Import('PyTraceBack_Print'); - //@PyTraceBack_Store :=Import('PyTraceBack_Store'); - PyTuple_GetItem :=Import('PyTuple_GetItem'); - PyTuple_GetSlice :=Import('PyTuple_GetSlice'); - PyTuple_New :=Import('PyTuple_New'); - PyTuple_SetItem :=Import('PyTuple_SetItem'); - PyTuple_Size :=Import('PyTuple_Size'); - PyType_IsSubtype :=Import('PyType_IsSubtype'); - PyType_GenericAlloc :=Import('PyType_GenericAlloc'); - PyType_GenericNew :=Import('PyType_GenericNew'); - PyType_Ready :=Import('PyType_Ready'); - PyUnicode_FromWideChar :=Import(Format('PyUnicode%s_FromWideChar',[UnicodeSuffix])); - PyUnicode_AsWideChar :=Import(Format('PyUnicode%s_AsWideChar',[UnicodeSuffix])); - PyUnicode_Decode :=Import(Format('PyUnicode%s_Decode',[UnicodeSuffix])); - PyUnicode_AsEncodedString :=Import(Format('PyUnicode%s_AsEncodedString',[UnicodeSuffix])); - PyUnicode_FromOrdinal :=Import(Format('PyUnicode%s_FromOrdinal',[UnicodeSuffix])); - PyUnicode_FromString :=Import(Format('PyUnicode%s_FromString',[UnicodeSuffix])); - PyUnicode_GetSize :=Import(Format('PyUnicode%s_GetSize',[UnicodeSuffix])); - PyWeakref_GetObject :=Import('PyWeakref_GetObject'); - PyWeakref_NewProxy :=Import('PyWeakref_NewProxy'); - PyWeakref_NewRef :=Import('PyWeakref_NewRef'); - PyWrapper_New :=Import('PyWrapper_New'); - PyBool_FromLong :=Import('PyBool_FromLong'); - PyThreadState_SetAsyncExc :=Import('PyThreadState_SetAsyncExc'); - Py_AtExit :=Import('Py_AtExit'); - //Py_Cleanup :=Import('Py_Cleanup'); - Py_FatalError :=Import('Py_FatalError'); - if not IsPython3000 then begin - Py_FindMethod :=Import('Py_FindMethod'); - Py_FindMethodInChain :=Import('Py_FindMethodInChain'); - DLL_Py_FlushLine :=Import('Py_FlushLine'); - _PyString_Resize :=Import('_PyString_Resize'); - Py_CompileStringFlags :=Import('Py_CompileStringFlags'); - end else begin - _PyString_Resize :=Import('_PyBytes_Resize'); - Py_CompileStringExFlags :=Import('Py_CompileStringExFlags'); - end; - _PyObject_New :=Import('_PyObject_New'); - Py_Finalize :=Import('Py_Finalize'); - if getProcAddress( FDLLHandle, 'PyCode_Addr2Line' ) <> nil then - DLL_PyCode_Addr2Line := Import('PyCode_Addr2Line'); - if getProcAddress( FDLLHandle, 'PyImport_ExecCodeModule' ) <> nil then - DLL_PyImport_ExecCodeModule := Import('PyImport_ExecCodeModule'); - //@PyClass_IsSubclass :=Import('PyClass_IsSubclass'); - PyErr_ExceptionMatches :=Import('PyErr_ExceptionMatches'); - PyErr_GivenExceptionMatches:=Import('PyErr_GivenExceptionMatches'); - PyEval_EvalCode :=Import('PyEval_EvalCode'); - Py_GetVersion :=Import('Py_GetVersion'); - Py_GetCopyright :=Import('Py_GetCopyright'); - Py_GetExecPrefix :=Import('Py_GetExecPrefix'); - Py_GetPath :=Import('Py_GetPath'); - if IsPython3000 then - Py_SetPythonHome3000 :=Import('Py_SetPythonHome') - else - Py_SetPythonHome :=Import('Py_SetPythonHome'); - if IsPython3000 then - Py_GetPythonHome3000 :=Import('Py_GetPythonHome') - else - Py_GetPythonHome :=Import('Py_GetPythonHome'); - Py_GetPrefix :=Import('Py_GetPrefix'); - Py_GetProgramName :=Import('Py_GetProgramName'); - PyParser_SimpleParseStringFlags := Import('PyParser_SimpleParseStringFlags'); - PyNode_Free :=Import('PyNode_Free'); - PyErr_NewException :=Import('PyErr_NewException'); -/// jah 29-sep-2000 : updated for python 2.0 -/// replaced Py_Malloc with PyMem_Malloc -///--- @Py_Malloc := Import ('Py_Malloc'); -///+++ @Py_Malloc := Import ('PyMem_Malloc'); + PyCFunction_NewEx := Import('PyCFunction_NewEx'); + + PyEval_CallObjectWithKeywords:= Import('PyEval_CallObjectWithKeywords'); + PyEval_GetFrame := Import('PyEval_GetFrame'); + PyEval_GetGlobals := Import('PyEval_GetGlobals'); + PyEval_GetLocals := Import('PyEval_GetLocals'); + PyEval_InitThreads := Import('PyEval_InitThreads'); + PyEval_RestoreThread := Import('PyEval_RestoreThread'); + PyEval_SaveThread := Import('PyEval_SaveThread'); + PyFile_GetLine := Import('PyFile_GetLine'); + PyFile_WriteObject := Import('PyFile_WriteObject'); + PyFile_WriteString := Import('PyFile_WriteString'); + PyFloat_AsDouble := Import('PyFloat_AsDouble'); + PyFloat_FromDouble := Import('PyFloat_FromDouble'); + PyFloat_FromString := Import('PyFloat_FromString'); + PyFunction_GetCode := Import('PyFunction_GetCode'); + PyFunction_GetGlobals := Import('PyFunction_GetGlobals'); + PyFunction_New := Import('PyFunction_New'); + PyImport_AddModule := Import('PyImport_AddModule'); + PyImport_GetMagicNumber := Import('PyImport_GetMagicNumber'); + PyImport_ImportFrozenModule:= Import('PyImport_ImportFrozenModule'); + PyImport_ImportModule := Import('PyImport_ImportModule'); + PyImport_Import := Import('PyImport_Import'); + PyImport_ReloadModule := Import('PyImport_ReloadModule'); + PyList_Append := Import('PyList_Append'); + PyList_AsTuple := Import('PyList_AsTuple'); + PyList_GetItem := Import('PyList_GetItem'); + PyList_GetSlice := Import('PyList_GetSlice'); + PyList_Insert := Import('PyList_Insert'); + PyList_New := Import('PyList_New'); + PyList_Reverse := Import('PyList_Reverse'); + PyList_SetItem := Import('PyList_SetItem'); + PyList_SetSlice := Import('PyList_SetSlice'); + PyList_Size := Import('PyList_Size'); + PyList_Sort := Import('PyList_Sort'); + PyLong_AsDouble := Import('PyLong_AsDouble'); + PyLong_AsLong := Import('PyLong_AsLong'); + PyLong_FromDouble := Import('PyLong_FromDouble'); + PyLong_FromLong := Import('PyLong_FromLong'); + PyLong_FromString := Import('PyLong_FromString'); + PyLong_FromString := Import('PyLong_FromString'); + PyLong_FromUnsignedLong := Import('PyLong_FromUnsignedLong'); + PyLong_AsUnsignedLong := Import('PyLong_AsUnsignedLong'); + PyLong_FromUnicodeObject := Import('PyLong_FromUnicodeObject'); + PyLong_FromLongLong := Import('PyLong_FromLongLong'); + PyLong_FromUnsignedLongLong := Import('PyLong_FromUnsignedLongLong'); + PyLong_AsLongLong := Import('PyLong_AsLongLong'); + PyLong_FromVoidPtr := Import('PyLong_FromVoidPtr'); + PyMapping_Check := Import('PyMapping_Check'); + PyMapping_GetItemString := Import('PyMapping_GetItemString'); + PyMapping_HasKey := Import('PyMapping_HasKey'); + PyMapping_HasKeyString := Import('PyMapping_HasKeyString'); + PyMapping_Length := Import('PyMapping_Length'); + PyMapping_SetItemString := Import('PyMapping_SetItemString'); + PyMapping_Keys := Import('PyMapping_Keys'); + PyMapping_Values := Import('PyMapping_Values'); + PyMethod_Function := Import('PyMethod_Function'); + PyMethod_New := Import('PyMethod_New'); + PyMethod_Self := Import('PyMethod_Self'); + PyModule_GetName := Import('PyModule_GetName'); + PyModule_New := Import('PyModule_New'); + PyNumber_Absolute := Import('PyNumber_Absolute'); + PyNumber_Add := Import('PyNumber_Add'); + PyNumber_And := Import('PyNumber_And'); + PyNumber_Check := Import('PyNumber_Check'); + PyNumber_FloorDivide := Import('PyNumber_FloorDivide'); + PyNumber_TrueDivide := Import('PyNumber_TrueDivide'); + PyNumber_Divmod := Import('PyNumber_Divmod'); + PyNumber_Float := Import('PyNumber_Float'); + PyNumber_Invert := Import('PyNumber_Invert'); + PyNumber_Long := Import('PyNumber_Long'); + PyNumber_Lshift := Import('PyNumber_Lshift'); + PyNumber_Multiply := Import('PyNumber_Multiply'); + PyNumber_Negative := Import('PyNumber_Negative'); + PyNumber_Or := Import('PyNumber_Or'); + PyNumber_Positive := Import('PyNumber_Positive'); + PyNumber_Power := Import('PyNumber_Power'); + PyNumber_Remainder := Import('PyNumber_Remainder'); + PyNumber_Rshift := Import('PyNumber_Rshift'); + PyNumber_Subtract := Import('PyNumber_Subtract'); + PyNumber_Xor := Import('PyNumber_Xor'); + PyOS_InterruptOccurred := Import('PyOS_InterruptOccurred'); + PyObject_CallObject := Import('PyObject_CallObject'); + PyObject_CallMethod := Import('PyObject_CallMethod'); + PyObject_RichCompare := Import('PyObject_RichCompare'); + PyObject_RichCompareBool := Import('PyObject_RichCompareBool'); + PyObject_GetAttr := Import('PyObject_GetAttr'); + PyObject_GetAttrString := Import('PyObject_GetAttrString'); + PyObject_GetItem := Import('PyObject_GetItem'); + PyObject_DelItem := Import('PyObject_DelItem'); + PyObject_HasAttr := Import('PyObject_HasAttr'); + PyObject_HasAttrString := Import('PyObject_HasAttrString'); + PyObject_Hash := Import('PyObject_Hash'); + PyObject_IsTrue := Import('PyObject_IsTrue'); + PyObject_Length := Import('PyObject_Length'); + PyObject_Repr := Import('PyObject_Repr'); + PyObject_SetAttr := Import('PyObject_SetAttr'); + PyObject_SetAttrString := Import('PyObject_SetAttrString'); + PyObject_SetItem := Import('PyObject_SetItem'); + PyObject_Init := Import('PyObject_Init'); + PyObject_InitVar := Import('PyObject_InitVar'); + PyObject_New := Import('_PyObject_New'); + PyObject_NewVar := Import('_PyObject_NewVar'); + PyObject_Free := Import('PyObject_Free'); + PyObject_GetIter := Import('PyObject_GetIter'); + PyIter_Next := Import('PyIter_Next'); + PyObject_IsInstance := Import('PyObject_IsInstance'); + PyObject_IsSubclass := Import('PyObject_IsSubclass'); + PyObject_Call := Import('PyObject_Call'); + PyObject_GenericGetAttr := Import('PyObject_GenericGetAttr'); + PyObject_GenericSetAttr := Import('PyObject_GenericSetAttr'); + PyObject_Malloc := Import('PyObject_Malloc'); + PyObject_GC_New := Import('_PyObject_GC_New'); + PyObject_GC_NewVar := Import('_PyObject_GC_NewVar'); + PyObject_GC_Resize := Import('_PyObject_GC_Resize'); + PyObject_GC_Del := Import('PyObject_GC_Del'); + PyObject_GC_Track := Import('PyObject_GC_Track'); + PyObject_GC_UnTrack := Import('PyObject_GC_UnTrack'); + PySequence_Check := Import('PySequence_Check'); + PySequence_Concat := Import('PySequence_Concat'); + PySequence_Count := Import('PySequence_Count'); + PySequence_GetItem := Import('PySequence_GetItem'); + PySequence_GetSlice := Import('PySequence_GetSlice'); + PySequence_In := Import('PySequence_In'); + PySequence_Index := Import('PySequence_Index'); + PySequence_Length := Import('PySequence_Length'); + PySequence_Repeat := Import('PySequence_Repeat'); + PySequence_SetItem := Import('PySequence_SetItem'); + PySequence_SetSlice := Import('PySequence_SetSlice'); + PySequence_DelSlice := Import('PySequence_DelSlice'); + PySequence_Tuple := Import('PySequence_Tuple'); + PySequence_Contains := Import('PySequence_Contains'); + PySequence_List := Import('PySequence_List'); + PySlice_GetIndices := Import('PySlice_GetIndices'); + PySeqIter_New := Import('PySeqIter_New'); + PySlice_GetIndicesEx := Import('PySlice_GetIndicesEx'); + PySlice_New := Import('PySlice_New'); + PyBytes_AsString := Import('PyBytes_AsString'); + PyBytes_AsStringAndSize := Import('PyBytes_AsStringAndSize'); + PyBytes_Concat := Import('PyBytes_Concat'); + PyBytes_ConcatAndDel := Import('PyBytes_ConcatAndDel'); + PyBytes_FromString := Import('PyBytes_FromString'); + PyBytes_FromStringAndSize := Import('PyBytes_FromStringAndSize'); + PyBytes_Size := Import('PyBytes_Size'); + PyBytes_DecodeEscape := Import('PyBytes_DecodeEscape'); + PyBytes_Repr := Import('PyBytes_Repr'); + _PyBytes_Resize := Import('_PyBytes_Resize'); + PySys_GetObject := Import('PySys_GetObject'); + PySys_SetObject := Import('PySys_SetObject'); + PySys_SetPath := Import('PySys_SetPath'); + PyTraceBack_Here := Import('PyTraceBack_Here'); + PyTraceBack_Print := Import('PyTraceBack_Print'); + PyTuple_GetItem := Import('PyTuple_GetItem'); + PyTuple_GetSlice := Import('PyTuple_GetSlice'); + PyTuple_New := Import('PyTuple_New'); + PyTuple_SetItem := Import('PyTuple_SetItem'); + PyTuple_Size := Import('PyTuple_Size'); + PyType_IsSubtype := Import('PyType_IsSubtype'); + PyType_GenericAlloc := Import('PyType_GenericAlloc'); + PyType_GenericNew := Import('PyType_GenericNew'); + PyType_Ready := Import('PyType_Ready'); + PyUnicode_FromWideChar := Import('PyUnicode_FromWideChar'); + PyUnicode_FromString := Import('PyUnicode_FromString'); + PyUnicode_FromStringAndSize := Import('PyUnicode_FromStringAndSize'); + PyUnicode_FromKindAndData := Import('PyUnicode_FromKindAndData'); + PyUnicode_AsWideChar := Import('PyUnicode_AsWideChar'); + PyUnicode_AsUTF8 := Import('PyUnicode_AsUTF8'); + PyUnicode_AsUTF8AndSize := Import('PyUnicode_AsUTF8AndSize'); + PyUnicode_Decode := Import('PyUnicode_Decode'); + PyUnicode_DecodeUTF16 := Import('PyUnicode_DecodeUTF16'); + PyUnicode_AsEncodedString := Import('PyUnicode_AsEncodedString'); + PyUnicode_FromOrdinal := Import('PyUnicode_FromOrdinal'); + PyUnicode_GetLength := Import('PyUnicode_GetLength'); + PyWeakref_GetObject := Import('PyWeakref_GetObject'); + PyWeakref_NewProxy := Import('PyWeakref_NewProxy'); + PyWeakref_NewRef := Import('PyWeakref_NewRef'); + PyWrapper_New := Import('PyWrapper_New'); + PyBool_FromLong := Import('PyBool_FromLong'); + PyThreadState_SetAsyncExc := Import('PyThreadState_SetAsyncExc'); + Py_AtExit := Import('Py_AtExit'); + Py_FatalError := Import('Py_FatalError'); + Py_CompileStringExFlags := Import('Py_CompileStringExFlags'); + _PyObject_New := Import('_PyObject_New'); + Py_Finalize := Import('Py_Finalize'); + PyImport_ExecCodeModule := Import('PyImport_ExecCodeModule'); + PyErr_ExceptionMatches := Import('PyErr_ExceptionMatches'); + PyErr_GivenExceptionMatches := Import('PyErr_GivenExceptionMatches'); + PyEval_EvalCode := Import('PyEval_EvalCode'); + Py_GetVersion := Import('Py_GetVersion'); + Py_GetCopyright := Import('Py_GetCopyright'); + Py_GetExecPrefix := Import('Py_GetExecPrefix'); + Py_GetPath := Import('Py_GetPath'); + Py_SetPath := Import('Py_SetPath'); + Py_SetPythonHome := Import('Py_SetPythonHome'); + Py_GetPythonHome := Import('Py_GetPythonHome'); + Py_GetPrefix := Import('Py_GetPrefix'); + Py_GetProgramName := Import('Py_GetProgramName'); + + if (FMajorVersion = 3) and (MinorVersion < 10) then + begin + PyParser_SimpleParseStringFlags := Import('PyParser_SimpleParseStringFlags'); + PyNode_Free := Import('PyNode_Free'); + end; + + PyErr_NewException := Import('PyErr_NewException'); try - Py_Malloc := Import ('PyMem_Malloc'); PyMem_Malloc := Import ('PyMem_Malloc'); except end; - if not IsPython3000 then - Py_SetProgramName := Import('Py_SetProgramName') - else - Py_SetProgramName3000 := Import('Py_SetProgramName'); + Py_SetProgramName := Import('Py_SetProgramName'); Py_IsInitialized := Import('Py_IsInitialized'); Py_GetProgramFullPath := Import('Py_GetProgramFullPath'); - if getProcAddress( FDLLHandle, 'Py_GetBuildInfo' ) <> nil then - DLL_Py_GetBuildInfo := Import('Py_GetBuildInfo'); + Py_GetBuildInfo := Import('Py_GetBuildInfo'); Py_NewInterpreter := Import('Py_NewInterpreter'); Py_EndInterpreter := Import('Py_EndInterpreter'); PyEval_AcquireLock := Import('PyEval_AcquireLock'); @@ -4169,12 +3618,9 @@ procedure TPythonInterface.MapDll; PyGILState_Release := Import('PyGILState_Release'); end; -function TPythonInterface.Py_CompileString( s1,s2:PAnsiChar;i:integer):PPyObject; cdecl; +function TPythonInterface.Py_CompileString(str,filename:PAnsiChar;start:integer):PPyObject; begin - if IsPython3000 then - Result := Py_CompileStringExFlags(s1, s2, i, nil, -1) - else - Result := Py_CompileStringFlags(s1, s2, i, nil); + Result := Py_CompileStringExFlags(str, filename, start, nil, -1); end; function TPythonInterface.PyParser_SimpleParseString( str : PAnsiChar; start : integer) : PNode; cdecl; @@ -4182,12 +3628,12 @@ function TPythonInterface.PyParser_SimpleParseString( str : PAnsiChar; start : i Result := PyParser_SimpleParseStringFlags(str, start, 0); end; -procedure TPythonInterface.Py_INCREF(op: PPyObject); +class procedure TPythonInterface.Py_INCREF(op: PPyObject); begin Inc(op^.ob_refcnt); end; -procedure TPythonInterface.Py_DECREF(op: PPyObject); +class procedure TPythonInterface.Py_DECREF(op: PPyObject); begin with op^ do begin Dec(ob_refcnt); @@ -4197,116 +3643,37 @@ procedure TPythonInterface.Py_DECREF(op: PPyObject); end; end; -procedure TPythonInterface.Py_XINCREF(op: PPyObject); +class procedure TPythonInterface.Py_XINCREF(op: PPyObject); begin if op <> nil then Py_INCREF(op); end; -procedure TPythonInterface.Py_XDECREF(op: PPyObject); +class procedure TPythonInterface.Py_XDECREF(op: PPyObject); begin if op <> nil then Py_DECREF(op); end; -// This function is copied from compile.c because it was not -// exported in the Dll -function TPythonInterface.PyCode_Addr2Line( co: PPyCodeObject; addrq : Integer ) : Integer; cdecl; -var - size : Integer; - p : PAnsiChar; - line : Integer; - addr : Integer; - cpt : Integer; -begin - if Assigned(DLL_PyCode_Addr2Line) then - begin - Result := DLL_PyCode_Addr2Line( co, addrq ); - Exit; - end; - size := PyString_Size(co^.co_lnotab) div 2; - p := PyString_AsString(co^.co_lnotab); - line := co^.co_firstlineno; - addr := 0; - cpt := 0; - while (size-1) >= 0 do - begin - Dec(size); - Inc( addr, Ord(p[cpt]) ); - Inc(cpt); - if addr > addrq then - Break; - Inc( line, Ord(p[cpt]) ); - Inc(cpt); - end; - Result := line; -end; - -function TPythonInterface.Py_GetBuildInfo : PAnsiChar; cdecl; -begin - if Assigned(DLL_Py_GetBuildInfo) then - begin - Result := DLL_Py_GetBuildInfo; - Exit; - end; - Result := 'No build info'; -end; -function TPythonInterface.PyImport_ExecCodeModule( const AName : AnsiString; codeobject : PPyObject) : PPyObject; -var - m, d, v, modules : PPyObject; +class procedure TPythonInterface.Py_CLEAR(var op: PPyObject); +Var + _py_tmp : PPyObject; begin - if Assigned(DLL_PyImport_ExecCodeModule) then + _py_tmp := op; + if _py_tmp <> nil then begin - Result := DLL_PyImport_ExecCodeModule(PAnsiChar(AName), codeobject); - Exit; + op := nil; + Py_DECREF(_py_tmp); end; - CheckPython; - m := PyImport_AddModule(PAnsiChar(AName)); - if not Assigned(m) then - begin - Result := nil; - Exit; - end; - d := PyModule_GetDict(m); - if PyDict_GetItemString(d, '__builtins__') = nil then - begin - if PyDict_SetItemString(d, '__builtins__', PyEval_GetBuiltins) <> 0 then - begin - Result := nil; - Exit; - end; - end; - // Remember the fielname as the __file__ attribute - if PyDict_SetItemString(d, '__file__', PPyCodeObject(codeobject)^.co_filename) <> 0 then - PyErr_Clear; // Not important enough to report - v := PyEval_EvalCode(PPyCodeObject(codeobject), d, d); // XXX owner ? - if not Assigned(v) then - begin - Result := nil; - Exit; - end; - Py_XDECREF(v); - modules := PyImport_GetModuleDict; - if PyDict_GetItemString(modules, PAnsiChar(AName)) = nil then - begin - PyErr_SetString(PyExc_ImportError^, - PAnsiChar(AnsiString(Format('Loaded module %.200s not found in sys.modules', [AName])))); - Result := nil; - Exit; - end; - Py_XINCREF(m); - Result := m; end; -function TPythonInterface.PyString_Check( obj : PPyObject ) : Boolean; +function TPythonInterface.PyBytes_Check( obj : PPyObject ) : Boolean; begin - Result := PyObject_TypeCheck(obj, PyString_Type); - if not Result then - Result := PyObject_TypeCheck(obj, PyUnicode_Type); + Result := PyObject_TypeCheck(obj, PyBytes_Type); end; -function TPythonInterface.PyString_CheckExact(obj: PPyObject): Boolean; +function TPythonInterface.PyBytes_CheckExact(obj: PPyObject): Boolean; begin - Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyString_Type)); + Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyBytes_Type)); end; function TPythonInterface.PyFloat_Check( obj : PPyObject ) : Boolean; @@ -4319,22 +3686,6 @@ function TPythonInterface.PyFloat_CheckExact(obj: PPyObject): Boolean; Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyFloat_Type)); end; -function TPythonInterface.PyInt_Check( obj : PPyObject ) : Boolean; -begin - if IsPython3000 then - Result := PyObject_TypeCheck(obj, PyLong_Type) - else - Result := PyObject_TypeCheck(obj, PyInt_Type); -end; - -function TPythonInterface.PyInt_CheckExact(obj: PPyObject): Boolean; -begin - if IsPython3000 then - Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyLong_Type)) - else - Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyInt_Type)); -end; - function TPythonInterface.PyLong_Check( obj : PPyObject ) : Boolean; begin Result := PyObject_TypeCheck(obj, PyLong_Type); @@ -4355,14 +3706,9 @@ function TPythonInterface.PyTuple_CheckExact(obj: PPyObject): Boolean; Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyTuple_Type)); end; -function TPythonInterface.PyInstance_Check( obj : PPyObject ) : Boolean; -begin - Result := Assigned( obj ) and (not IsPython3000) and (obj^.ob_type = PPyTypeObject(PyInstance_Type)); -end; - function TPythonInterface.PyClass_Check( obj : PPyObject ) : Boolean; begin - Result := Assigned( obj ) and not IsPython3000 and (obj^.ob_type = PPyTypeObject(PyClass_Type)); + Result := Assigned( obj ) and (PyObject_IsInstance(obj, PPyObject(PyType_Type)) <> 0); end; function TPythonInterface.PyType_CheckExact( obj : PPyObject ) : Boolean; @@ -4417,11 +3763,9 @@ function TPythonInterface.PyFunction_Check( obj : PPyObject ) : Boolean; (obj^.ob_type = PPyTypeObject(PyFunction_Type))); end; -function TPythonInterface.PyIter_Check( obj : PPyObject ) : Boolean; +function TPythonInterface.PyIter_Check(obj: PPyObject): Boolean; begin - Result := Assigned( obj ) and - (IsPython3000 or (PyType_HasFeature(obj^.ob_type, Py_TPFLAGS_HAVE_ITER)) - and Assigned(obj^.ob_type^.tp_iternext)); + Result := Assigned(obj) and Assigned(obj^.ob_type^.tp_iternext); end; function TPythonInterface.PyUnicode_Check( obj : PPyObject ) : Boolean; @@ -4467,14 +3811,6 @@ function TPythonInterface.PyBool_Check( obj : PPyObject ) : Boolean; Result := PyObject_TypeCheck(obj, PyBool_Type); end; -function TPythonInterface.PyBaseString_Check( obj : PPyObject ) : Boolean; -begin - if IsPython3000 then - Result:= PyObject_TypeCheck(obj, PyUnicode_Type) - else - Result := PyObject_TypeCheck(obj, PyBaseString_Type); -end; - function TPythonInterface.PyEnum_Check( obj : PPyObject ) : Boolean; begin Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyEnum_Type)); @@ -4487,13 +3823,7 @@ function TPythonInterface.PyObject_TypeCheck(obj : PPyObject; t : PPyTypeObject) Result := PyType_IsSubtype(obj^.ob_type, t) = 1; end; -function TPythonInterface.Py_InitModule( const AName : PAnsiChar; md : PPyMethodDef) : PPyObject; -begin - CheckPython; - Result := Py_InitModule4( AName, md, nil, nil, APIVersion ); -end; - -function TPythonInterface.Py_InitModule3000(const md: PyModuleDef): PPyObject; +function TPythonInterface.Py_InitModule(const md: PyModuleDef): PPyObject; Var modules : PPyObject; begin @@ -4507,12 +3837,6 @@ function TPythonInterface.Py_InitModule3000(const md: PyModuleDef): PPyObject; GetPythonEngine.CheckError; end; -procedure TPythonInterface.Py_FlushLine; cdecl; -begin - if Assigned(DLL_Py_FlushLine) then - DLL_Py_FlushLine; -end; - (*******************************************************) (** **) (** class TPythonTraceback **) @@ -4543,6 +3867,18 @@ destructor TPythonTraceback.Destroy; inherited; end; +procedure TPythonTraceback.AddItem(const Context, FileName: string; + LineNo: Integer); +var + Item: TTracebackItem; +begin + Item := TTracebackItem.Create; + Item.Context := Context; + Item.FileName := FileName; + Item.LineNo := LineNo; + FItems.Add(Item); +end; + procedure TPythonTraceback.Clear; var i : Integer; @@ -4565,7 +3901,6 @@ procedure TPythonTraceback.Clear; } procedure TPythonTraceback.Refresh; var -// tb, tb1 : PPyTraceBackObject; tb, tb1 : PPyObject; obj : PPyObject; frame : PPyObject; @@ -4581,8 +3916,8 @@ procedure TPythonTraceback.Refresh; // get the limit of the traceback alimit := FLimit; limitv := PySys_GetObject('tracebacklimit'); - if Assigned(limitv) and PyInt_Check(limitv) then - alimit := PyInt_AsLong(limitv); + if Assigned(limitv) and PyLong_Check(limitv) then + alimit := PyLong_AsLong(limitv); tb := PySys_GetObject('last_traceback'); tb1 := tb; Py_XIncRef(tb1); @@ -4671,7 +4006,6 @@ constructor TPythonEngine.Create(AOwner: TComponent); i : Integer; begin inherited; - FLock := TCriticalSection.Create; FInitScript := TstringList.Create; FClients := TList.Create; FRedirectIO := True; @@ -4692,18 +4026,21 @@ constructor TPythonEngine.Create(AOwner: TComponent); end; destructor TPythonEngine.Destroy; +var + I: Integer; begin LocalVars := nil; GlobalVars := nil; Destroying; Finalize; -{$IFDEF FPC} + for I := 0 to ClientCount - 1 do + Clients[I].ClearEngine; +{$IFDEF FPC} // See https://github.com/Alexey-T/Python-for-Lazarus/issues/29 inherited; -{$ENDIF} // Free our objects +{$ENDIF} FClients.Free; FInitScript.Free; FTraceback.Free; - FLock.Free; {$IFNDEF FPC} inherited; {$ENDIF} @@ -4712,7 +4049,6 @@ destructor TPythonEngine.Destroy; procedure TPythonEngine.Finalize; var i: integer; - canDetachClients : Boolean; begin // switch off redirection when the component is destroying, // because the form or datamodule is beeing closed, and @@ -4735,28 +4071,17 @@ procedure TPythonEngine.Finalize; Finalize; end; // Then finalize Python, if we have to - if Initialized and FAutoFinalize then + if Initialized and FAutoFinalize then begin try - FFinalizing := True; - Py_Finalize; - finally - FFinalizing := False; - FInitialized := False; - end; - // Detach our clients, when engine is beeing destroyed or one of its clients. - canDetachClients := csDestroying in ComponentState; - if not canDetachClients then - for i := 0 to ClientCount - 1 do - if csDestroying in Clients[i].ComponentState then - begin - canDetachClients := True; - Break; + try + FFinalizing := True; + Py_Finalize; + finally + FFinalizing := False; + FInitialized := False; end; - if canDetachClients then - begin - for i := 0 to ClientCount - 1 do - Clients[i].ClearEngine; - FClients.Clear; + except + end; end; // Free our reference gPythonEngine := nil; @@ -4770,16 +4095,6 @@ procedure TPythonEngine.Finalize; FPyDateTime_DateTimeTZType := nil; end; -procedure TPythonEngine.Lock; -begin - FLock.Enter; -end; - -procedure TPythonEngine.Unlock; -begin - FLock.Leave; -end; - procedure TPythonEngine.AfterLoad; begin inherited; @@ -4795,10 +4110,10 @@ procedure TPythonEngine.BeforeLoad; procedure TPythonEngine.DoOpenDll(const aDllName : String); var - i : Integer; + i: Integer; begin if UseLastKnownVersion then - for i:= Integer(COMPILED_FOR_PYTHON_VERSION_INDEX) to High(PYTHON_KNOWN_VERSIONS) do + for i:= Integer(COMPILED_FOR_PYTHON_VERSION_INDEX) downto 1 do begin RegVersion := PYTHON_KNOWN_VERSIONS[i].RegVersion; FDLLHandle := SafeLoadLibrary(GetDllPath+PYTHON_KNOWN_VERSIONS[i].DllName); @@ -4808,10 +4123,12 @@ procedure TPythonEngine.DoOpenDll(const aDllName : String); APIVersion := PYTHON_KNOWN_VERSIONS[i].APIVersion; Exit; end; - if not PYTHON_KNOWN_VERSIONS[i].CanUseLatest then - Break; - end; - inherited; + end + else + begin + RegVersion := SysVersionFromDLLName(aDllName); + inherited; + end; end; procedure TPythonEngine.AssignPyFlags; @@ -4832,14 +4149,7 @@ procedure TPythonEngine.AssignPyFlags; SetFlag(Py_OptimizeFlag, pfOptimize in FPyFlags); SetFlag(Py_NoSiteFlag, pfNoSite in FPyFlags); SetFlag(Py_FrozenFlag, pfFrozenFlag in FPyFlags); - if not IsPython3000 then begin - SetFlag(Py_UseClassExceptionsFlag, pfUseClassExceptionsFlag in FPyFlags); - SetFlag(Py_UnicodeFlag, pfUnicode in FPyFlags); - SetFlag(Py_TabcheckFlag, pfTabcheck in FPyFlags); - end; SetFlag(Py_IgnoreEnvironmentFlag, pfIgnoreEnvironmentFlag in FPyFlags); - if Assigned(Py_DivisionWarningFlag) then - SetFlag(Py_DivisionWarningFlag, pfDivisionWarningFlag in FPyFlags); end; procedure TPythonEngine.Initialize; @@ -4847,7 +4157,19 @@ procedure TPythonEngine.Initialize; procedure InitSysPath; var _path : PPyObject; + const Script = + 'import sys' + sLineBreak + + 'sys.executable = r"%s"' + sLineBreak + + 'path = sys.path' + sLineBreak + + 'for i in range(len(path)-1, -1, -1):' + sLineBreak + + ' if path[i].find("site-packages") > 0:' + sLineBreak + + ' path.pop(i)' + sLineBreak + + 'import site' + sLineBreak + + 'site.main()' + sLineBreak + + 'del sys, path, i, site'; begin + if VenvPythonExe <> '' then + ExecString(AnsiString(Format(Script, [VenvPythonExe]))); _path := PySys_GetObject('path'); if Assigned(FOnSysPathInit) then FOnSysPathInit(Self, _path); @@ -4906,38 +4228,13 @@ procedure TPythonEngine.Initialize; if Assigned(gPythonEngine) then raise Exception.Create('There is already one instance of TPythonEngine running' ); - {$IFDEF FPC} - //this allows you to just call Initialize to create a non-IDE instance with - //Lazarus. - if(AutoLoad and not IsHandleValid) then begin - LoadDLL;//Calls initialize - exit; - end; - {$ENDIF} - gPythonEngine := Self; - //CheckRegistry; //AT: disabled - - if IsPython3000 then begin - if Assigned(Py_SetProgramName3000) then - begin - FProgramNameW := ParamStr(0); - Py_SetProgramName3000(PWideChar(FProgramNameW)); - end - end else begin - if Assigned(Py_SetProgramName) then - begin - FProgramName := ParamStr(0); - Py_SetProgramName(PAnsiChar(FProgramName)); - end - end; + CheckRegistry; + if Assigned(Py_SetProgramName) and (Length(FProgramName) > 0) then + Py_SetProgramName(PWCharT(FProgramName)); AssignPyFlags; - if FPythonHomeW<>'' then begin - if IsPython3000 then - Py_SetPythonHome3000(PWideChar(FPythonHomeW)) - else - Py_SetPythonHome(PAnsiChar(FPythonHome)); - end; + if Length(FPythonHome) > 0 then + Py_SetPythonHome(PWCharT(FPythonHome)); Py_Initialize; if Assigned(Py_IsInitialized) then FInitialized := Py_IsInitialized() <> 0 @@ -4967,17 +4264,6 @@ procedure TPythonEngine.SetInitScript(Value: TStrings); FInitScript.Assign(Value); end; -function TPythonEngine.GetInterpreterState: PPyInterpreterState; -var - res: PPyThreadState; -begin - if Assigned(PyThreadState_Get) then begin - res:= PyThreadState_Get; - Result := res^.interp; - end else - Result := nil; -end; - function TPythonEngine.GetThreadState: PPyThreadState; begin if Assigned(PyThreadState_Get) then @@ -5008,24 +4294,10 @@ function TPythonEngine.GetClients( idx : Integer ) : TEngineClient; procedure TPythonEngine.Notification( AComponent: TComponent; Operation: TOperation); -var - i : Integer; begin inherited; - if Operation = opRemove then - begin - if AComponent = IO then - IO := nil - else - begin - for i := 0 to ClientCount - 1 do - if Clients[i] = AComponent then - begin - RemoveClient( Clients[i] ); - Break; - end; - end; - end; + if (Operation = opRemove) and (AComponent = IO) then + IO := nil end; procedure TPythonEngine.CheckRegistry; @@ -5074,62 +4346,36 @@ procedure TPythonEngine.CheckRegistry; procedure TPythonEngine.SetProgramArgs; var - buff : PAnsiChar; - argv : PPAnsiChar; - i, argc : Integer; - L : array of AnsiString; - wargv : PPWideChar; - wbuff : PWideChar; - {$IFDEF UNIX} - UCS4L : array of UCS4String; - {$ELSE} - WL : array of UnicodeString; - {$ENDIF} + I, argc : Integer; + wargv : array of PWCharT; + WL : array of WCharTString; + TempS: UnicodeString; begin // we build a string list of the arguments, because ParamStr returns a volatile string - // and we want to build an array of PAnsiChar, pointing to valid strings. + // and we want to build an array of PWCharT, pointing to valid strings. argc := ParamCount; - if not IsPython3000 then begin - SetLength(L, argc+1); - GetMem( buff, sizeof(PAnsiChar)*(argc+1) ); - try - argv := PPAnsiChar(buff); - // get the strings - // build the PAnsiChar array - for i := 0 to argc do begin - L[i] := AnsiString(ParamStr(i)); - argv^[i] := PAnsiChar(L[i]); - end; - // set the argv list of the sys module with the application arguments - PySys_SetArgv( argc+1, argv ); - finally - FreeMem( buff ); - end; - end else begin - GetMem(wbuff, sizeof(PWideChar)*(argc+1)); - try - wargv := PPWideChar(wbuff); - // build the PWideChar array - {$IFDEF UNIX} - // Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!! - SetLength(UCS4L, argc+1); - for i := 0 to argc do begin - UCS4L[i] := WideStringToUCS4String(ParamStr(i)); - wargv^[i] := @UCS4L[i][0]; - end; - {$ELSE} - SetLength(WL, argc+1); - for i := 0 to argc do begin - WL[i] := UnicodeString(ParamStr(i)); - wargv^[i] := PWideChar(WL[i]); - end; - {$ENDIF} - // set the argv list of the sys module with the application arguments - PySys_SetArgv3000( argc + 1, wargv ); - finally - FreeMem( wbuff ); - end; + SetLength(wargv, argc + 1); + // build the PWCharT array + SetLength(WL, argc+1); + for I := 0 to argc do begin + { + ... the first entry should refer to the script file to be executed rather + than the executable hosting the Python interpreter. If there isn’t a + script that will be run, the first entry in argv can be an empty string. + } + if I = 0 then + TempS := '' + else + TempS := ParamStr(I); + {$IFDEF POSIX} + WL[I] := UnicodeStringToUCS4String(TempS); + {$ELSE} + WL[I] := UnicodeString(TempS); + {$ENDIF} + wargv[I] := PWCharT(WL[I]); end; + // set the argv list of the sys module with the application arguments + PySys_SetArgv( argc + 1, PPWCharT(wargv) ); end; procedure TPythonEngine.InitWinConsole; @@ -5194,29 +4440,71 @@ procedure TPythonEngine.SetPyFlags(const Value: TPythonFlags); end; // of if end; -procedure TPythonEngine.SetPythonHome(const PythonHome: String); +function TPythonEngine.GetPythonHome: UnicodeString; begin - FPythonHomeW := PythonHome; - FPythonHome := PythonHome; +{$IFDEF POSIX} + if Length(FPythonHome) = 0 then + Result := '' + else + Result := UCS4StringToUnicodeString(FPythonHome); +{$ELSE} + Result := FPythonHome; +{$ENDIF} end; -function TPythonEngine.IsType(ob: PPyObject; obt: PPyTypeObject): Boolean; +function TPythonEngine.GetPythonPath: UnicodeString; begin - result := ob^.ob_type = obt; +{$IFDEF POSIX} + if (Length(FPythonPath) > 0) then + Result := UCS4StringToUnicodeString(FPythonPath) + else + Result := ''; +{$ELSE} + Result := FPythonPath; +{$ENDIF} end; -function TPythonEngine.GetAttrString(obj: PPyObject; AName: PAnsiChar):PAnsiChar; -var - attr: PPyObject; +function TPythonEngine.GetProgramName: UnicodeString; begin - CheckPython; - result := nil; - attr := PyObject_GetAttrString(obj, AName); - if attr <> nil then begin - result := PyString_AsString(attr); - Py_XDECREF(attr); - end; - PyErr_Clear; +{$IFDEF POSIX} + if Length(FProgramName) = 0 then + Result := '' + else + Result := UCS4StringToUnicodeString(FProgramName); +{$ELSE} + Result := FProgramName; +{$ENDIF} +end; +procedure TPythonEngine.SetPythonHome(const PythonHome: UnicodeString); +begin +{$IFDEF POSIX} + FPythonHome := UnicodeStringToUCS4String(PythonHome); +{$ELSE} + FPythonHome := PythonHome; +{$ENDIF} +end; + +procedure TPythonEngine.SetPythonPath(const Value: UnicodeString); +begin +{$IFDEF POSIX} + FPythonPath := UnicodeStringToUCS4String(Value); +{$ELSE} + FPythonPath := Value; +{$ENDIF} +end; + +procedure TPythonEngine.SetProgramName(const ProgramName: UnicodeString); +begin +{$IFDEF POSIX} + FProgramName := UnicodeStringToUCS4String(ProgramName); +{$ELSE} + FProgramName := ProgramName; +{$ENDIF} +end; + +function TPythonEngine.IsType(ob: PPyObject; obt: PPyTypeObject): Boolean; +begin + result := ob^.ob_type = obt; end; function TPythonEngine.EvalPyFunction(pyfunc, pyargs:PPyObject): Variant; @@ -5244,9 +4532,7 @@ function TPythonEngine.EvalPyFunction(pyfunc, pyargs:PPyObject): Variant; Py_DECREF(presult); end; end; - Py_FlushLine; except - Py_FlushLine; if PyErr_Occurred <> nil then CheckError(False) else @@ -5278,40 +4564,55 @@ function TPythonEngine.EvalFunctionNoArgs(pyfunc:PPyObject): Variant; end; end; -function TPythonEngine.EvalStringAsStr(const command : AnsiString) : String; +function TPythonEngine.EvalStringAsStr(const command: AnsiString; const + FileName: string = '<string>'): string; begin - Result := Run_CommandAsString( command, eval_input ); + Result := Run_CommandAsString(command, eval_input, FileName); end; -function TPythonEngine.EvalString(const command : AnsiString) : PPyObject; +function TPythonEngine.EvalString(const command: AnsiString; const FileName: + string = '<string>'): PPyObject; begin - Result := Run_CommandAsObject( command, eval_input ); + Result := Run_CommandAsObject(command, eval_input, FileName); end; -procedure TPythonEngine.ExecString(const command : AnsiString); +procedure TPythonEngine.ExecString(const command: AnsiString; const FileName: + string = '<string>'); begin - Py_XDecRef( Run_CommandAsObject( command, file_input ) ); + Py_XDecRef(Run_CommandAsObject(command, file_input, FileName)); end; -function TPythonEngine.Run_CommandAsString(const command : AnsiString; mode : Integer) : String; +function TPythonEngine.Run_CommandAsString(const command: AnsiString; mode: + Integer; const FileName: string = '<string>'): string; var - v : PPyObject; + PRes : PPyObject; begin Result := ''; - v := Run_CommandAsObject( command, mode ); - Result := PyObjectAsString( v ); - Py_XDECREF(v); + PRes := Run_CommandAsObject(command, mode, FileName); + Result := PyObjectAsString(PRes); + Py_XDECREF(PRes); end; -function TPythonEngine.Run_CommandAsObject(const command : AnsiString; mode : Integer) : PPyObject; +function TPythonEngine.Run_CommandAsObject(const command: AnsiString; mode: + Integer; const FileName: string = '<string>'): PPyObject; begin - Result := Run_CommandAsObjectWithDict(command, mode, nil, nil); + Result := Run_CommandAsObjectWithDict(command, mode, nil, nil, FileName); end; -function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; mode : Integer; locals, globals : PPyObject) : PPyObject; +function TPythonEngine.Run_CommandAsObjectWithDict(const command: AnsiString; + mode: Integer; locals, globals: PPyObject; const FileName: string = + '<string>'): PPyObject; +{ + This is the core function for executing/evaluating python code + Parameters: + - command: utf-8 encoded AnsiString with the code that will be executed or evaluated + - mode: one of the constants file_input, single_input, eval_input + - locals, globals: python dictionaries with local/global namespaces. Can be nil. + - FileName; optional string used when debugging code with external debuggers +} var m : PPyObject; - _locals, _globals : PPyObject; + _locals, _globals, Code : PPyObject; begin CheckPython; Result := nil; @@ -5337,12 +4638,14 @@ function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; m _globals := _locals; try - Result := PyRun_String(PAnsiChar(CleanString(command)), mode, _globals, _locals); + Code := Py_CompileString(PAnsiChar(CleanString(command)), + PAnsiChar(EncodeString(FileName)), mode); + if Code = nil then + CheckError(False); + Result := PyEval_EvalCode(Code, _globals, _locals ); if Result = nil then CheckError(False); - Py_FlushLine; except - Py_FlushLine; if PyErr_Occurred <> nil then CheckError(False) else @@ -5350,40 +4653,62 @@ function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; m end; end; +procedure TPythonEngine.ExecStrings(strings: TStrings; const FileName: string = + '<string>'); +begin + Py_XDecRef(Run_CommandAsObject(EncodeString(strings.Text), file_input, FileName)); +end; -procedure TPythonEngine.ExecStrings( strings : TStrings ); +function TPythonEngine.EvalStrings(strings: TStrings; const FileName: string = + '<string>'): PPyObject; begin - Py_XDecRef( Run_CommandAsObject( strings.Text, file_input ) ); + Result := Run_CommandAsObject(EncodeString(strings.Text) , eval_input, FileName); end; -function TPythonEngine.EvalStrings( strings : TStrings ) : PPyObject; +procedure TPythonEngine.ExecFile(const FileName: string; locals, + globals: PPyObject); +var + SL: TStringList; begin - Result := Run_CommandAsObject( strings.Text, eval_input ); + SL := TStringList.Create; + try + SL.LoadFromFile(FileName, TEncoding.UTF8); + ExecStrings(SL, locals, globals, FileName); + finally + SL.Free; + end; end; -procedure TPythonEngine.ExecString(const command : AnsiString; locals, globals : PPyObject ); +procedure TPythonEngine.ExecString(const command: AnsiString; locals, globals: + PPyObject; const FileName: string = '<string>'); begin - Py_XDecRef( Run_CommandAsObjectWithDict( command, file_input, locals, globals ) ); + Py_XDecRef(Run_CommandAsObjectWithDict(command, file_input, locals, globals, FileName)); end; -procedure TPythonEngine.ExecStrings( strings : TStrings; locals, globals : PPyObject ); +procedure TPythonEngine.ExecStrings(strings: TStrings; locals, globals: + PPyObject; const FileName: string = '<string>'); begin - Py_XDecRef( Run_CommandAsObjectWithDict( strings.Text, file_input, locals, globals ) ); + Py_XDecRef( Run_CommandAsObjectWithDict(EncodeString(strings.Text), + file_input, locals, globals, FileName)); end; -function TPythonEngine.EvalString( const command : AnsiString; locals, globals : PPyObject ) : PPyObject; +function TPythonEngine.EvalString(const command: AnsiString; locals, globals: + PPyObject; const FileName: string = '<string>'): PPyObject; begin - Result := Run_CommandAsObjectWithDict( command, eval_input, locals, globals ); + Result := Run_CommandAsObjectWithDict(command, eval_input, locals, globals, FileName); end; -function TPythonEngine.EvalStrings( strings : TStrings; locals, globals : PPyObject ) : PPyObject; +function TPythonEngine.EvalStrings(strings: TStrings; locals, globals: + PPyObject; const FileName: string = '<string>'): PPyObject; begin - Result := Run_CommandAsObjectWithDict( strings.Text, eval_input, locals, globals ); + Result := Run_CommandAsObjectWithDict(EncodeString(strings.Text), + eval_input, locals, globals, FileName); end; -function TPythonEngine.EvalStringsAsStr( strings : TStrings ) : String; +function TPythonEngine.EvalStringsAsStr(strings: TStrings; const FileName: + string = '<string>'): string; begin - Result := Run_CommandAsString( strings.Text, eval_input ); + Result := Run_CommandAsString(EncodeString(strings.Text), eval_input, FileName); end; function TPythonEngine.CheckEvalSyntax( const str : AnsiString ) : Boolean; @@ -5419,14 +4744,16 @@ procedure TPythonEngine.RaiseError; Result := E; end; - function DefineSyntaxError( E : EPySyntaxError; const sType, sValue : String; err_type, err_value : PPyObject ) : EPySyntaxError; + function DefineSyntaxError( E : EPySyntaxError; const sType, sValue : UnicodeString; err_type, err_value : PPyObject ) : EPySyntaxError; var - s_value : String; - s_line : String; - s_filename : String; - i_line_number : Integer; - i_offset : Integer; - tmp : PPyObject; + s_value : UnicodeString; + s_line : UnicodeString; + s_filename : UnicodeString; + i_line_number : Integer; + i_offset : Integer; + i_end_line_number : Integer; + i_end_offset : Integer; + tmp : PPyObject; begin Result := E; Result.EName := sType; @@ -5436,64 +4763,82 @@ procedure TPythonEngine.RaiseError; s_filename := ''; i_line_number := 0; i_offset := 0; + i_end_line_number := 0; + i_end_offset := 0; // Sometimes there's a tuple instead of instance... - if PyTuple_Check( err_value ) and (PyTuple_Size( err_value) >= 2) then + if PyTuple_Check(err_value) and (PyTuple_Size( err_value) >= 2) then begin - s_value := PyString_AsDelphiString(PyTuple_GetItem( err_value, 0)); + s_value := PyObjectAsString(PyTuple_GetItem( err_value, 0)); err_value := PyTuple_GetItem( err_value, 1); if PyTuple_Check( err_value ) and (PyTuple_Size( err_value) >= 4) then begin - i_line_number := PyInt_AsLong(PyTuple_GetItem( err_value, 1)); - i_offset := PyInt_AsLong(PyTuple_GetItem( err_value, 2)); - s_line := Trim(PyString_AsDelphiString(PyTuple_GetItem( err_value, 3))); + i_line_number := PyLong_AsLong(PyTuple_GetItem( err_value, 1)); + i_offset := PyLong_AsLong(PyTuple_GetItem( err_value, 2)); + s_line := Trim(PyObjectAsString(PyTuple_GetItem( err_value, 3))); end; end else // Is it an instance of the SyntaxError class ? - if (PyInstance_Check( err_value ) and (PyClass_IsSubclass( PPyObject(PPyInstanceObject(err_value)^.in_class), err_type ) <> 0)) or - ((PyType_IsSubtype(PPyTypeObject(err_type), PPyTypeObject(PyExc_SyntaxError^)) = 1) and IsType(err_value, PPyTypeObject(err_type))) then - begin - // Get the filename - tmp := PyObject_GetAttrString(err_value, 'filename'); - if tmp <> nil then begin - if PyString_Check(tmp) then - s_filename := PyString_AsDelphiString(tmp) - else if tmp = Py_None then - s_filename := '???'; - Py_XDECREF(tmp); - end; - // Get the text containing the error, cut of carriage return - tmp := PyObject_GetAttrString(err_value, 'text'); - if Assigned(tmp) and PyString_Check(tmp) then - s_line := Trim(PyString_AsDelphiString(tmp)); - Py_XDECREF(tmp); - // Get the offset where the error should appear - tmp := PyObject_GetAttrString(err_value, 'offset' ); - if Assigned(tmp) and PyInt_Check(tmp) then - i_offset := PyInt_AsLong(tmp); + if (PyType_IsSubtype(PPyTypeObject(err_type), PPyTypeObject(PyExc_SyntaxError^)) = 1) + and IsType(err_value, PPyTypeObject(err_type)) + then + begin + // Get the filename + tmp := PyObject_GetAttrString(err_value, 'filename'); + if tmp <> nil then begin + if PyUnicode_Check(tmp) then + s_filename := PyUnicodeAsString(tmp) + else if tmp = Py_None then + s_filename := '???'; Py_XDECREF(tmp); - // Get the line number of the error - tmp := PyObject_GetAttrString(err_value, 'lineno' ); - if Assigned(tmp) and PyInt_Check(tmp) then - i_line_number := PyInt_AsLong(tmp); + end; + // Get the text containing the error, cut of carriage return + tmp := PyObject_GetAttrString(err_value, 'text'); + if Assigned(tmp) and PyUnicode_Check(tmp) then + s_line := Trim(PyUnicodeAsString(tmp)); + Py_XDECREF(tmp); + // Get the offset where the error should appear + tmp := PyObject_GetAttrString(err_value, 'offset' ); + if Assigned(tmp) and PyLong_Check(tmp) then + i_offset := PyLong_AsLong(tmp); + Py_XDECREF(tmp); + // Get the line number of the error + tmp := PyObject_GetAttrString(err_value, 'lineno' ); + if Assigned(tmp) and PyLong_Check(tmp) then + i_line_number := PyLong_AsLong(tmp); + Py_XDECREF(tmp); + // Get the message of the error + tmp := PyObject_GetAttrString(err_value, 'msg' ); + if Assigned(tmp) and PyUnicode_Check(tmp) then + s_value := PyUnicodeAsString(tmp); + Py_XDECREF(tmp); + if (MajorVersion > 3) or (MinorVersion >= 10) then + begin + // Get the end offset of the error + tmp := PyObject_GetAttrString(err_value, 'end_offset' ); + if Assigned(tmp) and PyLong_Check(tmp) then + i_end_offset := PyLong_AsLong(tmp); Py_XDECREF(tmp); - // Get the message of the error - tmp := PyObject_GetAttrString(err_value, 'msg' ); - if Assigned(tmp) and PyString_Check(tmp) then - s_value := PyString_AsDelphiString(tmp); + // Get the end line number of the error + tmp := PyObject_GetAttrString(err_value, 'end_lineno' ); + if Assigned(tmp) and PyLong_Check(tmp) then + i_end_line_number := PyLong_AsLong(tmp); Py_XDECREF(tmp); end; + end; // If all is ok if s_value <> '' then begin with Result do begin - Message := Format('%s: %s (line %d, offset %d): ''%s''', [sType,s_value,i_line_number, i_offset,s_line]); - EName := sType; - EValue := s_value; - EFileName := s_filename; - ELineNumber := i_line_number; - EOffset := i_offset; - ELineStr := s_line; + Message := Format('%s: %s (line %d, offset %d): ''%s''', [sType,s_value,i_line_number, i_offset,s_line]); + EName := sType; + EValue := s_value; + EFileName := s_filename; + ELineNumber := i_line_number; + EOffset := i_offset; + EEndLineNumber := i_end_line_number; + EEndOffset := i_end_offset; + ELineStr := s_line; end; end else @@ -5502,11 +4847,8 @@ procedure TPythonEngine.RaiseError; function GetTypeAsString( obj : PPyObject ) : String; begin - if PyClass_Check( obj ) then - with PPyClassObject(obj)^ do - Result := PyString_AsDelphiString(cl_name) - else if PyType_CheckExact( obj ) then - Result := String(PPyTypeObject(obj).tp_name) + if PyType_CheckExact( obj ) then + Result := string(PPyTypeObject(obj).tp_name) else Result := PyObjectAsString(obj); end; @@ -5597,8 +4939,6 @@ procedure TPythonEngine.RaiseError; raise Define( EPySystemError.Create(''), s_type, s_value ) else if (PyErr_GivenExceptionMatches(err_type, PyExc_MemoryError^) <> 0) then raise Define( EPyMemoryError.Create(''), s_type, s_value ) - else if (not IsPython3000) and (PyErr_GivenExceptionMatches(err_type, PyExc_StandardError^) <> 0) then - raise Define( EPyStandardError.Create(''), s_type, s_value ) else if (PyErr_GivenExceptionMatches(err_type, PyExc_UserWarning^) <> 0) then raise Define( EPyUserWarning.Create(''), s_type, s_value ) else if (PyErr_GivenExceptionMatches(err_type, PyExc_DeprecationWarning^) <> 0) then @@ -5623,35 +4963,26 @@ procedure TPythonEngine.RaiseError; raise EPythonError.Create('RaiseError: couldn''t fetch last exception'); end; -function TPythonEngine.PyObjectAsString( obj : PPyObject ) : String; +function TPythonEngine.PyObjectAsString( obj : PPyObject ) : string; +//differs from Python4Delphi- Alexey var - s : PPyObject; -// i : Integer; -// tmp : PAnsiChar; - w : UnicodeString; + S : PPyObject; begin - CheckPython; Result := ''; if not Assigned( obj ) then Exit; if PyUnicode_Check(obj) then begin - w := PyUnicode_AsWideString(obj); - Result := w; + Result := PyUnicodeAsUTF8String(obj); Exit; end; - s := PyObject_Str( obj ); - if Assigned(s) and PyString_Check(s) then - begin - Result := PyString_AsDelphiString(s); -// tmp := PyString_AsString(s); -// SetLength( Result, PyString_Size(s)+1 ); -// Result := ''; -// for i := 0 to PyString_Size(s) - 1 do -// Insert( tmp[i], Result, i+1 ); - end; - Py_XDECREF(s); + S := PyObject_Str( obj ); + if Assigned(S) and PyUnicode_Check(S) then + begin + Result := PyUnicodeAsUTF8String(S); + end; + Py_XDECREF(S); end; procedure TPythonEngine.DoRedirectIO; @@ -5667,6 +4998,8 @@ procedure TPythonEngine.DoRedirectIO; ' return self.pyio.read(size)'+LF+ ' def flush(self):' + LF + ' pass' + LF + + ' def isatty(self):' + LF + + ' return False' + LF + 'sys.old_stdin=sys.stdin'+LF+ 'sys.old_stdout=sys.stdout'+LF+ 'sys.old_stderr=sys.stderr'+LF+ @@ -5710,7 +5043,7 @@ procedure TPythonEngine.RemoveClient( client : TEngineClient ); // is not predictable and may cause some memory crashes ! if (csDesigning in ComponentState) then FClients.Remove( client ) - else if (Initialized) then begin + else if Initialized then begin FClients.Remove( client ); if (ClientCount = 0) then Finalize; @@ -5731,6 +5064,27 @@ function TPythonEngine.FindClient( const aName : AnsiString ) : TEngineClient; end; end; +function TPythonEngine.EncodeString(const str: UnicodeString): AnsiString; {$IFDEF FPC}overload;{$ENDIF} +begin + Result := UTF8Encode(str) +end; + +{$IFDEF FPC} +function TPythonEngine.EncodeString (const str: AnsiString): AnsiString; overload; +begin + Result := UTF8Encode(str); +end; +{$ENDIF} + +function TPythonEngine.EncodeWindowsFilePath(const str: string): AnsiString; +{PEP 529} +begin + if (MajorVersion > 3) or ((MajorVersion = 3) and (MinorVersion >=6) )then + Result := UTF8Encode(str) + else + Result := AnsiString(str); +end; + function TPythonEngine.TypeByName( const aTypeName : AnsiString ) : PPyTypeObject; var i : Integer; @@ -5847,13 +5201,9 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject; y, m, d, h, mi, sec, ms, jd, wd : WORD; dt : TDateTime; dl : Integer; - myInt : NativeInt; wStr : UnicodeString; - Disp : IDispatch; - DispID : Integer; args : PPyObject; begin - Disp := nil; //Dereference Variant DerefV := V; while VarType(DeRefV) = varByRef or varVariant do @@ -5872,7 +5222,7 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject; varShortInt, varWord, varLongWord, - varInteger: Result := PyInt_FromLong( DeRefV ); + varInteger: Result := PyLong_FromLong( LongInt(DeRefV) ); varInt64: Result := PyLong_FromLongLong( DeRefV ); varSingle, varDouble, @@ -5886,7 +5236,7 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject; begin wd := (DayOfWeek( dt ) + 7 - 2) mod 7; // In Python, Monday is the first day (=0) jd := Round(EncodeDate(y,m,d)-EncodeDate(y,1,1))+1; // This shoud be the Julian day, the day in a year (0-366) - dl := -1; // This is daylight save... ??????? I don't know what it is... + dl := -1; // This is daylight save... ?Ώ?Ώ? I don't know what it is... Result := ArrayToPyTuple( [y, m, d, h, mi, sec, wd, jd, dl] ); end else if (DatetimeConversionMode = dcmToDatetime) then @@ -5910,17 +5260,17 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject; wStr := '' else wStr := DeRefV; - Result := PyUnicode_FromWideChar( PWideChar(wStr), Length(wStr) ); + Result := PyUnicodeFromString(wStr); end; varString: begin s := AnsiString(DeRefV); - Result := PyString_FromStringAndSize(PAnsiChar(s), Length(s)); + Result := PyBytes_FromStringAndSize(PAnsiChar(s), Length(s)); end; varUString: begin - wStr := DeRefV; - Result := PyUnicode_FromWideChar( PWideChar(wStr), Length(wStr) ); + wStr := DeRefV; + Result := PyUnicodeFromString(wStr); end; else if VarType(DeRefV) and varArray <> 0 then @@ -5953,8 +5303,8 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant; begin member := PyObject_GetAttrString( obj, PAnsiChar(AMember) ); CheckError(False); - if PyInt_Check(member) then - Result := PyInt_AsLong(member) + if PyLong_Check(member) then + Result := PyLong_AsLong(member) else raise EPythonError.CreateFmt('Unexpected type found in member %s of a time_struct object', [AMember]); Py_XDecRef(member); @@ -6024,17 +5374,17 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant; else if PyTuple_Check( obj ) and (PyTuple_Size(obj) = 9) then begin for i := 0 to 8 do - if not PyInt_Check(PyTuple_GetItem(obj, i)) then + if not PyLong_Check(PyTuple_GetItem(obj, i)) then Exit; - y := PyInt_AsLong( PyTuple_GetItem(obj, 0) ); - m := PyInt_AsLong( PyTuple_GetItem(obj, 1) ); - d := PyInt_AsLong( PyTuple_GetItem(obj, 2) ); - h := PyInt_AsLong( PyTuple_GetItem(obj, 3) ); - mi := PyInt_AsLong( PyTuple_GetItem(obj, 4) ); - sec := PyInt_AsLong( PyTuple_GetItem(obj, 5) ); - wd := PyInt_AsLong( PyTuple_GetItem(obj, 6) ); - jd := PyInt_AsLong( PyTuple_GetItem(obj, 7) ); - dl := PyInt_AsLong( PyTuple_GetItem(obj, 8) ); + y := PyLong_AsLong( PyTuple_GetItem(obj, 0) ); + m := PyLong_AsLong( PyTuple_GetItem(obj, 1) ); + d := PyLong_AsLong( PyTuple_GetItem(obj, 2) ); + h := PyLong_AsLong( PyTuple_GetItem(obj, 3) ); + mi := PyLong_AsLong( PyTuple_GetItem(obj, 4) ); + sec := PyLong_AsLong( PyTuple_GetItem(obj, 5) ); + wd := PyLong_AsLong( PyTuple_GetItem(obj, 6) ); + jd := PyLong_AsLong( PyTuple_GetItem(obj, 7) ); + dl := PyLong_AsLong( PyTuple_GetItem(obj, 8) ); if not (m in [1..12]) or not (d in [1..31]) or not (h in [0..23]) or @@ -6075,13 +5425,10 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant; Result := PyObject_IsTrue(obj) = 1 else if PyLong_Check(obj) then Result := PyLong_AsLongLong(obj) - // changed the order of Long and int check (KV) - else if PyInt_Check(obj) then - Result := PyInt_AsLong(obj) else if PyUnicode_Check(obj) then - Result := PyUnicode_AsWideString(obj) - else if PyString_Check(obj) then - Result := PyObjectAsString(obj) + Result := PyUnicodeAsString(obj) + else if PyBytes_Check(obj) then + Result := AnsiString(PyBytes_AsString(obj)) else if ExtractDate( Result ) then begin // Nothing to do @@ -6115,50 +5462,50 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant; function TPythonEngine.VarRecAsPyObject( v : TVarRec ) : PPyObject; begin case v.VType of - vtInteger: Result := PyInt_FromLong( v.VInteger ); - vtBoolean: Result := PyInt_FromLong( Integer(v.VBoolean) ); - vtChar: Result := PyString_FromString( PAnsiChar(AnsiString(v.VChar)) ); + vtInteger: Result := PyLong_FromLong( v.VInteger ); + vtBoolean: Result := PyLong_FromLong( Integer(v.VBoolean) ); + vtChar: Result := PyUnicodeFromString(AnsiString(v.VChar)); vtExtended: Result := PyFloat_FromDouble( v.VExtended^ ); vtString: begin if Assigned(v.VString) then - Result := PyString_FromString(PAnsiChar(AnsiString(v.VString^))) + Result := PyUnicodeFromString(AnsiString(v.VString^)) else - Result := PyString_FromString( '' ); + Result := PyUnicodeFromString(''); end; - vtPChar: Result := PyString_FromString( v.VPChar ); + vtPChar: Result := PyUnicodeFromString(AnsiString(v.VPChar)); vtAnsiString: begin if Assigned(v.VAnsiString) then - Result := PyString_FromString( v.VAnsiString ) + Result := PyUnicodeFromString(PAnsiChar(v.VAnsiString)) else - Result := PyString_FromString(''); + Result := PyUnicodeFromString('');; end; vtCurrency: Result := PyFloat_FromDouble( v.VCurrency^ ); vtVariant: Result := VariantAsPyObject( v.VVariant^ ); vtPointer: Result := v.VPointer; vtInt64: Result := PyLong_FromLongLong( v.VInt64^ ); - vtWideChar: Result := PyUnicode_FromWideString( v.VWideChar ); + vtWideChar: Result := PyUnicodeFromString( v.VWideChar ); vtPWideChar: begin if Assigned(v.VPWideChar) then - Result := PyUnicode_FromWideString( UnicodeString(v.VPWideChar) ) + Result := PyUnicodeFromString( UnicodeString(v.VPWideChar) ) else - Result := PyUnicode_FromWideString( '' ); + Result := PyUnicodeFromString( '' ); end; vtWideString: begin if Assigned(v.VWideString) then - Result := PyUnicode_FromWideString( WideString(v.VWideString) ) + Result := PyUnicodeFromString( WideString(v.VWideString) ) else - Result := PyUnicode_FromWideString( '' ); + Result := PyUnicodeFromString( '' ); end; vtUnicodeString: begin if Assigned(v.VUnicodeString) then - Result := PyUnicode_FromWideString( UnicodeString(v.VUnicodeString) ) + Result := PyUnicodeFromString( UnicodeString(v.VUnicodeString) ) else - Result := PyUnicode_FromWideString( '' ); + Result := PyUnicodeFromString( '' ); end; else Raise Exception.Create('Argument type not allowed'); @@ -6313,7 +5660,7 @@ function TPythonEngine.StringsToPyList( strings : TStrings ) : PPyObject; raise EPythonError.Create('Could not create a new list object'); for i := 0 to strings.Count - 1 do PyList_SetItem( Result, i, - PyString_FromString( PAnsiChar(AnsiString(strings.Strings[i])) ) ); + PyUnicodeFromString( strings.Strings[i]) ); end; function TPythonEngine.StringsToPyTuple( strings : TStrings ) : PPyObject; @@ -6325,18 +5672,20 @@ function TPythonEngine.StringsToPyTuple( strings : TStrings ) : PPyObject; raise EPythonError.Create('Could not create a new tuple object'); for i := 0 to strings.Count - 1 do PyTuple_SetItem( Result, i, - PyString_FromString( PAnsiChar(AnsiString(strings.Strings[i])) ) ); + PyUnicodeFromString( strings.Strings[i]) ); end; -procedure TPythonEngine.PyListToStrings( list : PPyObject; strings : TStrings ); +procedure TPythonEngine.PyListToStrings(list: PPyObject; Strings: TStrings; + ClearStrings: Boolean = True); var i : Integer; begin if not PyList_Check(list) then raise EPythonError.Create('the python object is not a list'); - strings.Clear; + if ClearStrings then + Strings.Clear; for i := 0 to PyList_Size( list ) - 1 do - strings.Add( PyObjectAsString( PyList_GetItem( list, i ) ) ); + Strings.Add( PyObjectAsString( PyList_GetItem( list, i ) ) ); end; procedure TPythonEngine.PyTupleToStrings( tuple: PPyObject; strings : TStrings ); @@ -6350,48 +5699,69 @@ procedure TPythonEngine.PyTupleToStrings( tuple: PPyObject; strings : TStrings ) strings.Add( PyObjectAsString( PyTuple_GetItem( tuple, i ) ) ); end; -function TPythonEngine.PyUnicode_AsWideString( obj : PPyObject ) : UnicodeString; +function TPythonEngine.PyBytesAsAnsiString(obj: PPyObject): AnsiString; var - _size : Integer; -{$IFDEF unix} - _ucs4Str : UCS4String; -{$ENDIF} + buffer: PAnsiChar; + size: NativeInt; +begin + if PyBytes_Check(obj) then + begin + PyBytes_AsStringAndSize(obj, buffer, size); + SetString(Result, buffer, size); + end + else + raise EPythonError.CreateFmt(SPyConvertionError, ['PyBytesAsAnsiString', 'Bytes']); +end; + +function TPythonEngine.PyUnicodeAsString(obj : PPyObject) : UnicodeString; +var + Buffer: PAnsiChar; + Size: NativeInt; + NewSize: Cardinal; begin if PyUnicode_Check(obj) then begin - //_size := PySequence_Length(obj); //not fully correct for some Unicode - _size := PyUnicode_GetSize(obj); - if _size > 0 then - begin -{$IFDEF unix} - // Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!! - SetLength(_ucs4Str, _size+1); - if PyUnicode_AsWideChar(obj, @_ucs4Str[0], _size) <> _size then - raise EPythonError.Create('Could not copy the whole Unicode string into its buffer'); - Result := UCS4StringToWideString(_ucs4Str); - // remove trailing zeros (needed by Kylix1) - while (Length(Result) > 0) and (Result[Length(Result)] = #0) do - Delete(Result, Length(Result), 1); -{$ELSE} - SetLength(Result, _size); - if PyUnicode_AsWideChar(obj, @Result[1], _size) <> _size then - raise EPythonError.Create('Could not copy the whole Unicode string into its buffer'); -{$ENDIF} - end + // Size does not include the final #0 + Buffer := PyUnicode_AsUTF8AndSize(obj, @Size); + SetLength(Result, Size); + if (Size = 0) or (Buffer = nil) then + Exit; + + // The second argument is the size of the destination (Result) including #0 + NewSize := Utf8ToUnicode(PUnicodeChar(Result), Size + 1, Buffer, Size); + // NewSize includes #0 + SetLength(Result, NewSize - 1); + end + else + raise EPythonError.CreateFmt(SPyConvertionError, ['PyUnicodeAsString', 'Unicode']); +end; + +function TPythonEngine.PyUnicodeAsUTF8String( obj : PPyObject ) : RawByteString; +var + buffer: PAnsiChar; + size: NativeInt; +begin + if PyUnicode_Check(obj) then + begin + Result := ''; + buffer := PyUnicode_AsUTF8AndSize(obj, @size); + if Assigned(buffer) then + SetString(Result, buffer, size) else Result := ''; + SetCodePage(Result, CP_UTF8, False); end else - raise EPythonError.Create('PyUnicode_AsWideString expects a Unicode Python object'); + raise EPythonError.CreateFmt(SPyConvertionError, ['PyUnicodeAsUTF8String', 'Unicode']); end; -function TPythonEngine.PyUnicode_FromWideString( const AString : UnicodeString) : PPyObject; -{$IFDEF unix} +function TPythonEngine.PyUnicodeFromString(const AString : UnicodeString) : PPyObject; +{$IFDEF POSIX} var _ucs4Str : UCS4String; {$ENDIF} begin -{$IFDEF unix} +{$IFDEF POSIX} // Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!! _ucs4Str := WideStringToUCS4String(AString); Result := PyUnicode_FromWideChar( {PWideChar}(@_ucs4Str[0]), Length(_ucs4Str)-1 {trim trailing zero}); @@ -6400,12 +5770,24 @@ function TPythonEngine.PyUnicode_FromWideString( const AString : UnicodeString) {$ENDIF} end; +function TPythonEngine.ReturnFalse : PPyObject; +begin + Result := Py_False; + Py_INCREF( Result ); +end; + function TPythonEngine.ReturnNone : PPyObject; begin Result := Py_None; Py_INCREF( Result ); end; +function TPythonEngine.ReturnTrue : PPyObject; +begin + Result := Py_True; + Py_INCREF( Result ); +end; + function TPythonEngine.FindModule( const ModuleName : AnsiString ) : PPyObject; var modules, m : PPyObject; @@ -6418,6 +5800,19 @@ function TPythonEngine.FindModule( const ModuleName : AnsiString ) : PPyObject; Result := nil; end; +function TPythonEngine.FindPythonType(const TypeName: AnsiString): TPythonType; +var + i : Integer; +begin + Result := nil; + for i := 0 to ClientCount - 1 do + if (Clients[i] is TPythonType) and (TPythonType(Clients[i]).TypeName = TypeName) then + begin + Result := TPythonType(Clients[i]); + Break; + end; +end; + function TPythonEngine.FindFunction(ModuleName,FuncName: AnsiString): PPyObject; var module,func: PPyObject; @@ -6469,7 +5864,7 @@ function TPythonEngine.SetToList( data : Pointer; size : Integer ) : PPyObject; for i := 0 to size*8-1 do if GetBit(i) then begin - PyList_SetItem( Result, cpt, PyInt_FromLong(i) ); + PyList_SetItem( Result, cpt, PyLong_FromLong(i) ); Inc(cpt); end; end; @@ -6496,14 +5891,36 @@ procedure TPythonEngine.ListToSet( List : PPyObject; data : Pointer; size : Inte end; procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False); + + procedure ProcessSystemExit; + var + errtype, errvalue, errtraceback: PPyObject; + SErrValue: string; + begin + // PyErr_Fetch clears the error. The returned python objects are new references + PyErr_Fetch(errtype, errvalue, errtraceback); + Traceback.Refresh(errtraceback); + SErrValue := PyObjectAsString(errvalue); + Py_XDECREF(errtype); + Py_XDECREF(errvalue); + Py_XDECREF(errtraceback); + raise EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]); + end; + +var + PyException: PPyObject; begin - if PyErr_Occurred <> nil then + PyException := PyErr_Occurred; + if PyException <> nil then begin - if ACatchStopEx and (PyErr_GivenExceptionMatches(PyErr_Occurred, PyExc_StopIteration^) <> 0) then + if ACatchStopEx and (PyErr_GivenExceptionMatches(PyException, PyExc_StopIteration^) <> 0) then begin PyErr_Clear; - raise EPyStopIteration.Create('Stop iteration'); + raise EPyStopIteration.CreateRes(@SPyExcStopIteration); end + else if PyErr_GivenExceptionMatches(PyException, PyExc_SystemExit^) <> 0 then + // Special treatment for SystemExit. Calling PyErr_Print would terminate the process + ProcessSystemExit else begin PyErr_Print; @@ -6518,7 +5935,7 @@ function TPythonEngine.GetMainModule : PPyObject; Result := PyImport_AddModule(PAnsiChar(ExecModule)); end; -function TPythonEngine.PyTimeStruct_Check( obj : PPyObject ) : Boolean; +function TPythonEngine.PyTimeStruct_Check(obj : PPyObject) : Boolean; begin Result := Assigned(FTimeStruct) and (Pointer(obj^.ob_type) = FTimeStruct); end; @@ -6573,45 +5990,12 @@ function TPythonEngine.PyTZInfo_CheckExact( obj : PPyObject ) : Boolean; Result := Assigned(FPyDateTime_DateType) and (Pointer(obj^.ob_type) = FPyDateTime_TZInfoType); end; -function TPythonEngine.PyString_AsDelphiString(ob: PPyObject): AnsiString; -begin - if PyUnicode_Check(ob) then - Result := AnsiString(PyUnicode_AsWideString(ob)) - else - Result := AnsiString(PyString_AsString(ob)); -end; - -function TPythonEngine.PyString_AsAnsiString( ob: PPyObject): AnsiString; -begin - if PyUnicode_Check(ob) then - Result := AnsiString(PyUnicode_AsWideString(ob)) - else - Result := AnsiString(PyString_AsString(ob)); -end; - -function TPythonEngine.PyString_AsWideString( ob: PPyObject): UnicodeString; -begin - if PyUnicode_Check(ob) then - Result := PyUnicode_AsWideString(ob) - else - Result := UnicodeString(PyString_AsString(ob)); -end; - -function TPythonEngine.PyString_FromString( str: PAnsiChar): PPyObject; -var - _text : UnicodeString; +function TPythonEngine.PyUnicodeFromString(const AString: AnsiString): PPyObject; begin - if IsPython3000 then - begin - _text := UnicodeString(str); - Result := PyUnicode_FromWideString(_text); - end - else - Result := DLL_PyString_FromString(str); + Result := PyUnicodeFromString(UnicodeString(AString)); end; - (*******************************************************) (** **) (** class TEngineClient **) @@ -6651,6 +6035,10 @@ constructor TEngineClient.Create( AOwner : TComponent ); destructor TEngineClient.Destroy; begin + // if the client is destroyed before the Python Engine then + // we need to finalize it. Otherwise it will already be finalized + if FInitialized then + Finalize; Engine := nil; // This detaches the client from the Engine. if Assigned( FOnDestroy ) then FOnDestroy( Self ); @@ -6664,14 +6052,6 @@ procedure TEngineClient.Loaded; FOnCreate( Self ); end; -procedure TEngineClient.Notification( AComponent: TComponent; Operation: TOperation); -begin - inherited; - if Operation = opRemove then - if AComponent = FEngine then - FEngine := nil; -end; - procedure TEngineClient.Initialize; begin if FInitialized then @@ -6909,12 +6289,26 @@ function TMethodsContainer.AddMethodWithKeywords( AMethodName : PAnsiChar; Result^.ml_flags := Result^.ml_flags or METH_KEYWORDS; end; +function TMethodsContainer.AddStaticMethodWithKeywords(AMethodName: PAnsiChar; + AMethod: PyCFunctionWithKW; ADocString: PAnsiChar): PPyMethodDef; +begin + Result := AddMethodWithKeywords(AMethodName, AMethod, ADocString); + Result^.ml_flags := Result^.ml_flags or METH_STATIC; +end; + +function TMethodsContainer.AddClassMethodWithKeywords(AMethodName: PAnsiChar; + AMethod: PyCFunctionWithKW; ADocString: PAnsiChar): PPyMethodDef; +begin + Result := AddMethodWithKeywords(AMethodName, AMethod, ADocString); + Result^.ml_flags := Result^.ml_flags or METH_CLASS; +end; + function TMethodsContainer.AddDelphiMethod( AMethodName : PAnsiChar; ADelphiMethod: TDelphiMethod; ADocString : PAnsiChar ) : PPyMethodDef; begin Result := AddMethod( AMethodName, - GetOfObjectCallBack( TCallBack(ADelphiMethod), 2, ctCDECL), + GetOfObjectCallBack( TCallBack(ADelphiMethod), 2, DEFAULT_CALLBACK_TYPE), ADocString ); end; @@ -6923,7 +6317,7 @@ function TMethodsContainer.AddDelphiMethodWithKeywords( AMethodName : PAnsiCh ADocString : PAnsiChar ) : PPyMethodDef; begin Result := AddMethod( AMethodName, - GetOfObjectCallBack( TCallBack(ADelphiMethod), 3, ctCDECL), + GetOfObjectCallBack( TCallBack(ADelphiMethod), 3, DEFAULT_CALLBACK_TYPE), ADocString ); Result^.ml_flags := Result^.ml_flags or METH_KEYWORDS; end; @@ -7258,6 +6652,7 @@ procedure TError.Assign(Source: TPersistent); begin Name := TError(Source).Name; Text := TError(Source).Text; + ErrorType := TError(Source).ErrorType; Exit; end; inherited Assign(Source); @@ -7302,7 +6697,7 @@ procedure TError.BuildError( const ModuleName : AnsiString ); with Owner.Owner.Engine do begin if ErrorType = etString then - Error := PyString_FromString( PAnsiChar(Text) ) + Error := PyUnicodeFromString(Text) else if ErrorType = etClass then begin if FParentClass.Name <> '' then @@ -7322,13 +6717,12 @@ procedure TError.RaiseError( const msg : AnsiString ); begin Owner.Owner.CheckEngine; with Owner.Owner.Engine do - PyErr_SetString( Error, PAnsiChar(msg) ); + PyErr_SetString(Error, PAnsiChar(EncodeString(msg))); end; procedure TError.RaiseErrorObj( const msg : AnsiString; obj : PPyObject ); var args, res, str : PPyObject; - inst : PPyInstanceObject; i : Integer; keys : PPyObject; key : PPyObject; @@ -7347,21 +6741,12 @@ procedure TError.RaiseErrorObj( const msg : AnsiString; obj : PPyObject ); Py_DECREF(args); if not Assigned(res) then raise Exception.CreateFmt('TError.RaiseErrorObj: Could not create an instance of "%s"', [Self.Name]); - if PyInstance_Check( res ) then - begin - inst := PPyInstanceObject(res); - Py_XDECREF( inst^.in_dict ); - inst^.in_dict := obj; - str := PyString_FromString( PAnsiChar(msg) ); - PyDict_SetItemString( obj, 'args', str ); - Py_XDecRef(str); - end - else if PyObject_TypeCheck(res, PPyTypeObject(PyExc_Exception^)) then + if PyObject_TypeCheck(res, PPyTypeObject(PyExc_Exception^)) then begin args := PyTuple_New(1); if not Assigned(args) then raise Exception.Create('TError.RaiseErrorObj: Could not create an empty tuple'); - str := PyString_FromString( PAnsiChar(msg) ); + str := PyUnicodeFromString(msg); PyTuple_SetItem(args, 0, str); res := PyEval_CallObjectWithKeywords(Error, args, nil); Py_DECREF(args); @@ -7383,7 +6768,8 @@ procedure TError.RaiseErrorObj( const msg : AnsiString; obj : PPyObject ); end else raise Exception.Create('TError.RaiseErrorObj: I didn''t get an instance' ); - PyErr_SetObject( Error, res ); + PyErr_SetObject(Error, res); + Py_XDECREF(res); end else PyErr_SetObject( Error, obj ); @@ -7510,7 +6896,7 @@ procedure TPythonModule.DefineDocString; if DocString.Text <> '' then begin doc := - PyString_FromString(PChar(CleanString(FDocString.Text, False))); + PyUnicodeFromString(CleanString(FDocString.Text, False)); PyObject_SetAttrString( FModule, '__doc__', doc ); Py_XDecRef(doc); CheckError(False); @@ -7525,15 +6911,12 @@ procedure TPythonModule.MakeModule; Exit; with Engine do begin - if IsPython3000 then begin - FillChar(FModuleDef, SizeOf(FModuleDef), 0); - FModuleDef.m_base.ob_refcnt := 1; - FModuleDef.m_name := PAnsiChar(ModuleName); - FModuleDef.m_methods := MethodsData; - FModuleDef.m_size := -1; - FModule := Py_InitModule3000( ModuleDef ); - end else - FModule := Py_InitModule( PAnsiChar(ModuleName), MethodsData ); + FillChar(FModuleDef, SizeOf(FModuleDef), 0); + FModuleDef.m_base.ob_refcnt := 1; + FModuleDef.m_name := PAnsiChar(ModuleName); + FModuleDef.m_methods := MethodsData; + FModuleDef.m_size := -1; + FModule := Py_InitModule( ModuleDef ); DefineDocString; end; end; @@ -7569,9 +6952,10 @@ procedure TPythonModule.InitializeForNewInterpreter; end; end; -procedure TPythonModule.AddClient( client : TEngineClient ); +procedure TPythonModule.AddClient(Client : TEngineClient); begin - FClients.Add( client ); + if FClients.IndexOf(Client) < 0 then + FClients.Add(Client); end; function TPythonModule.ErrorByName( const AName : AnsiString ) : TError; @@ -7602,6 +6986,12 @@ procedure TPythonModule.RaiseErrorObj( const error, msg : AnsiString; obj : PPyO ErrorByName( error ).RaiseErrorObj( msg, obj ); end; +procedure TPythonModule.RemoveClient(Client: TEngineClient); +begin + // Remove does not raise an exception if not found + FClients.Remove(Client); +end; + procedure TPythonModule.BuildErrors; var i : Integer; @@ -7689,11 +7079,12 @@ function TPythonModule.GetVarAsVariant( const varName : AnsiString ) : Variant; with Engine do begin obj := GetVar( varName ); - try - Result := PyObjectAsVariant( obj ); - finally - Py_XDecRef(obj); - end; + if Assigned(obj) then + try + Result := PyObjectAsVariant( obj ); + finally + Py_XDecRef(obj); + end; end; end; @@ -7722,7 +7113,8 @@ constructor TPyObject.Create( APythonType : TPythonType ); end; end; -constructor TPyObject.CreateWith( APythonType : TPythonType; args : PPyObject ); +constructor TPyObject.CreateWith(APythonType: TPythonType; args, kwds: + PPyObject); begin Create( APythonType ); end; @@ -7816,7 +7208,7 @@ function TPyObject.GetAttr(key : PAnsiChar) : PPyObject; begin with GetPythonEngine do begin - PyKey := PyString_FromString(key); + PyKey := PyUnicodeFromString(key); try Result := PyObject_GenericGetAttr(GetSelf, PyKey) finally @@ -7831,15 +7223,15 @@ function TPyObject.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; begin Result := -1; PyErr_SetString (PyExc_AttributeError^, - PAnsiChar(AnsiString(Format('Unknown attribute "%s"',[key])))); + PAnsiChar(EncodeString(Format('Unknown attribute "%s"',[key])))); end; end; function TPyObject.Repr : PPyObject; begin - with GetPythonEngine do - Result := - PyString_FromString( PAnsiChar(AnsiString(Format('<%s at %x>', [PythonType.TypeName, NativeInt(self)]))) ); + Result := + GetPythonEngine.PyUnicodeFromString( Format('<%s at %x>', + [PythonType.TypeName, NativeInt(self)]) ); end; function TPyObject.Compare( obj: PPyObject) : Integer; @@ -7935,11 +7327,6 @@ function TPyObject.NbMultiply( obj : PPyObject) : PPyObject; Result := nil; end; -function TPyObject.NbDivide( obj : PPyObject) : PPyObject; -begin - Result := nil; -end; - function TPyObject.NbFloorDivide( obj : PPyObject) : PPyObject; begin Result := nil; @@ -7985,11 +7372,6 @@ function TPyObject.NbAbsolute : PPyObject; Result := nil; end; -function TPyObject.NbNonZero : Integer; -begin - Result := -1; -end; - function TPyObject.NbBool : Integer; begin Result := 0; @@ -8025,36 +7407,16 @@ function TPyObject.NbOr( obj : PPyObject) : PPyObject; Result := nil; end; -function TPyObject.NbCoerce( obj : PPPyObject) : Integer; -begin - Result := 0; -end; - function TPyObject.NbInt : PPyObject; begin Result := nil; end; -function TPyObject.NbLong : PPyObject; -begin - Result := nil; -end; - function TPyObject.NbFloat : PPyObject; begin Result := nil; end; -function TPyObject.NbOct : PPyObject; -begin - Result := nil; -end; - -function TPyObject.NbHex : PPyObject; -begin - Result := nil; -end; - function TPyObject.NbInplaceAdd(obj: PPyObject): PPyObject; begin Result := nil; @@ -8146,21 +7508,11 @@ function TPyObject.SqItem( idx : NativeInt ) : PPyObject; Result := GetPythonEngine.ReturnNone; end; -function TPyObject.SqSlice( idx1, idx2 : NativeInt ) : PPyObject; -begin - Result := GetPythonEngine.ReturnNone; -end; - function TPyObject.SqAssItem( idx : NativeInt; obj : PPyObject) : Integer; begin Result := -1; end; -function TPyObject.SqAssSlice( idx1, idx2 : NativeInt; obj : PPyObject): integer; -begin - Result := -1; -end; - function TPyObject.SqContains(obj: PPyObject): integer; begin Result := -1; @@ -8218,7 +7570,7 @@ class procedure TPyObject.SetupType(APythonType: TPythonType); constructor TTypeServices.Create; begin inherited; - FBasic := [bsGetAttr, bsSetAttr, bsRepr, bsStr]; + FBasic := [bsGetAttrO, bsSetAttrO, bsRepr, bsStr]; end; procedure TTypeServices.AssignTo( Dest: TPersistent ); @@ -8294,13 +7646,21 @@ procedure TPythonType.SetModule( val : TPythonModule ); begin if val <> FModule then begin + if Assigned(FModule) then + begin + FModule.RemoveFreeNotification(Self); + FModule.RemoveClient(Self); + end; FModule := val; if Assigned(val) then + begin + val.FreeNotification(Self); if Initialized and not (csLoading in ComponentState) then if val.Initialized then AddTypeVar else val.AddClient(Self); + end; end; end; @@ -8323,9 +7683,9 @@ procedure TPythonType.SetTypeName( const val : AnsiString ); end; end; -function TPythonType.CreateMethod( pSelf, args : PPyObject ) : PPyObject; +function TPythonType.CreateMethod(pSelf, args, kwds: PPyObject): PPyObject; begin - Result := CreateInstanceWith( args ); + Result := CreateInstanceWith(args, kwds); end; procedure TPythonType.ReallocGetSets; @@ -8350,32 +7710,22 @@ procedure TPythonType.ReallocMethods; FType.tp_methods := MethodsData; end; +procedure TPythonType.SetBaseType(AType: TPythonType); +begin + if AType = nil then + FType.tp_base := nil + else + FType.tp_base := @AType.FType; +end; + procedure TPythonType.SetDocString( value : TStringList ); begin FDocString.Assign( value ); end; -function TPythonType.TypeFlagsAsInt : LongInt; +function TPythonType.TypeFlagsAsInt : C_ULong; begin Result := 0; - if tpfHaveGetCharBuffer in TypeFlags then - Result := Result or Py_TPFLAGS_HAVE_GETCHARBUFFER; - if tpfHaveSequenceIn in TypeFlags then - Result := Result or Py_TPFLAGS_HAVE_SEQUENCE_IN; - if tpfGC in TypeFlags then - Result := Result or Py_TPFLAGS_GC; - if tpfHaveInplaceOps in TypeFlags then - Result := Result or Py_TPFLAGS_HAVE_INPLACEOPS; - if tpfCheckTypes in TypeFlags then - Result := Result or Py_TPFLAGS_CHECKTYPES; - if tpfHaveRichCompare in TypeFlags then - Result := Result or Py_TPFLAGS_HAVE_RICHCOMPARE; - if tpfHaveWeakRefs in TypeFlags then - Result := Result or Py_TPFLAGS_HAVE_WEAKREFS; - if tpfHaveIter in TypeFlags then - Result := Result or Py_TPFLAGS_HAVE_ITER; - if tpfHaveClass in TypeFlags then - Result := Result or Py_TPFLAGS_HAVE_CLASS; if tpfHeapType in TypeFlags then Result := Result or Py_TPFLAGS_HEAPTYPE; if tpfBaseType in TypeFlags then @@ -8386,6 +7736,28 @@ function TPythonType.TypeFlagsAsInt : LongInt; Result := Result or Py_TPFLAGS_READYING; if tpfHaveGC in TypeFlags then Result := Result or Py_TPFLAGS_HAVE_GC; + if tpVectorCall in TypeFlags then + Result := Result or _Py_TPFLAGS_HAVE_VECTORCALL; + if tpMethodDescriptor in TypeFlags then + Result := Result or Py_TPFLAGS_METHOD_DESCRIPTOR; + if tpHaveVersionTag in TypeFlags then + Result := Result or Py_TPFLAGS_HAVE_VERSION_TAG; + if tpValidVersionTag in TypeFlags then + Result := Result or Py_TPFLAGS_VALID_VERSION_TAG; + if tpIsAbstract in TypeFlags then + Result := Result or Py_TPFLAGS_IS_ABSTRACT; + if tpLongSubclass in TypeFlags then + Result := Result or Py_TPFLAGS_LONG_SUBCLASS; + if tpListSubClass in TypeFlags then + Result := Result or Py_TPFLAGS_LIST_SUBCLASS; + if tpTupleSubclass in TypeFlags then + Result := Result or Py_TPFLAGS_TUPLE_SUBCLASS; + if tpBytesSubclass in TypeFlags then + Result := Result or Py_TPFLAGS_BYTES_SUBCLASS; + if tpBaseExcSubclass in TypeFlags then + Result := Result or Py_TPFLAGS_BASE_EXC_SUBCLASS; + if tpTypeSubclass in TypeFlags then + Result := Result or Py_TPFLAGS_TYPE_SUBCLASS; end; // Type services @@ -8490,7 +7862,7 @@ function TPythonType.NewSubtypeInst( aType: PPyTypeObject; args, kwds : PPyObje obj.ob_type := aType; obj.IsSubtype := aType <> @FType; obj.PythonAlloc := True; - obj.CreateWith(Self, args); + obj.CreateWith(Self, args, kwds); if Engine.PyErr_Occurred <> nil then begin Engine.Py_DECREF(Result); @@ -8527,11 +7899,6 @@ function TPythonType_NbMultiply( pSelf, obj : PPyObject) : PPyObject; cdecl; Result := PythonToDelphi(pSelf).NbMultiply( obj ); end; -function TPythonType_NbDivide( pSelf, obj : PPyObject) : PPyObject; cdecl; -begin - Result := PythonToDelphi(pSelf).NbDivide( obj ); -end; - function TPythonType_NbFloorDivide( pSelf, obj : PPyObject) : PPyObject; cdecl; begin Result := PythonToDelphi(pSelf).NbFloorDivide( obj ); @@ -8577,11 +7944,6 @@ function TPythonType_NbAbsolute( pSelf : PPyObject ) : PPyObject; cdecl; Result := PythonToDelphi(pSelf).NbAbsolute; end; -function TPythonType_NbNonZero( pSelf : PPyObject ) : Integer; cdecl; -begin - Result := PythonToDelphi(pSelf).NbNonZero; -end; - function TPythonType_NbBool( pSelf : PPyObject ) : Integer; cdecl; begin Result := PythonToDelphi(pSelf).NbBool; @@ -8617,36 +7979,16 @@ function TPythonType_NbOr( pSelf, obj : PPyObject) : PPyObject; cdecl; Result := PythonToDelphi(pSelf).NbOr( obj ); end; -function TPythonType_NbCoerce( pSelf, obj : PPPyObject) : Integer; cdecl; -begin - Result := PythonToDelphi(pSelf^).NbCoerce( obj ); -end; - function TPythonType_NbInt( pSelf : PPyObject ) : PPyObject; cdecl; begin Result := PythonToDelphi(pSelf).NbInt; end; -function TPythonType_NbLong( pSelf : PPyObject ) : PPyObject; cdecl; -begin - Result := PythonToDelphi(pSelf).NbLong; -end; - function TPythonType_NbFloat( pSelf : PPyObject ) : PPyObject; cdecl; begin Result := PythonToDelphi(pSelf).NbFloat; end; -function TPythonType_NbOct( pSelf : PPyObject ) : PPyObject; cdecl; -begin - Result := PythonToDelphi(pSelf).NbOct; -end; - -function TPythonType_NbHex( pSelf : PPyObject ) : PPyObject; cdecl; -begin - Result := PythonToDelphi(pSelf).NbHex; -end; - function TPythonType_NbInplaceAdd(pSelf, obj: PPyObject): PPyObject; cdecl; begin Result := PythonToDelphi(pSelf).NbInplaceAdd( obj ); @@ -8739,22 +8081,11 @@ function TPythonType_SqItem( pSelf : PPyObject; idx : NativeInt ) : PPyObject; Result := PythonToDelphi(pSelf).SqItem( idx ); end; -function TPythonType_SqSlice( pSelf : PPyObject; idx1, idx2 : NativeInt ) : PPyObject; cdecl; -begin - Result := PythonToDelphi(pSelf).SqSlice( idx1, idx2 ); -end; - function TPythonType_SqAssItem( pSelf : PPyObject; idx : NativeInt; obj : PPyObject) : Integer; cdecl; begin Result := PythonToDelphi(pSelf).SqAssItem( idx, obj ); end; -function TPythonType_SqAssSlice( pSelf : PPyObject; idx1, idx2 : NativeInt; obj : PPyObject): integer; cdecl; -begin - Result := PythonToDelphi(pSelf).SqAssSlice( idx1, idx2, obj ); -end; - - // Mapping services function TPythonType_MpLength( pSelf : PPyObject ) : NativeInt; cdecl; @@ -8788,6 +8119,7 @@ function TPythonType_SqInplaceRepeat(pSelf : PPyObject; i: NativeInt): PPyObject end; procedure TPythonType.InitServices; +{ Called from TPythonType.Initialize which first calls CheckEngine - FEngine is alread assigned } begin with FType do begin @@ -8807,8 +8139,6 @@ procedure TPythonType.InitServices; tp_repr := TPythonType_Repr; if bsStr in Services.Basic then tp_str := TPythonType_Str; - if bsCompare in Services.Basic then - tp_compare := TPythonType_Compare; if bsHash in Services.Basic then tp_hash := TPythonType_Hash; if bsGetAttrO in Services.Basic then @@ -8831,127 +8161,70 @@ procedure TPythonType.InitServices; begin tp_init := TPythonType_InitSubtype; tp_alloc := TPythonType_AllocSubtypeInst; - tp_new := GetCallBack( Self, @TPythonType.NewSubtypeInst, 3, ctCDECL); + tp_new := GetCallBack( Self, @TPythonType.NewSubtypeInst, 3, DEFAULT_CALLBACK_TYPE); tp_free := FreeSubtypeInst; tp_methods := MethodsData; tp_members := MembersData; tp_getset := GetSetData; end; - // Number services + // Number services if Services.Number <> [] then begin - if GetPythonEngine.IsPython3000 then - begin - FNumber := AllocMem(SizeOf(PyNumberMethods300)); // zeroes memory - with PPyNumberMethods300(FNumber)^ do - begin - if nsAdd in Services.Number then nb_add := TPythonType_NbAdd; // #3.1 - if nsSubtract in Services.Number then nb_subtract := TPythonType_NbSubtract; // #3.2 - if nsMultiply in Services.Number then nb_multiply := TPythonType_NbMultiply; // #3.3 - if nsDivide in Services.Number then; // gone in Python 3.x - if nsFloorDivide in Services.Number then nb_floor_divide := TPythonType_NbFloorDivide; // #3.30 - if nsTrueDivide in Services.Number then nb_true_divide := TPythonType_NbTrueDivide; // #3.31 - if (nsMatrixMultiply in Services.Number) and ((GetPythonEngine.MajorVersion > 3) - or ((GetPythonEngine.MajorVersion = 3) and (GetPythonEngine.MinorVersion >= 5))) - then - nb_matrix_multiply := TPythonType_NbMatrixMultiply; // #3.35 - if nsRemainder in Services.Number then nb_remainder := TPythonType_NbRemainder; // #3.4 - if nsDivmod in Services.Number then nb_divmod := TPythonType_NbDivmod; // #3.5 - if nsPower in Services.Number then nb_power := TPythonType_NbPower; // #3.6 - if nsNegative in Services.Number then nb_negative := TPythonType_NbNegative; // #3.7 - if nsPositive in Services.Number then nb_positive := TPythonType_NbPositive; // #3.8 - if nsAbsolute in Services.Number then nb_absolute := TPythonType_NbAbsolute; // #3.9 - if nsNonZero in Services.Number then ; // gone in Python 3.x - if nsBool in Services.Number then nb_bool := TPythonType_NbBool; // #3.10 - if nsInvert in Services.Number then nb_invert := TPythonType_NbInvert; // #3.11 - if nsLShift in Services.Number then nb_lshift := TPythonType_NbLShift; // #3.12 - if nsRShift in Services.Number then nb_rshift := TPythonType_NbRShift; // #3.13 - if nsAnd in Services.Number then nb_and := TPythonType_NbAnd; // #3.14 - if nsXor in Services.Number then nb_xor := TPythonType_NbXor; // #3.15 - if nsOr in Services.Number then nb_or := TPythonType_NbOr; // #3.16 - if nsCoerce in Services.Number then ;// gone in Python 3.x - if nsInt in Services.Number then nb_int := TPythonType_NbInt; // #3.17 - if nsLong in Services.Number then ;// gone in Python 3.x, now nb_reserved - if nsFloat in Services.Number then nb_float := TPythonType_NbFloat; // #3.19 - if nsOct in Services.Number then ;// gone in Python 3.x - if nsHex in Services.Number then ;// gone in Python 3.x - if nsInplaceAdd in Services.InplaceNumber then nb_inplace_add := TPythonType_NbInplaceAdd; // #3.20 - if nsInplaceSubtract in Services.InplaceNumber then nb_inplace_subtract := TPythonType_NbInplaceSubtract; // #3.21 - if nsInplaceMultiply in Services.InplaceNumber then nb_inplace_multiply := TPythonType_NbInplaceMultiply; // #3.22 - if nsInplaceDivide in Services.InplaceNumber then ;// gone in Python 3.x - if nsInplaceFloorDivide in Services.InplaceNumber then nb_inplace_floor_divide := TPythonType_NbInplaceFloorDivide; // #3.32 - if nsInplaceTrueDivide in Services.InplaceNumber then nb_inplace_true_divide := TPythonType_NbInplaceTrueDivide; // #3.33 - if nsInplaceRemainder in Services.InplaceNumber then nb_inplace_remainder := TPythonType_NbInplaceRemainder; // #3.23 - if nsInplacePower in Services.InplaceNumber then nb_inplace_power := TPythonType_NbInplacePower; // #3.24 - if nsInplaceLShift in Services.InplaceNumber then nb_inplace_lshift := TPythonType_NbInplaceLShift; // #3.25 - if nsInplaceRShift in Services.InplaceNumber then nb_inplace_rshift := TPythonType_NbInplaceRShift; // #3.26 - if nsInplaceAnd in Services.InplaceNumber then nb_inplace_and := TPythonType_NbInplaceAnd; // #3.27 - if nsInplaceXor in Services.InplaceNumber then nb_inplace_xor := TPythonType_NbInplaceXor; // #3.28 - if nsInplaceOr in Services.InplaceNumber then nb_inplace_or := TPythonType_NbInplaceOr; // #3.29 - if (nsInplaceMatrixMultiply in Services.InplaceNumber) and - ((GetPythonEngine.MajorVersion > 3) or ((GetPythonEngine.MajorVersion = 3) - and (GetPythonEngine.MinorVersion >= 5))) - then - nb_inplace_matrix_multiply := TPythonType_NbInplaceMatrixMultiply; // #3.36 - end; - end - else + tp_as_number := @FNumber; + + with FNumber do begin - FNumber := AllocMem(SizeOf(PyNumberMethods200)); - with PPyNumberMethods200(FNumber)^ do - begin - if nsAdd in Services.Number then nb_add := TPythonType_NbAdd; // #2.1 - if nsSubtract in Services.Number then nb_subtract := TPythonType_NbSubtract; // #2.2 - if nsMultiply in Services.Number then nb_multiply := TPythonType_NbMultiply; // #2.3 - if nsDivide in Services.Number then nb_divide := TPythonType_NbDivide; // #2.4 - if nsFloorDivide in Services.Number then nb_floor_divide := TPythonType_NbFloorDivide; // #2.35 - if nsTrueDivide in Services.Number then nb_true_divide := TPythonType_NbTrueDivide; // #2.36 - if nsMatrixMultiply in Services.Number then ;// new in Python 3.x - if nsRemainder in Services.Number then nb_remainder := TPythonType_NbRemainder; // #2.5 - if nsDivmod in Services.Number then nb_divmod := TPythonType_NbDivmod; // #2.6 - if nsPower in Services.Number then nb_power := TPythonType_NbPower; // #2.7 - if nsNegative in Services.Number then nb_negative := TPythonType_NbNegative; // #2.8 - if nsPositive in Services.Number then nb_positive := TPythonType_NbPositive; // #2.9 - if nsAbsolute in Services.Number then nb_absolute := TPythonType_NbAbsolute; // #2.10 - if nsNonZero in Services.Number then nb_nonzero := TPythonType_NbNonZero; // #2.11 - if nsBool in Services.Number then // new in Python 3.x - if nsInvert in Services.Number then nb_invert := TPythonType_NbInvert; // #2.12 - if nsLShift in Services.Number then nb_lshift := TPythonType_NbLShift; // #2.13 - if nsRShift in Services.Number then nb_rshift := TPythonType_NbRShift; // #2.14 - if nsAnd in Services.Number then nb_and := TPythonType_NbAnd; // #2.15 - if nsXor in Services.Number then nb_xor := TPythonType_NbXor; // #2.16 - if nsOr in Services.Number then nb_or := TPythonType_NbOr; // #2.17 - if nsCoerce in Services.Number then nb_coerce := TPythonType_NbCoerce; // #2.18 - if nsInt in Services.Number then nb_int := TPythonType_NbInt; // #2.19 - if nsLong in Services.Number then nb_long := TPythonType_NbLong; // #2.20 - if nsFloat in Services.Number then nb_float := TPythonType_NbFloat; // #2.21 - if nsOct in Services.Number then nb_oct := TPythonType_NbOct; // #2.22 - if nsHex in Services.Number then nb_hex := TPythonType_NbHex; // #2.23 - if nsInplaceAdd in Services.InplaceNumber then nb_inplace_add := TPythonType_NbInplaceAdd; // #2.24 - if nsInplaceSubtract in Services.InplaceNumber then nb_inplace_subtract := TPythonType_NbInplaceSubtract; // #2.25 - if nsInplaceMultiply in Services.InplaceNumber then nb_inplace_multiply := TPythonType_NbInplaceMultiply; // #2.26 - if nsInplaceDivide in Services.InplaceNumber then nb_inplace_divide := TPythonType_NbInplaceDivide; // #2.27 - if nsInplaceFloorDivide in Services.InplaceNumber then nb_inplace_floor_divide := TPythonType_NbInplaceFloorDivide; // #2.37 - if nsInplaceTrueDivide in Services.InplaceNumber then nb_inplace_true_divide := TPythonType_NbInplaceTrueDivide; // #2.38 - if nsInplaceRemainder in Services.InplaceNumber then nb_inplace_remainder := TPythonType_NbInplaceRemainder; // #2.28 - if nsInplacePower in Services.InplaceNumber then nb_inplace_power := TPythonType_NbInplacePower; // #2.29 - if nsInplaceLShift in Services.InplaceNumber then nb_inplace_lshift := TPythonType_NbInplaceLShift; // #2.30 - if nsInplaceRShift in Services.InplaceNumber then nb_inplace_rshift := TPythonType_NbInplaceRShift; // #2.31 - if nsInplaceAnd in Services.InplaceNumber then nb_inplace_and := TPythonType_NbInplaceAnd; // #2.32 - if nsInplaceXor in Services.InplaceNumber then nb_inplace_xor := TPythonType_NbInplaceXor; // #2.33 - if nsInplaceOr in Services.InplaceNumber then nb_inplace_or := TPythonType_NbInplaceOr; // #2.34 - if nsInplaceMatrixMultiply in Services.InplaceNumber then ; // new in Python 3.5 - end; + if nsAdd in Services.Number then nb_add := TPythonType_NbAdd; // #3.1 + if nsSubtract in Services.Number then nb_subtract := TPythonType_NbSubtract; // #3.2 + if nsMultiply in Services.Number then nb_multiply := TPythonType_NbMultiply; // #3.3 + if nsFloorDivide in Services.Number then nb_floor_divide := TPythonType_NbFloorDivide; // #3.30 + if nsTrueDivide in Services.Number then nb_true_divide := TPythonType_NbTrueDivide; // #3.31 + if (nsMatrixMultiply in Services.Number) and ((FEngine.MajorVersion > 3) + or ((FEngine.MajorVersion = 3) and (FEngine.MinorVersion >= 5))) + then + nb_matrix_multiply := TPythonType_NbMatrixMultiply; // #3.35 + if nsRemainder in Services.Number then nb_remainder := TPythonType_NbRemainder; // #3.4 + if nsDivmod in Services.Number then nb_divmod := TPythonType_NbDivmod; // #3.5 + if nsPower in Services.Number then nb_power := TPythonType_NbPower; // #3.6 + if nsNegative in Services.Number then nb_negative := TPythonType_NbNegative; // #3.7 + if nsPositive in Services.Number then nb_positive := TPythonType_NbPositive; // #3.8 + if nsAbsolute in Services.Number then nb_absolute := TPythonType_NbAbsolute; // #3.9 + if nsBool in Services.Number then nb_bool := TPythonType_NbBool; // #3.10 + if nsInvert in Services.Number then nb_invert := TPythonType_NbInvert; // #3.11 + if nsLShift in Services.Number then nb_lshift := TPythonType_NbLShift; // #3.12 + if nsRShift in Services.Number then nb_rshift := TPythonType_NbRShift; // #3.13 + if nsAnd in Services.Number then nb_and := TPythonType_NbAnd; // #3.14 + if nsXor in Services.Number then nb_xor := TPythonType_NbXor; // #3.15 + if nsOr in Services.Number then nb_or := TPythonType_NbOr; // #3.16 + if nsInt in Services.Number then nb_int := TPythonType_NbInt; // #3.17 + if nsFloat in Services.Number then nb_float := TPythonType_NbFloat; // #3.19 + if nsInplaceAdd in Services.InplaceNumber then nb_inplace_add := TPythonType_NbInplaceAdd; // #3.20 + if nsInplaceSubtract in Services.InplaceNumber then nb_inplace_subtract := TPythonType_NbInplaceSubtract; // #3.21 + if nsInplaceMultiply in Services.InplaceNumber then nb_inplace_multiply := TPythonType_NbInplaceMultiply; // #3.22 + if nsInplaceFloorDivide in Services.InplaceNumber then nb_inplace_floor_divide := TPythonType_NbInplaceFloorDivide; // #3.32 + if nsInplaceTrueDivide in Services.InplaceNumber then nb_inplace_true_divide := TPythonType_NbInplaceTrueDivide; // #3.33 + if nsInplaceRemainder in Services.InplaceNumber then nb_inplace_remainder := TPythonType_NbInplaceRemainder; // #3.23 + if nsInplacePower in Services.InplaceNumber then nb_inplace_power := TPythonType_NbInplacePower; // #3.24 + if nsInplaceLShift in Services.InplaceNumber then nb_inplace_lshift := TPythonType_NbInplaceLShift; // #3.25 + if nsInplaceRShift in Services.InplaceNumber then nb_inplace_rshift := TPythonType_NbInplaceRShift; // #3.26 + if nsInplaceAnd in Services.InplaceNumber then nb_inplace_and := TPythonType_NbInplaceAnd; // #3.27 + if nsInplaceXor in Services.InplaceNumber then nb_inplace_xor := TPythonType_NbInplaceXor; // #3.28 + if nsInplaceOr in Services.InplaceNumber then nb_inplace_or := TPythonType_NbInplaceOr; // #3.29 + if (nsInplaceMatrixMultiply in Services.InplaceNumber) and + ((FEngine.MajorVersion > 3) or ((FEngine.MajorVersion = 3) + and (FEngine.MinorVersion >= 5))) + then + nb_inplace_matrix_multiply := TPythonType_NbInplaceMatrixMultiply; // #3.36 end; - tp_as_number := FNumber; end; // Sequence services if Services.Sequence <> [] then + begin tp_as_sequence := @FSequence; - with FSequence do + with FSequence do begin if ssLength in Services.Sequence then sq_length := TPythonType_SqLength; @@ -8961,12 +8234,8 @@ procedure TPythonType.InitServices; sq_repeat := TPythonType_SqRepeat; if ssItem in Services.Sequence then sq_item := TPythonType_SqItem; - if ssSlice in Services.Sequence then - sq_slice := TPythonType_SqSlice; if ssAssItem in Services.Sequence then sq_ass_item := TPythonType_SqAssItem; - if ssAssSlice in Services.Sequence then - sq_ass_slice := TPythonType_SqAssSlice; if ssContains in Services.Sequence then sq_contains := TPythonType_SqContains; if ssInplaceConcat in Services.Sequence then @@ -8974,12 +8243,14 @@ procedure TPythonType.InitServices; if ssInplaceRepeat in Services.Sequence then sq_inplace_repeat := TPythonType_SqInplaceRepeat; end; + end; // Mapping services if Services.Mapping <> [] then + begin tp_as_mapping := @FMapping; - with FMapping do + with FMapping do begin if msLength in Services.Mapping then mp_length := TPythonType_MpLength; @@ -8988,6 +8259,7 @@ procedure TPythonType.InitServices; if msAssSubscript in Services.Mapping then mp_ass_subscript := TPythonType_MpAssSubscript; end; + end; end; end; @@ -9007,9 +8279,9 @@ destructor TPythonType.Destroy; begin if gVarType = Self then gVarType := nil; + Module := nil; FDocString.Free; FServices.Free; - FreeMem(FNumber); inherited; end; @@ -9041,7 +8313,8 @@ procedure TPythonType.Initialize; procedure TPythonType.Finalize; begin - Engine.Py_XDECREF(FCreateFunc); + if Assigned(Engine) then + Engine.Py_CLEAR(FCreateFunc); FCreateFunc := nil; inherited; end; @@ -9065,14 +8338,14 @@ function TPythonType.CreateInstance : PPyObject; end; end; -function TPythonType.CreateInstanceWith( args : PPyObject ) : PPyObject; +function TPythonType.CreateInstanceWith(args, kwds: PPyObject): PPyObject; var obj : TPyObject; begin CheckEngine; with Engine do begin - obj := PyObjectClass.CreateWith( Self, args ); + obj := PyObjectClass.CreateWith(Self, args, kwds); obj.ob_type := @FType; if PyErr_Occurred <> nil then begin @@ -9087,7 +8360,7 @@ function TPythonType.CreateInstanceWith( args : PPyObject ) : PPyObject; procedure TPythonType.AddTypeVar; var d : PPyObject; - meth : TDelphiMethod; + meth : TDelphiMethodWithKW; begin CheckEngine; Assert(Module <> nil); @@ -9100,13 +8373,11 @@ procedure TPythonType.AddTypeVar; begin meth := CreateMethod; FCreateFuncDef.ml_name := PAnsiChar(FCreateFuncName); - FCreateFuncDef.ml_meth := GetOfObjectCallBack( TCallBack(meth), 2, ctCDECL); - FCreateFuncDef.ml_flags := METH_VARARGS; + FCreateFuncDef.ml_meth := GetOfObjectCallBack(TCallBack(meth), 3, DEFAULT_CALLBACK_TYPE); + FCreateFuncDef.ml_flags := METH_KEYWORDS; FCreateFuncDef.ml_doc := PAnsiChar(FCreateFuncDoc); - if GetPythonEngine.IsPython3000 then - FCreateFunc := Engine.PyCFunction_NewEx(@FCreateFuncDef, nil, nil) - else - FCreateFunc := Engine.PyCFunction_New(@FCreateFuncDef, nil); + FCreateFunc := Engine.PyCFunction_NewEx(@FCreateFuncDef, nil, nil); + Engine.Py_INCREF(FCreateFunc); end; Assert(Assigned(FCreateFunc)); end; @@ -9342,7 +8613,7 @@ constructor TPyVar.Create( APythonType : TPythonType ); // the Create constructor first, and because the constructors // are virtual, TPyVar.Create will be automatically be called. -constructor TPyVar.CreateWith( APythonType : TPythonType; args : PPyObject ); +constructor TPyVar.CreateWith(APythonType: TPythonType; args, kwds: PPyObject); begin inherited; with GetPythonEngine do @@ -9367,26 +8638,26 @@ destructor TPyVar.Destroy; // Then we override the needed services -function TPyVar.GetAttr(key : PAnsiChar) : PPyObject; +function TPyVar.GetAttrO( key: PPyObject) : PPyObject; begin with GetPythonEngine do begin - if CompareText( AnsiString(key), 'Value') = 0 then + if CompareText( PyObjectAsString(key), 'Value') = 0 then Result := GetValue else - Result := inherited GetAttr(key); + Result := inherited GetAttrO(key); end; end; -function TPyVar.SetAttr(key : PAnsiChar; value : PPyObject) : Integer; +function TPyVar.SetAttrO( key, value: PPyObject) : Integer; begin Result := 0; with GetPythonEngine do begin - if CompareText( AnsiString(key), 'Value' ) = 0 then + if CompareText( PyObjectAsString(key), 'Value' ) = 0 then SetValue( value ) else - Result := inherited SetAttr(key, value); + Result := inherited SetAttrO(key, value); end; end; @@ -9399,8 +8670,8 @@ function TPyVar.Repr : PPyObject; obj := GetValue; try Result := - PyString_FromString( PAnsiChar(AnsiString(Format('<%s: %s>', - [PythonType.TypeName, PyObjectAsString(obj)]))) ); + PyUnicodeFromString(Format('<%s: %s>', + [PythonType.TypeName, PyObjectAsString(obj)]) ); finally Py_XDecRef(obj); end; @@ -9513,29 +8784,22 @@ procedure TPyVar.SetValueFromVariant( const value : Variant ); procedure TPythonThread.Execute; var - withinterp: Boolean; global_state : PPyThreadState; gilstate : PyGILState_STATE; begin - withinterp := Assigned( fInterpreterState); with GetPythonEngine do begin - if withinterp then + if fThreadExecMode = emNewState then begin - fThreadExecMode := emNewState; - fThreadState := PyThreadState_New( fInterpreterState); - if Assigned(fThreadState) then - begin - PyEval_AcquireThread(fThreadState); + gilstate := PyGILState_Ensure(); + try + fThreadState := GetThreadState; ExecuteWithPython; - PyEval_ReleaseThread( fThreadState); - PyThreadState_Clear( fThreadState); - PyThreadState_Delete( fThreadState); - end else - raise EPythonError.Create( 'Could not create a new thread state'); - end else {withinterp} + finally + PyGILState_Release(gilstate); + end; + end else {fThreadExecMode} begin - fThreadExecMode := emNewInterpreter; gilstate := PyGILState_Ensure(); global_state := PyThreadState_Get; PyThreadState_Swap(nil); @@ -9555,24 +8819,24 @@ procedure TPythonThread.Execute; end; -procedure TPythonThread.Py_Begin_Allow_Threads; +class procedure TPythonThread.Py_Begin_Allow_Threads; begin with GetPythonEngine do f_savethreadstate := PyEval_SaveThread; end; -procedure TPythonThread.Py_End_Allow_Threads; +class procedure TPythonThread.Py_End_Allow_Threads; begin with GetPythonEngine do PyEval_RestoreThread( f_savethreadstate); end; -procedure TPythonThread.Py_Begin_Block_Threads; +class procedure TPythonThread.Py_Begin_Block_Threads; begin Py_End_Allow_Threads; end; -procedure TPythonThread.Py_Begin_Unblock_Threads; +class procedure TPythonThread.Py_Begin_Unblock_Threads; begin Py_Begin_Allow_Threads; end; @@ -9597,7 +8861,7 @@ function pyio_write(self, args : PPyObject) : PPyObject; if GetCurrentThreadId <> MainThreadId then with GetPythonEngine do begin - if RedirectIO and (IO <> nil) and (IO.ClassName <> 'TPythonInputOutput') then + if RedirectIO and (IO <> nil) and (IO.ClassName <> 'TPythonInputOutput') and not IO.DelayWrites then begin Result := GetPythonEngine.ReturnNone; Exit; @@ -9612,10 +8876,9 @@ function pyio_write(self, args : PPyObject) : PPyObject; if RedirectIO and (IO <> nil) and Assigned(a1) then begin if PyUnicode_Check(a1) then - IO.Write(PyUnicode_AsWideString(a1)) + IO.Write(PyUnicodeAsString(a1)) else - if PyString_Check(a1) then - IO.Write(PyObjectAsString(a1)); + IO.Write(IOString(PyObjectAsString(a1))); end; Result := ReturnNone; end @@ -9640,23 +8903,19 @@ function pyio_read(self, args : PPyObject) : PPyObject; if Assigned(IO) then if IO.UnicodeIO then begin Widetxt := IO.ReceiveUniData; - // KV!!!!!! if PyErr_Occurred <> nil then Result := nil else - // KV!!!!!! - Result := PyUnicode_FromWideString(PWideChar(Widetxt)); + Result := PyUnicodeFromString(PWideChar(Widetxt)); end else begin txt := IO.ReceiveData; - // KV!!!!!! if PyErr_Occurred <> nil then Result := nil else - // KV!!!!!! - Result := PyString_FromString(PAnsiChar(txt)); + Result := PyUnicodeFromString(txt); end else - Result := PyString_FromString(PAnsiChar(txt)); + Result := PyUnicodeFromString(txt); end else Result := ReturnNone; @@ -9710,29 +8969,13 @@ function pyio_GetTypesStats(self, args : PPyObject) : PPyObject; with GetPythonEngine do begin Result := PyTuple_New(4); - PyTuple_SetItem( Result, 0, PyString_FromString(PAnsiChar(T.TypeName)) ); - PyTuple_SetItem( Result, 1, PyInt_FromLong(T.InstanceCount) ); - PyTuple_SetItem( Result, 2, PyInt_FromLong(T.CreateHits) ); - PyTuple_SetItem( Result, 3, PyInt_FromLong(T.DeleteHits) ); + PyTuple_SetItem( Result, 0, PyUnicodeFromString(T.TypeName)); + PyTuple_SetItem( Result, 1, PyLong_FromLong(T.InstanceCount) ); + PyTuple_SetItem( Result, 2, PyLong_FromLong(T.CreateHits) ); + PyTuple_SetItem( Result, 3, PyLong_FromLong(T.DeleteHits) ); end; end; - function FindType( const TName : AnsiString ) : TPythonType; - var - i : Integer; - begin - Result := nil; - with GetPythonEngine do - for i := 0 to ClientCount - 1 do - if Clients[i] is TPythonType then - with TPythonType(Clients[i]) do - if TypeName = TName then - begin - Result := TPythonType(Clients[i]); - Break; - end; - end; - var i : Integer; T : TPythonType; @@ -9746,7 +8989,7 @@ function pyio_GetTypesStats(self, args : PPyObject) : PPyObject; for i := 0 to PyTuple_Size(args)-1 do begin str := AnsiString(PyObjectAsString( PyTuple_GetItem(args, i) )); - T := FindType( str ); + T := FindPythonType( str ); if Assigned(T) then begin obj := HandleType( T ); @@ -9766,9 +9009,6 @@ function pyio_GetTypesStats(self, args : PPyObject) : PPyObject; end; - - - (*******************************************************) (** **) (** Global procedures **) @@ -9779,9 +9019,8 @@ function GetPythonEngine : TPythonEngine; begin if not Assigned( gPythonEngine ) then raise Exception.Create( 'No Python engine was created' ); - if not gPythonEngine.Finalizing then - if not gPythonEngine.Initialized then - raise Exception.Create( 'The Python engine is not properly initialized' ); + if not gPythonEngine.Finalizing and not gPythonEngine.Initialized then + raise Exception.Create( 'The Python engine is not properly initialized' ); Result := gPythonEngine; end; @@ -9820,6 +9059,14 @@ procedure Register; TPythonType, TPythonModule, TPythonDelphiVar]); end; +function SysVersionFromDLLName(const DLLFileName : string): string; +var + Minor, Major: integer; +begin + PythonVersionFromDLLName(DLLFileName, Major, Minor); + Result := Format('%d.%d', [Major, Minor]); +end; + function PyType_HasFeature(AType : PPyTypeObject; AFlag : Integer) : Boolean; begin //(((t)->tp_flags & (f)) != 0) @@ -9845,28 +9092,10 @@ procedure MaskFPUExceptions(ExceptionsMasked : boolean; {$endif} end; -(* -function CleanString(const s : AnsiString; AppendLF : Boolean) : AnsiString; -var - i : Integer; -begin - result := s; - if s = '' then - Exit; - i := Pos(AnsiString(CR),s); - while i > 0 do - begin - Delete( result, i, 1 ); - i := PosEx(AnsiString(CR),result, i); - end; - if AppendLF and (result[length(result)] <> LF) then - Result := Result + LF; -end; -*) - function CleanString(const s : AnsiString; AppendLF : Boolean) : AnsiString; begin Result := AdjustLineBreaks(s, tlbsLF); + if Result = '' then Exit; if AppendLF and (result[length(result)] <> LF) then Result := Result + LF; end; @@ -9917,5 +9146,55 @@ function IsPythonVersionRegistered(PythonVersion : AnsiString; end; {$ENDIF} +procedure PythonVersionFromDLLName(LibName: string; out MajorVersion, MinorVersion: integer); +//Windows: 'c:\some\path\python310.dll' +//Linux: '/some/path/libpython3.10m.so' +const + cPython = 'python'; + DefaultMajor = 3; + DefaultMinor = 4; +var + NPos: integer; + ch: char; +begin + MajorVersion:= DefaultMajor; + MinorVersion:= DefaultMinor; + LibName:= LowerCase(ExtractFileName(LibName)); //strip path + NPos:= Pos(cPython, LibName); + if NPos=0 then exit; + Inc(NPos, Length(cPython)); + if NPos>Length(LibName) then exit; + ch:= LibName[NPos]; + case ch of + '2'..'5': //support major versions 2...5 + MajorVersion:= StrToIntDef(ch, DefaultMajor); + else + exit; + end; + Delete(LibName, 1, NPos); + if LibName='' then exit; + case LibName[1] of + '.': //Unix name with dot + Delete(LibName, 1, 1); + '0'..'9': //Windows name w/o dot + begin end; + else //unknown char after major version + exit; + end; + //strip file extension and handle 'libpython3.10m.so' + for NPos:= 1 to Length(LibName) do + begin + case LibName[NPos] of + '.', 'a'..'z': + begin + SetLength(LibName, NPos-1); + Break + end; + end; + end; + //the rest is minor version number '0'...'999' + MinorVersion:= StrToIntDef(LibName, DefaultMinor); +end; + end. diff --git a/python4lazarus/PythonGUIInputOutput.pas b/python4lazarus/PythonGUIInputOutput.pas index f8f79e6..83d80f4 100644 --- a/python4lazarus/PythonGUIInputOutput.pas +++ b/python4lazarus/PythonGUIInputOutput.pas @@ -182,9 +182,18 @@ procedure TPythonGUIInputOutput.WriteOutput; begin if FQueue.Count = 0 then Exit; - S := FQueue.Strings[ 0 ]; - FQueue.Delete(0); - DisplayString( S ) + + Lock; + try + while FQueue.Count > 0 do + begin + S := FQueue.Strings[ 0 ]; + FQueue.Delete(0); + DisplayString( S ); + end; + finally + Unlock; + end; end; {PUBLIC METHODS} diff --git a/python4lazarus/PythonVersions.pas b/python4lazarus/PythonVersions.pas index f5d60ff..6b746de 100644 --- a/python4lazarus/PythonVersions.pas +++ b/python4lazarus/PythonVersions.pas @@ -1,7 +1,6 @@ {----------------------------------------------------------------------------- Unit Name: PythonVersions - Author: Kiriakos - Date: PyScripter + Author: PyScripter Purpose: Discover and get info about Python versions Part of the Python for Delphi library @@ -57,8 +56,7 @@ TPythonVersion = record The function result has the semantics of Delphi compare functions -1: A is bigger (newer), 0: equal versions, 1: B is bigger (newer) *) - function CompareVersions(A, B : string) : Integer; - + function CompareVersions(A, B : string) : Integer; {$IFDEF MSWINDOWS} (* Checks whether an executable was compiled for X64 *) @@ -69,11 +67,14 @@ TPythonVersion = record function GetRegisteredPythonVersion(SysVersion: string; out PythonVersion: TPythonVersion): Boolean; (* Returns all registered Python versions *) - function GetRegisteredPythonVersions : TPythonVersions; + function GetRegisteredPythonVersions(const MinVersion: string = '0.0'; + const MaxVersion: string = '100.100'): TPythonVersions; (* Returns the highest numbered registered Python version *) - function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion): Boolean; + function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion; + const MinVersion: string = '0.0'; const MaxVersion: string = '100.100'): Boolean; function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVersion; - AcceptVirtualEnvs: Boolean = True): Boolean; + AcceptVirtualEnvs: Boolean = True; const MinVersion: string = '0.0'; + const MaxVersion: string = '100.100'): Boolean; {$ENDIF} implementation @@ -92,7 +93,9 @@ implementation function TPythonVersion.GetDLLName: string; begin {$IFDEF MSWINDOWS} - Result := 'python' + SysVersion[1] + SysVersion[3] + '.dll'; + Result := SysVersion; + Delete(Result, 2, 1); + Result := 'python' + Result + '.dll'; {$ELSE} Result := 'libpython' + SysVersion + '.so'; {$ENDIF} @@ -101,13 +104,7 @@ function TPythonVersion.GetDLLName: string; function TPythonVersion.ExpectedArchitecture: string; begin Result := ''; - {$IFDEF CPUX64} - Result := '64bit'; - {$ENDIF} - {$IFDEF CPU64} - Result := '64bit'; - {$ENDIF} - {$IFDEF CPU64bits} + {$IF Defined(CPUX64) or Defined(CPU64) or Defined(CPU64bits)} Result := '64bit'; {$ENDIF} if Result = '' then @@ -169,17 +166,24 @@ function TPythonVersion.GetDisplayName: string; function TPythonVersion.GetHelpFile: string; var PythonHelpFilePath: string; + HtmlIndex: string; Res: Integer; SR: TSearchRec; begin Result := FHelpFile; - // for unregistered Python - if (Result = '') and (InstallPath <> '') then + // for unregistered Python or python 11 + if ((Result = '') or (ExtractFileExt(Result) = '.html')) and (InstallPath <> '') then begin - PythonHelpFilePath := InstallPath + '\Doc\python*.chm'; + PythonHelpFilePath := IncludeTrailingPathDelimiter(InstallPath) + 'Doc\python*.chm'; Res := FindFirst(PythonHelpFilePath, faAnyFile, SR); if Res = 0 then - Result := InstallPath + '\Doc\' + SR.Name; + Result := IncludeTrailingPathDelimiter(InstallPath) + 'Doc\' + SR.Name + else if Result = '' then + begin + HtmlIndex := IncludeTrailingPathDelimiter(InstallPath) + 'Doc\html\index.html'; + if FileExists(HtmlIndex) then + Result := HtmlIndex; + end; FindClose(SR); end; end; @@ -400,7 +404,8 @@ function GetRegisteredPythonVersion(SysVersion: string; PythonVersion.IsRegistered := Result; end; -function GetRegisteredPythonVersions : TPythonVersions; +function GetRegisteredPythonVersions(const MinVersion: string = '0.0'; + const MaxVersion: string = '100.100'): TPythonVersions; Var Count: Integer; I: Integer; @@ -409,27 +414,40 @@ function GetRegisteredPythonVersions : TPythonVersions; Count := 0; SetLength(Result, High(PYTHON_KNOWN_VERSIONS)); for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do + begin + if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MaxVersion) < 0 then + continue; + if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MinVersion) > 0 then + break; if GetRegisteredPythonVersion(PYTHON_KNOWN_VERSIONS[I].RegVersion, PythonVersion) then begin Result[Count] := PythonVersion; Inc(Count); end; + end; SetLength(Result, Count); end; -function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion): Boolean; +function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion; + const MinVersion: string = '0.0'; const MaxVersion: string = '100.100'): Boolean; Var I: Integer; begin + Result := False; for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do begin - Result := GetRegisteredPythonVersion(PYTHON_KNOWN_VERSIONS[I].RegVersion, PythonVersion); - if Result then break; + if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MaxVersion) < 0 then + continue; + if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MinVersion) > 0 then + break; + if GetRegisteredPythonVersion(PYTHON_KNOWN_VERSIONS[I].RegVersion, PythonVersion) then + Exit(True); end; end; function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVersion; - AcceptVirtualEnvs: Boolean = True): Boolean; + AcceptVirtualEnvs: Boolean = True; const MinVersion: string = '0.0'; + const MaxVersion: string = '100.100'): Boolean; function FindPythonDLL(APath : string): string; Var @@ -438,15 +456,15 @@ function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVer DLLFileName: string; begin Result := ''; - Handle := FindFirstFile(PWideChar(APath+'\python??.dll'), FindFileData); + Handle := FindFirstFile(PWideChar(APath+'\python*.dll'), FindFileData); if Handle = INVALID_HANDLE_VALUE then Exit; // not python dll DLLFileName:= FindFileData.cFileName; // skip if python3.dll was found - if Length(DLLFileName) <> 12 then FindNextFile(Handle, FindFileData); + if Length(DLLFileName) <= 11 then FindNextFile(Handle, FindFileData); if Handle = INVALID_HANDLE_VALUE then Exit; Windows.FindClose(Handle); DLLFileName:= FindFileData.cFileName; - if Length(DLLFileName) = 12 then + if Length(DLLFileName) > 11 then Result := DLLFileName; end; @@ -506,16 +524,20 @@ function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVer end; PythonVersion.DLLPath := DLLPath; - SysVersion := GetPythonVersionFromDLLName(DLLFileName); + SysVersion := SysVersionFromDLLName(DLLFileName); PythonVersion.SysVersion := SysVersion; PythonVersion.fSysArchitecture := PythonVersion.ExpectedArchitecture; - for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do - if PYTHON_KNOWN_VERSIONS[I].RegVersion = SysVersion then begin - Result := True; - break; - end; + if (CompareVersions(MinVersion, SysVersion) >= 0) and + (CompareVersions(MaxVersion, SysVersion) <= 0) + then + // Full search in case some python version is not supported + for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do + if PYTHON_KNOWN_VERSIONS[I].RegVersion = SysVersion then begin + Result := True; + break; + end; end; {$ENDIF} diff --git a/python4lazarus/VarPyth.pas b/python4lazarus/VarPyth.pas new file mode 100644 index 0000000..29f2328 --- /dev/null +++ b/python4lazarus/VarPyth.pas @@ -0,0 +1,2180 @@ +{$I Definition.Inc} + +unit VarPyth; + +(**************************************************************************) +(* *) +(* Module: Unit 'VarPyth' Copyright (c) 2001 *) +(* *) +(* Version: 1.0 Morgan Martinet *) +(* Sub-Version: 0.7 4723 rue Brebeuf *) +(* H2J 3L2 MONTREAL (QC) *) +(* CANADA *) +(* e-mail: p4d@mmm-experts.com *) +(* *) +(**************************************************************************) +(* Functionality: This allows you to use Python objects like COM *) +(* automation objects, inside your Delphi source code. *) +(* This is a replacement of the former PythonAtom.pas *) +(* that uses the new custom variant types introduced *) +(* in Delphi6. *) +(**************************************************************************) +(* Contributors: *) +(**************************************************************************) +(* This source code is distributed with no WARRANTY, for no reason or use.*) +(* Everyone is allowed to use and change this code free for his own tasks *) +(* and projects, as long as this header and its copyright text is intact. *) +(* For changed versions of this code, which are public distributed the *) +(* following additional conditions have to be fullfilled: *) +(* 1) The header has to contain a comment on the change and the author of *) +(* it. *) +(* 2) A copy of the changed source has to be sent to the above E-Mail *) +(* address or my then valid address, if this is possible to the *) +(* author. *) +(* The second condition has the target to maintain an up to date central *) +(* version of the component. If this condition is not acceptable for *) +(* confidential or legal reasons, everyone is free to derive a component *) +(* or to generate a diff file to my or other original sources. *) +(**************************************************************************) + +interface + +uses + Variants, PythonEngine, Classes; + +type + TSequenceType = (stTuple, stList); + +{ Python variant creation utils } +function VarPythonCreate( AObject : PPyObject ) : Variant; overload; +function VarPythonCreate( const AValue : Variant ) : Variant; overload; +function VarPythonCreate( const AValues : array of const; ASequenceType : TSequenceType = stList ) : Variant; overload; +function VarPythonEval( const APythonExpression : AnsiString) : Variant; + +{ Python variant helper functions } +function VarPython: TVarType; +function VarIsPython(const AValue: Variant): Boolean; +function VarAsPython(const AValue: Variant): Variant; +function ExtractPythonObjectFrom(const AValue : Variant) : PPyObject; +function VarIsSame(const A, B : Variant ) : Boolean; // checks if 2 variants share the same Python object. +function VarIsSameType(const A, B : Variant ) : Boolean; // checks if 2 variants are of the same Python type. +function VarIsPythonSequence(const AValue: Variant): Boolean; +function VarIsPythonMapping(const AValue: Variant): Boolean; +function VarIsPythonNumber(const AValue: Variant): Boolean; +function VarIsPythonString(const AValue: Variant): Boolean; +function VarIsPythonInteger(const AValue: Variant): Boolean; +function VarIsPythonFloat(const AValue: Variant): Boolean; +function VarIsPythonTuple(const AValue: Variant): Boolean; +function VarIsPythonList(const AValue: Variant): Boolean; +function VarIsPythonDict(const AValue: Variant): Boolean; +function VarIsPythonClass(const AValue: Variant): Boolean; +function VarIsPythonMethod(const AValue: Variant): Boolean; +function VarIsPythonFunction(const AValue: Variant): Boolean; +function VarIsPythonModule(const AValue: Variant): Boolean; +function VarIsPythonCallable(const AValue: Variant): Boolean; +function VarIsPythonIterator(const AValue: Variant): Boolean; +function VarIsPythonUnicode(const AValue: Variant): Boolean; +function VarIsPythonDateTime(const AValue: Variant): Boolean; +function VarIsPythonDate(const AValue: Variant): Boolean; +function VarIsPythonTime(const AValue: Variant): Boolean; +function VarIsPythonDateTimeDelta(const AValue: Variant): Boolean; +function VarIsPythonTZInfo(const AValue: Variant): Boolean; +function VarIsBool(const AValue: Variant): Boolean; +function VarIsEnum(const AValue: Variant): Boolean; +function VarIsInstanceOf(const AInstance, AClass : Variant): Boolean; +function VarIsSubclassOf(const ADerived, AClass : Variant): Boolean; +function VarIsSubtypeOf(const ADerived, AType : Variant): Boolean; +function VarIsNone(const AValue : Variant): Boolean; +function VarIsTrue(const AValue : Variant): Boolean; + +function VarModuleHasObject(const AModule : Variant; aObj: AnsiString): Boolean; + +function NewPythonList( const ASize : Integer = 0 ): Variant; +function NewPythonTuple( const ASize : Integer ): Variant; +function NewPythonDict: Variant; + +// Not really needed since you can assign a PythonVariant to a string anyway +// but it is slightly faster and in some places avoids the declaration of a variable +function VarPythonAsString(AValue : Variant) : string; +{$IFDEF FPC} +// to work around http://mantis.freepascal.org/view.php?id=20849) +function VarPythonToVariant(AValue : Variant): Variant; +{$ENDIF} + +function None: Variant; +function Ellipsis: Variant; +function MainModule: Variant; // return the main module that's used for executing a script. +function BuiltinModule: Variant; // return the builtin module +function SysModule: Variant; // return the builtin module 'sys' +function DatetimeModule: Variant; // return the builtin module 'datetime' +function Import(const AModule: string): Variant; // import a Python module and return the module object. +function Reload(const AModule: Variant): Variant; //reload a Python imported module and return the module object. +function len(const AValue : Variant ): NativeInt; // return the length of a Python collection. +function _type(const AValue : Variant ): Variant; // return the type object of a Python object. +function iter(const AValue : Variant ): Variant; // return an iterator for the container AValue. You can call the 'next' method of the iterator until you catch the EPyStopIteration exception. + +type + TVarPyEnumerator = record + private + FIterator: Variant; + FCurrent: Variant; + public + constructor Create(const AValue: Variant); + function MoveNext: Boolean; inline; + function GetCurrent: Variant; inline; + property Current: Variant read GetCurrent; + end; + + TVarPyEnumerateHelper = record + private + FIterable: Variant; + public + constructor Create(const AValue: Variant); + function GetEnumerator: TVarPyEnumerator; + end; + +function VarPyIterate(const AValue: Variant): TVarPyEnumerateHelper; + +// Adds a python iterable items to a TStrings +procedure VarPyToStrings(const AValue : Variant; const AStrings: TStrings); + +implementation + +uses + VarUtils, SysUtils, TypInfo; + +type + TNamedParamDesc = record + Index : Integer; + Name : AnsiString; + end; + TNamedParamArray = array of TNamedParamDesc; + +{$IF not defined(FPC) and (defined(OSX64) or defined(LINUX) or not defined(DELPHI10_4_OR_HIGHER))} + {$DEFINE PATCHEDSYSTEMDISPINVOKE} //To correct memory leaks +{$IFEND} + + { Python variant type handler } + TPythonVariantType = class(TInvokeableVariantType, IVarInstanceReference) + protected + fNamedParams : TNamedParamArray; + function LeftPromotion(const V: TVarData; const AOperator: TVarOp; + out RequiredVarType: TVarType): Boolean; override; + function RightPromotion(const V: TVarData; const AOperator: TVarOp; + out RequiredVarType: TVarType): Boolean; override; + function GetInstance(const V: TVarData): TObject; + function EvalPython(const V: TVarData; const AName: AnsiString; + const Arguments: TVarDataArray): PPyObject; + function VarDataToPythonObject( AVarData : TVarData ) : PPyObject; + procedure PyhonVarDataCreate( var Dest : TVarData; AObject : PPyObject ); + {$IFDEF FPC} + procedure VarDataClear(var Dest: TVarData); + procedure VarDataCopyNoInd(var Dest: TVarData; const Source: TVarData); + procedure VarDataCastTo(var Dest: TVarData; const Source: TVarData; + const AVarType: TVarType); overload; + {$ELSE} + function FixupIdent(const AText: string): string; override; + {$ENDIF FPC} + public + procedure Clear(var V: TVarData); override; + function IsClear(const V: TVarData): Boolean; override; + procedure Copy(var Dest: TVarData; const Source: TVarData; + const Indirect: Boolean); override; + procedure Cast(var Dest: TVarData; const Source: TVarData); override; + procedure CastTo(var Dest: TVarData; const Source: TVarData; + const AVarType: TVarType); override; + + procedure BinaryOp(var Left: TVarData; const Right: TVarData; + const AOperator: TVarOp); override; + procedure UnaryOp(var Right: TVarData; const AOperator: TVarOp); override; + function CompareOp(const Left: TVarData; const Right: TVarData; + const AOperator: TVarOp): Boolean; override; + function DoFunction(var Dest: TVarData; const V: TVarData; + const AName: string; const Arguments: TVarDataArray): Boolean; override; + function DoProcedure(const V: TVarData; const AName: string; + const Arguments: TVarDataArray): Boolean; override; + function GetProperty(var Dest: TVarData; const V: TVarData; + const AName: string): Boolean; override; + function SetProperty({$IFDEF FPC}var{$ELSE}const{$ENDIF} V: TVarData; const AName: string; + const Value: TVarData): Boolean; override; + {$IFDEF DELPHIXE7_OR_HIGHER} + procedure DispInvoke(Dest: PVarData; + [Ref] const Source: TVarData; CallDesc: PCallDesc; Params: Pointer);override; + {$ELSE} + procedure DispInvoke(Dest: PVarData; + var Source: TVarData; CallDesc: PCallDesc; Params: Pointer);override; + {$ENDIF} + end; + +var + { Python variant type handler instance } + PythonVariantType: TPythonVariantType = nil; + +type + { Python data that the Python variant points to } + TPythonData = class(TObject) + private + fPyObject: PPyObject; + function GetAsString: string; + procedure SetPyObject(const Value: PPyObject); + function GetAsVariant: Variant; + function GetAsWideString: UnicodeString; + function GetAsAnsiString: AnsiString; + public + constructor Create(AObject : PPyObject); + destructor Destroy; override; + + // query state + function IsNone : Boolean; + + // non-destructive operations + function Equal(const Right: TPythonData): Boolean; + function LessThan(const Right: TPythonData): Boolean; + function LessOrEqualThan(const Right: TPythonData): Boolean; + function GreaterThan(const Right: TPythonData): Boolean; + function GreaterOrEqualThan(const Right: TPythonData): Boolean; + + // destructive operations + procedure DoAdd(const Right: TPythonData); + procedure DoSubtract(const Right: TPythonData); + procedure DoMultiply(const Right: TPythonData); + procedure DoDivide(const Right: TPythonData); + procedure DoIntDivide(const Right: TPythonData); + procedure DoModulus(const Right: TPythonData); + procedure DoShiftLeft(const Right: TPythonData); + procedure DoShiftRight(const Right: TPythonData); + procedure DoAnd(const Right: TPythonData); + procedure DoOr(const Right: TPythonData); + procedure DoXor(const Right: TPythonData); + procedure DoNegate; + procedure DoNot; + + // conversion + property AsString: string read GetAsString; + property AsAnsiString: AnsiString read GetAsAnsiString; + property AsVariant: Variant read GetAsVariant; + property AsWideString: UnicodeString read GetAsWideString; + + // data + property PyObject : PPyObject read fPyObject write SetPyObject; + end; + +type + { Helper record that helps crack open TVarData } + TPythonVarData = packed record + VType: TVarType; + Reserved1, Reserved2, Reserved3: Word; + VPython: TPythonData; + Reserved4: Integer; + {$IFDEF CPU64BITS} + Reserved5: Integer; // size is 24 bytes in 64bit + {$ENDIF CPU64BITS} + end; + + +resourcestring + SMultiDimensionalPropsNotSupported = 'Multi-dimensional sequences or mappings are not supported in Python'; + SCantConvertArg = 'Can''t convert argument #%d of %s into a Python object'; + SCantConvertKeyToPythonObject = 'Can''t convert Key into a Python object'; + SCantConvertValueToPythonObject = 'Can''t convert Value into a Python object'; + SCantCreateNewSequenceObject = 'Can''t create a new sequence object'; + SExpectedPythonVariant = 'Expected a Python variant'; + +{ Python variant creation utils } + +function VarPythonCreate( AObject : PPyObject ) : Variant; +begin + VarClear(Result); + if Assigned(AObject) then + begin + TPythonVarData(Result).VType := VarPython; + TPythonVarData(Result).VPython := TPythonData.Create(AObject); + end; // of if +end; + +function VarPythonCreate( const AValue : Variant ) : Variant; +var + _value : PPyObject; +begin + if VarIsPython(AValue) then + Result := AValue + else + with GetPythonEngine do + begin + _value := VariantAsPyObject(AValue); + try + Result := VarPythonCreate( _value ); + finally + Py_XDecRef(_value); + end; + end; // of with +end; + +function VarPythonCreate( const AValues : array of const; ASequenceType : TSequenceType = stList ) : Variant; +var + i : Integer; + _seq, _item : PPyObject; +begin + with GetPythonEngine do + begin + if ASequenceType = stTuple then + _seq := PyTuple_New( High(AValues)-Low(AValues)+1 ) + else + _seq := PyList_New( High(AValues)-Low(AValues)+1 ); + if not Assigned(_seq) then + raise Exception.Create(SCantCreateNewSequenceObject); + try + for i := Low(AValues) to High(AValues) do + begin + if (AValues[i].VType = vtVariant) and VarIsPython(AValues[i].VVariant^) then + begin + _item := ExtractPythonObjectFrom( AValues[i].VVariant^ ); + Py_XIncRef(_item); + end + else + _item := VarRecAsPyObject( AValues[i] ); + if ASequenceType = stTuple then + PyTuple_SetItem( _seq, i, _item ) + else + PyList_SetItem( _seq, i, _item ); + end; // of for + Result := VarPythonCreate( _seq ); + finally + Py_XDecRef(_seq); + end; // of try + end; // of with +end; + +function VarPythonEval( const APythonExpression : AnsiString) : Variant; +var + _obj : PPyObject; +begin + with GetPythonEngine do + begin + _obj := EvalString(APythonExpression); + try + Result := VarPythonCreate( _obj ); + finally + Py_XDecRef(_obj); + end; + end; +end; + +function VarPython: TVarType; +begin + Result := PythonVariantType.VarType; +end; + +function VarIsPython(const AValue: Variant): Boolean; +begin + Result := (TVarData(AValue).VType and varTypeMask) = VarPython; +end; + +function VarAsPython(const AValue: Variant): Variant; +begin + if not VarIsPython(AValue) then + VarCast(Result, AValue, VarPython) + else + Result := AValue; +end; + +// note that the returned reference to the Python object is a borrowed reference (not pre-incremented). +function ExtractPythonObjectFrom(const AValue : Variant) : PPyObject; +begin + if VarIsPython(AValue) then + Result := TPythonVarData(AValue).VPython.PyObject + else + Result := nil; +end; + +function VarIsSame(const A, B : Variant ) : Boolean; +begin + Result := ExtractPythonObjectFrom(A) = ExtractPythonObjectFrom(B); +end; + +function VarIsSameType(const A, B : Variant ) : Boolean; +var + _obj1, _obj2 : PPyObject; +begin + _obj1 := ExtractPythonObjectFrom(A); + _obj2 := ExtractPythonObjectFrom(B); + Result := Assigned(_obj1) and Assigned(_obj2) and (_obj1^.ob_type = _obj2^.ob_type); +end; + +//------------------------------------------------------------------------------ +{ Python variant helper functions } +function VarIsPythonSequence(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + (GetPythonEngine.PySequence_Check(ExtractPythonObjectFrom(AValue)) <> 0); +end; + +function VarIsPythonMapping(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + (GetPythonEngine.PyMapping_Check(ExtractPythonObjectFrom(AValue)) <> 0); +end; + +function VarIsPythonNumber(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + (GetPythonEngine.PyNumber_Check(ExtractPythonObjectFrom(AValue)) <> 0); +end; + +function VarIsPythonString(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyUnicode_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonInteger(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyLong_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonFloat(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyFloat_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonTuple(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyTuple_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonList(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyList_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonDict(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyDict_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonClass(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + (GetPythonEngine.PyClass_Check(ExtractPythonObjectFrom(AValue)) + or (GetPythonEngine.PyObject_HasAttrString(ExtractPythonObjectFrom(AValue), '__bases__') <> 0)); +end; + +function VarIsPythonMethod(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyMethod_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonFunction(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyFunction_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonModule(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyModule_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonCallable(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + (GetPythonEngine.PyCallable_Check(ExtractPythonObjectFrom(AValue)) <> 0); +end; + +function VarIsPythonIterator(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + (GetPythonEngine.PyIter_Check(ExtractPythonObjectFrom(AValue))); +end; + +function VarIsPythonUnicode(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyUnicode_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonDateTime(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyDateTime_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonDate(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyDate_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonTime(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyTime_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonDateTimeDelta(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyDelta_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsPythonTZInfo(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyTZInfo_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsBool(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyBool_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsEnum(const AValue: Variant): Boolean; +begin + Result := VarIsPython(AValue) and + GetPythonEngine.PyEnum_Check(ExtractPythonObjectFrom(AValue)); +end; + +function VarIsInstanceOf(const AInstance, AClass : Variant): Boolean; +begin + with GetPythonEngine do + begin + Result := VarIsPython(AInstance) and VarIsPython(AClass) and + (PyObject_IsInstance( ExtractPythonObjectFrom(AInstance), + ExtractPythonObjectFrom(AClass)) <> 0); + CheckError; + end; // of with +end; + +function VarIsSubclassOf(const ADerived, AClass : Variant): Boolean; +begin + with GetPythonEngine do + begin + Result := VarIsPython(ADerived) and VarIsPython(AClass) and + (PyObject_IsSubclass( ExtractPythonObjectFrom(ADerived), + ExtractPythonObjectFrom(AClass)) <> 0); + CheckError; + end; // of with +end; + +function VarIsSubtypeOf(const ADerived, AType : Variant): Boolean; +begin + with GetPythonEngine do + begin + Result := VarIsPython(ADerived) and VarIsPython(AType) and + (PyType_IsSubtype( ExtractPythonObjectFrom(ADerived)^.ob_type, + PPyTypeObject(ExtractPythonObjectFrom(AType))) <> 0); + CheckError; + end; // of with +end; + +function VarIsNone(const AValue : Variant): Boolean; +begin + Result := VarIsPython(AValue) and + (ExtractPythonObjectFrom(AValue) = GetPythonEngine.Py_None); +end; + +function VarIsTrue(const AValue : Variant): Boolean; +begin + Result := AValue; // the cast into a boolean will call the PyObject_IsTrue API. +end; + +function VarModuleHasObject(const AModule : Variant; aObj: AnsiString): Boolean; +begin + with GetPythonEngine do + Result := VarIsPython(AModule) and + PyModule_Check(ExtractPythonObjectFrom(AModule)) and + Assigned(PyDict_GetItemString( + PyModule_GetDict(ExtractPythonObjectFrom(AModule)),PAnsiChar(aObj))); +end; + +function NewPythonList( const ASize : Integer = 0 ): Variant; +var + _list : PPyObject; +begin + with GetPythonEngine do + begin + _list := PyList_New(ASize); + try + Result := VarPythonCreate( _list ); + finally + Py_XDecRef(_list); + end; // of try + end; // of with +end; + +function NewPythonTuple( const ASize : Integer ): Variant; +var + _tuple : PPyObject; +begin + with GetPythonEngine do + begin + _tuple := PyTuple_New(ASize); + try + Result := VarPythonCreate( _tuple ); + finally + Py_XDecRef(_tuple); + end; // of try + end; // of with +end; + +function NewPythonDict: Variant; +var + _dict : PPyObject; +begin + with GetPythonEngine do + begin + _dict := PyDict_New; + try + Result := VarPythonCreate( _dict ); + finally + Py_XDecRef(_dict); + end; // of try + end; // of with +end; + +function VarPythonAsString(AValue : Variant) : string; +begin + if VarIsPython(AValue) then + Result := TPythonVarData(AValue).VPython.AsString + else + Result := AValue; +end; + +{$IFDEF FPC} +function VarPythonToVariant(AValue : Variant): Variant; +begin + if VarIsPython(AValue) then + Result := + GetPythonEngine.PyObjectAsVariant(TPythonVarData(AValue).VPython.PyObject) + else + Result := AValue; +end; +{$ENDIF} + +function None : Variant; +begin + with GetPythonEngine do + Result := VarPythonCreate(Py_None); +end; + +function Ellipsis : Variant; +begin + with GetPythonEngine do + Result := VarPythonCreate(Py_Ellipsis); +end; + +function MainModule : Variant; +var + _main : PPyObject; +begin + _main := GetPythonEngine.GetMainModule; // the refcount is not pre-incremented + Assert(Assigned(_main)); + Result := VarPythonCreate(_main); +end; + +function BuiltinModule : Variant; +begin + Result := Import(GetPythonEngine.BuiltInModuleName); +end; + +function SysModule : Variant; +begin + Result := Import('sys'); +end; + +function DatetimeModule : Variant; // return the builtin module 'datetime' +begin + Result := Import('datetime'); +end; + +function Import(const AModule: string): Variant; +var + _module : PPyObject; + _module_name : PPyObject; +begin + with GetPythonEngine do + begin + _module_name := PyUnicodeFromString(AModule); + try + _module := PyImport_Import(_module_name); + CheckError; + finally + Py_XDecRef(_module_name); + end; // of try + Assert(Assigned(_module)); + try + Result := VarPythonCreate(_module); + finally + Py_XDecRef(_module); + end; // of try + end; // of with +end; + +function Reload(const AModule: Variant): Variant; +var + LModule: PPyObject; +begin + with GetPythonEngine() do begin + LModule := PyImport_ReloadModule(ExtractPythonObjectFrom(AModule)); + CheckError(); + Assert(Assigned(LModule)); + try + Result := VarPythonCreate(LModule); + finally + Py_XDecRef(LModule); + end; // of try + end; // of with +end; + +function GetObjectLength(AObject: PPyObject): NativeInt; +begin + with GetPythonEngine do + begin + PyErr_Clear; + Result := PyObject_Length(AObject); + CheckError; + end; // of with +end; + +// returns the length of a Python collection. +function len(const AValue : Variant ) : NativeInt; +begin + if VarIsPython(AValue) then + Result := GetObjectLength( ExtractPythonObjectFrom(AValue) ) + else + raise Exception.Create(SExpectedPythonVariant); +end; + +function _type(const AValue : Variant ) : Variant; +begin + if VarIsPython(AValue) then + Result := VarPythonCreate( PPyObject( ExtractPythonObjectFrom(AValue)^.ob_type ) ) + else + raise Exception.Create(SExpectedPythonVariant); +end; + +function iter(const AValue : Variant ) : Variant; +var + _iter : PPyObject; +begin + if VarIsPython(AValue) then + with GetPythonEngine do + begin + PyErr_Clear; + _iter := PyObject_GetIter(ExtractPythonObjectFrom(AValue)); + CheckError; + try + Result := VarPythonCreate(_iter); + finally + Py_XDecRef(_iter); + end; + end + else + raise Exception.Create(SExpectedPythonVariant); +end; + +//------------------------------------------------------------------------------ +{ TPythonVariantType } + +procedure TPythonVariantType.BinaryOp(var Left: TVarData; + const Right: TVarData; const AOperator: TVarOp); +begin + if Right.VType = VarType then + case Left.VType of + varString, varUString: + case AOperator of + opAdd: + Variant(Left) := Variant(Left) + TPythonVarData(Right).VPython.AsString; + else + RaiseInvalidOp; + end; // of varString + else + if Left.VType = VarType then + case AOperator of + opAdd: + TPythonVarData(Left).VPython.DoAdd(TPythonVarData(Right).VPython); + opSubtract: + TPythonVarData(Left).VPython.DoSubtract(TPythonVarData(Right).VPython); + opMultiply: + TPythonVarData(Left).VPython.DoMultiply(TPythonVarData(Right).VPython); + opDivide: + TPythonVarData(Left).VPython.DoDivide(TPythonVarData(Right).VPython); + opIntDivide: + TPythonVarData(Left).VPython.DoIntDivide(TPythonVarData(Right).VPython); + opModulus: + TPythonVarData(Left).VPython.DoModulus(TPythonVarData(Right).VPython); + opShiftLeft: + TPythonVarData(Left).VPython.DoShiftLeft(TPythonVarData(Right).VPython); + opShiftRight: + TPythonVarData(Left).VPython.DoShiftRight(TPythonVarData(Right).VPython); + opAnd: + TPythonVarData(Left).VPython.DoAnd(TPythonVarData(Right).VPython); + opOr: + TPythonVarData(Left).VPython.DoOr(TPythonVarData(Right).VPython); + opXor: + TPythonVarData(Left).VPython.DoXor(TPythonVarData(Right).VPython); + else + RaiseInvalidOp; + end // of case + else + RaiseInvalidOp; + end // of case + else + RaiseInvalidOp; +end; + +procedure TPythonVariantType.Cast(var Dest: TVarData; + const Source: TVarData); +var + _object : PPyObject; +begin + _object := VarDataToPythonObject(Source); + try + PyhonVarDataCreate( Dest, _object ); + finally + GetPythonEngine.Py_XDECREF(_object); + end; +end; + +procedure TPythonVariantType.CastTo(var Dest: TVarData; + const Source: TVarData; const AVarType: TVarType); +var + V : Variant; +begin + if Source.VType = VarType then + case AVarType of + varOleStr: + VarDataFromOleStr(Dest, TPythonVarData(Source).VPython.AsWideString); + varUString: + {$IFDEF FPC} + VarDataFromOleStr(Dest, TPythonVarData(Source).VPython.AsWideString); + {$ELSE} + VarDataFromStr(Dest, TPythonVarData(Source).VPython.AsWideString); + {$ENDIF} + varString: + // Preserve AnsiStrings + {$IFDEF FPC} + Variant(Dest) := TPythonVarData(Source).VPython.AsWideString; + {$ELSE} + VarDataFromLStr(Dest, TPythonVarData(Source).VPython.AsAnsiString); + {$ENDIF} + else + if AVarType and varTypeMask = varBoolean then + begin + Dest.VType := varBoolean; + Dest.VBoolean := GetPythonEngine.PyObject_IsTrue( TPythonVarData(Source).VPython.PyObject ) = 1; + end + else + begin + V := TPythonVarData(Source).VPython.AsVariant; + VarDataCastTo(Dest, TVarData(V), AVarType); + end; + end // of case + else + inherited; +end; + +{$IFDEF FPC} +procedure TPythonVariantType.VarDataClear(var Dest: TVarData); +begin + VarClear(Variant(Dest)); +end; + +procedure TPythonVariantType.VarDataCopyNoInd(var Dest: TVarData; const Source: TVarData); +begin + VarCopyNoInd(Variant(Dest), Variant(Source)); +end; + +procedure TPythonVariantType.VarDataCastTo(var Dest: TVarData; const Source: TVarData; + const AVarType: TVarType); overload; +begin + VarCast(Variant(Dest), Variant(Source), AVarType); +end; +{$ENDIF} + +procedure TPythonVariantType.Clear(var V: TVarData); +begin + V.VType := varEmpty; + FreeAndNil(TPythonVarData(V).VPython); +end; + +function TPythonVariantType.CompareOp(const Left, Right: TVarData; + const AOperator: TVarOp): Boolean; +begin + Result := False; + if (Left.VType = VarType) and (Right.VType = VarType) then + case AOperator of + opCmpEQ: + Result := TPythonVarData(Left).VPython.Equal(TPythonVarData(Right).VPython); + opCmpNE: + Result := not TPythonVarData(Left).VPython.Equal(TPythonVarData(Right).VPython); + opCmpLT: + Result := TPythonVarData(Left).VPython.LessThan(TPythonVarData(Right).VPython); + opCmpLE: + Result := TPythonVarData(Left).VPython.LessOrEqualThan(TPythonVarData(Right).VPython); + opCmpGT: + Result := TPythonVarData(Left).VPython.GreaterThan(TPythonVarData(Right).VPython); + opCmpGE: + Result := TPythonVarData(Left).VPython.GreaterOrEqualThan(TPythonVarData(Right).VPython); + else + RaiseInvalidOp; + end // of case + else + RaiseInvalidOp; +end; + +procedure TPythonVariantType.Copy(var Dest: TVarData; + const Source: TVarData; const Indirect: Boolean); +begin + if Indirect and VarDataIsByRef(Source) then + VarDataCopyNoInd(Dest, Source) + else + PyhonVarDataCreate( Dest, TPythonVarData(Source).VPython.PyObject ); +end; + +procedure SetClearVarToEmptyParam(var V: TVarData); +begin + VarClear(Variant(V)); + V.VType := varError; +{$IFNDEF FPC} + V.VError := VAR_PARAMNOTFOUND; +{$ELSE} + V.VError := HRESULT($80020004); {DISP_E_PARAMNOTFOUND} +{$ENDIF} +end; + +const + CDoMethod = $01; + CPropertyGet = $02; + CPropertySet = $04; + +{$IF defined(PATCHEDSYSTEMDISPINVOKE) and (defined(OSX64) or defined(LINUX))} +{ + Fixes https://quality.embarcadero.com/browse/RSP-28097 +} +var + _EmptyBSTR: PWideChar = nil; + +Const + SDispatchError = 'Variant method calls not supported'; + +procedure _DispInvokeError; +begin + raise EVariantDispatchError.Create(SDispatchError); +end; + +function GetDispatchInvokeArgs(CallDesc: PCallDesc; Params: Pointer; var Strings: TStringRefList; OrderLTR : Boolean): TVarDataArray; +const + { Parameter type masks - keep in sync with decl.h/ap* enumerations} + atString = $48; + atUString = $4A; + atVarMask = $3F; + atTypeMask = $7F; + atByRef = $80; +var + I: Integer; + ArgType: Byte; + PVarParm: PVarData; + StringCount: Integer; + VAList: TVarArgList; + Temp: Pointer; +begin + VAList := TVarArgList(Params^); + StringCount := 0; + SetLength(Result, CallDesc^.ArgCount); + for I := 0 to CallDesc^.ArgCount-1 do + begin + ArgType := CallDesc^.ArgTypes[I]; + + if OrderLTR then + PVarParm := @Result[I] + else + PVarParm := @Result[CallDesc^.ArgCount-I-1]; + + if (ArgType and atByRef) = atByRef then + begin + Temp := VarArgGetValue(VAList, Pointer); + if (ArgType and atTypeMask) = atString then + begin + PVarData(PVarParm)^.VType := varByRef or varOleStr; + PVarData(PVarParm)^.VPointer := Strings[StringCount].FromAnsi( PAnsiString(Temp)); + Inc(StringCount); + end + else + if (ArgType and atTypeMask) = atUString then + begin + PVarData(PVarParm)^.VType := varByRef or varOleStr; + PVarData(PVarParm)^.VPointer := Strings[StringCount].FromUnicode(PUnicodeString(Temp)); + Inc(StringCount); + end + else + begin + if ((ArgType and atTypeMask) = varVariant) and + ((PVarData(Temp)^.VType = varString) or (PVarData(Temp)^.VType = varUString)) then + VarCast(PVariant(Temp)^, PVariant(Temp)^, varOleStr); + //PVarData(PVarParm)^.VType := varByRef or (ArgType and atTypeMask); + + ArgType := ArgType and atTypeMask; + if DispatchUnsignedAsSigned then + case ArgType of + varUInt64: ArgType := varInt64; + varUInt32: ArgType := varInteger; + varWord: ArgType := varSmallint; + varByte: ArgType := varShortInt; + end; + PVarData(PVarParm)^.VType := varByRef or ArgType; + + PVarData(PVarParm)^.VPointer := Temp; + end; + end + else // ByVal + begin + PVarParm^.VType := ArgType; + case ArgType of + varEmpty, varNull: ; // Only need to set VType + varInteger: PVarParm^.VInteger := VarArgGetValue(VAList, Integer); + varSingle: PVarParm^.VSingle := VarArgGetValue(VAList, Single); + varDouble: PVarParm^.VDouble := VarArgGetValue(VAList, Double); + varCurrency: PVarParm^.VCurrency := VarArgGetValue(VAList, Currency); + varDate: PVarParm^.VDate := VarArgGetValue(VAList, TDateTime); + varOleStr: PVarParm^.VPointer := VarArgGetValue(VAList, Pointer); + varDispatch: PVarParm^.VDispatch := VarArgGetValue(VAList, Pointer); + varError: PVarParm^.VError := HRESULT($80020004); //DISP_E_PARAMNOTFOUND; + varBoolean: PVarParm^.VBoolean := VarArgGetValue(VAList, Boolean); + varVariant: + begin + PVarParm^.VType := varEmpty; +{$IFDEF CPUX64} + +// PVariant(PVarParm)^ := PVariant(Params^)^; + PVariant(PVarParm)^ := VarArgGetValue(VAList, PVariant)^; +{$ELSE} +// PVariant(PVarParm)^ := PVariant(Params)^; + PVariant(PVarParm)^ := VarArgGetValue(VAList, Variant); +{$ENDIF} + end; + varUnknown: PVarParm^.VUnknown := VarArgGetValue(VAList, Pointer); + varSmallint: PVarParm^.VSmallInt := VarArgGetValue(VAList, SmallInt); + varShortInt: PVarParm^.VShortInt := VarArgGetValue(VAList, ShortInt); + varByte: PVarParm^.VByte := VarArgGetValue(VAList, Byte); + varWord: + begin + if DispatchUnsignedAsSigned then + begin + PVarParm^.VType := varInteger; + PVarParm^.VInteger := Integer(VarArgGetValue(VAList, Word)); + end else + PVarParm^.VWord := VarArgGetValue(VAList, Word); + end; + varUInt32: + begin + if DispatchUnsignedAsSigned then + begin + PVarParm^.VType := varInteger; + PVarParm^.VInteger := Integer(VarArgGetValue(VAList, Cardinal)); + end else + PVarParm^.VUInt32 := VarArgGetValue(VAList, Cardinal); + end; + varInt64: PVarParm^.VInt64 := VarArgGetValue(VAList, Int64); + varUInt64: + begin + if DispatchUnsignedAsSigned then + begin + PVarParm^.VType := varInt64; + PVarParm^.VInt64 := VarArgGetValue(VAList, Int64); //Int64(PInt64(Params)^); + end else + PVarParm^.VUInt64 := VarArgGetValue(VAList, UInt64); //PUInt64(Params)^; + end; + atString: + begin + PVarParm^.VType := varOleStr; + Temp := VarArgGetValue(VAList, Pointer); + if AnsiString(Temp) <> '' then + begin + { + This line causes a crash and is replaced with the one below in line with unicode strings + PVarParm^.VPointer := PWideChar(Strings[StringCount].FromAnsi(PAnsiString(Temp))^); + } + PVarParm^.VPointer := PWideChar(Strings[StringCount].FromAnsi(@AnsiString(Temp))^); + Strings[StringCount].Ansi := nil; + Inc(StringCount); + end + else + PVarParm^.VPointer := _EmptyBSTR; + end; + atUString: + begin + PVarParm^.VType := varOleStr; + Temp := VarArgGetValue(VAList, Pointer); + if UnicodeString(Temp) <> '' then + begin + PVarParm^.VPointer := PWideChar(Strings[StringCount].FromUnicode(@UnicodeString(Temp))^); + Strings[StringCount].Unicode := nil; + Inc(StringCount); + end + else + PVarParm^.VPointer := _EmptyBSTR; + end; + else + // Unsupported Var Types + //varDecimal = $000E; { vt_decimal 14 } {UNSUPPORTED as of v6.x code base} + //varUndef0F = $000F; { undefined 15 } {UNSUPPORTED per Microsoft} + //varRecord = $0024; { VT_RECORD 36 } + //varString = $0100; { Pascal string 256 } {not OLE compatible } + //varAny = $0101; { Corba any 257 } {not OLE compatible } + //varUString = $0102; { Unicode string 258 } {not OLE compatible } + _DispInvokeError; + end; + end; + end; +end; +{$IFEND} + +{$IFDEF DELPHIXE7_OR_HIGHER} +procedure TPythonVariantType.DispInvoke(Dest: PVarData; + [Ref] const Source: TVarData; CallDesc: PCallDesc; Params: Pointer); +{$ELSE} +procedure TPythonVariantType.DispInvoke(Dest: PVarData; + var Source: TVarData; CallDesc: PCallDesc; Params: Pointer); +{$ENDIF} +{$IFDEF PATCHEDSYSTEMDISPINVOKE} + // Modified to correct memory leak QC102387 / RSP-23093 + procedure PatchedFinalizeDispatchInvokeArgs(CallDesc: PCallDesc; const Args: TVarDataArray; OrderLTR : Boolean); + const + atByRef = $80; + var + I: Integer; + ArgType: Byte; + PVarParm: PVarData; + VType: TVarType; + begin + for I := 0 to CallDesc^.ArgCount-1 do + begin + ArgType := CallDesc^.ArgTypes[I]; + + if OrderLTR then + PVarParm := @Args[I] + else + PVarParm := @Args[CallDesc^.ArgCount-I-1]; + + VType := PVarParm.VType; + + // Only ByVal Variant or Array parameters have been copied and need to be released + // Strings have been released via the use of the TStringRefList parameter to GetDispatchInvokeArgs + // !!Modified to prevent memory leaks!! RSP-23093 + if ((ArgType and atByRef) <> atByRef) and ((ArgType = varVariant) or ((VType and varArray) = varArray)) then + VarClear(PVariant(PVarParm)^); + end; + end; + + procedure PatchedDispInvoke(Dest: PVarData; + const Source: TVarData; CallDesc: PCallDesc; Params: Pointer); + {$IFNDEF DELPHI10_4_OR_HIGHER} + type + PStringRefList = ^TStringRefList; + {$ENDIF} + const + CDoMethod = $01; + CPropertyGet = $02; + CPropertySet = $04; + var + I, LArgCount: Integer; + LIdent: string; + LTemp: TVarData; + VarParams : TVarDataArray; + {$IFNDEF DELPHI10_4_OR_HIGHER} + Strings: array of TStringRef; + {$ELSE} + Strings: TStringRefList; + {$ENDIF} + PIdent: PByte; + begin + // Grab the identifier + LArgCount := CallDesc^.ArgCount; + PIdent := @CallDesc^.ArgTypes[LArgCount]; + LIdent := FixupIdent( UTF8ToString(MarshaledAString(PIdent)) ); + if LArgCount > 0 then begin + SetLength(Strings, LArgCount); + {$IFNDEF DELPHI10_4_OR_HIGHER} + VarParams := GetDispatchInvokeArgs(CallDesc, Params, PStringRefList(Strings)^, true); + {$ELSE} + VarParams := GetDispatchInvokeArgs(CallDesc, Params, Strings, true); + {$ENDIF} + end; + try + // What type of invoke is this? + case CallDesc^.CallType of + CDoMethod: + // procedure with N arguments + if Dest = nil then + begin + if not DoProcedure(Source, LIdent, VarParams) then + begin + + // ok maybe its a function but first we must make room for a result + VarDataInit(LTemp); + try + + // notate that the destination shouldn't be bothered with + // functions can still return stuff, we just do this so they + // can tell that they don't need to if they don't want to + SetClearVarToEmptyParam(LTemp); + + // ok lets try for that function + if not DoFunction(LTemp, Source, LIdent, VarParams) then + RaiseDispError; + finally + VarDataClear(LTemp); + end; + end + end + + // property get or function with 0 argument + else if LArgCount = 0 then + begin + if not GetProperty(Dest^, Source, LIdent) and + not DoFunction(Dest^, Source, LIdent, VarParams) then + RaiseDispError; + end + + // function with N arguments + else if not DoFunction(Dest^, Source, LIdent, VarParams) then + RaiseDispError; + + CPropertyGet: + if not ((Dest <> nil) and // there must be a dest + (LArgCount = 0) and // only no args + GetProperty(Dest^, Source, LIdent)) then // get op be valid + RaiseDispError; + + CPropertySet: + if not ((Dest = nil) and // there can't be a dest + (LArgCount = 1) and // can only be one arg + SetProperty(Source, LIdent, VarParams[0])) then // set op be valid + RaiseDispError; + else + RaiseDispError; + end; + + finally + PatchedFinalizeDispatchInvokeArgs(CallDesc, VarParams, true); + end; + + for I := 0 to Length(Strings) - 1 do + begin + if Pointer(Strings[I].Wide) = nil then + Break; + if Strings[I].Ansi <> nil then + Strings[I].Ansi^ := AnsiString(Strings[I].Wide) + else + if Strings[I].Unicode <> nil then + Strings[I].Unicode^ := UnicodeString(Strings[I].Wide) + end; + end; +{$ENDIF PATCHEDSYSTEMDISPINVOKE} + + procedure GetNamedParams; + var + LNamePtr: PAnsiChar; + LNamedArgStart : Integer; //arg position of 1st named argument (if any) + I : integer; + begin + LNamePtr := PAnsiChar(@CallDesc^.ArgTypes[CallDesc^.ArgCount]); + LNamedArgStart := CallDesc^.ArgCount - CallDesc^.NamedArgCount; + SetLength(fNamedParams, CallDesc^.NamedArgCount); + // Skip function Name + for I := 0 to CallDesc^.NamedArgCount - 1 do begin + LNamePtr := LNamePtr + Succ(Length(LNamePtr)); + fNamedParams[I].Index := I+LNamedArgStart; + fNamedParams[I].Name := AnsiString(LNamePtr); + end; + end; + +Var + NewCallDesc : TCallDesc; +begin + if CallDesc^.NamedArgCount > 0 then GetNamedParams; + try + if (CallDesc^.CallType = CPropertyGet) and (CallDesc^.ArgCount = 1) then begin + NewCallDesc := CallDesc^; + NewCallDesc.CallType := CDoMethod; + {$IFDEF PATCHEDSYSTEMDISPINVOKE} + PatchedDispInvoke(Dest, Source, @NewCallDesc, Params); + {$ELSE PATCHEDSYSTEMDISPINVOKE} + inherited DispInvoke(Dest, Source, @NewCallDesc, Params); + {$ENDIF PATCHEDSYSTEMDISPINVOKE} + end else + {$IFDEF PATCHEDSYSTEMDISPINVOKE} + PatchedDispInvoke(Dest, Source, CallDesc, Params); + {$ELSE PATCHEDSYSTEMDISPINVOKE} + inherited; + {$ENDIF PATCHEDSYSTEMDISPINVOKE} + finally + if CallDesc^.NamedArgCount > 0 then SetLength(fNamedParams, 0); + end; +end; + +function TPythonVariantType.DoFunction(var Dest: TVarData; + const V: TVarData; const AName: string; + const Arguments: TVarDataArray): Boolean; +var + _PyResult : PPyObject; +begin + // eval the function call + _PyResult := EvalPython(V, AnsiString(AName), Arguments); + try + Result := Assigned(_PyResult); + // if the evaluation returned a result + if Result then + // convert it into a variant + PyhonVarDataCreate( Dest, _PyResult ); + finally + GetPythonEngine.Py_XDecRef( _PyResult ); + end; // of try +end; + +function TPythonVariantType.DoProcedure(const V: TVarData; + const AName: string; const Arguments: TVarDataArray): Boolean; +var + _PyResult : PPyObject; +begin + _PyResult := EvalPython(V, AnsiString(AName), Arguments); + Result := Assigned(_PyResult); + GetPythonEngine.Py_XDecRef( _PyResult ); +end; + +function TPythonVariantType.EvalPython(const V: TVarData; + const AName: AnsiString; const Arguments: TVarDataArray): PPyObject; + + function ArgAsPythonObject( AArgIndex : Integer ) : PPyObject; + begin + Result := VarDataToPythonObject(Arguments[AArgIndex]); + // if conversion failed, then too bad ;-) + if not Assigned(Result) then + raise Exception.CreateFmt(SCantConvertArg, [AArgIndex, AName]); + end; // of function + + function GetObjectItem( AObject : PPyObject; const AKey : TVarData ) : PPyObject; + var + _key : PPyObject; + begin + _key := VarDataToPythonObject(AKey); + with GetPythonEngine do + begin + PyErr_Clear; + if not Assigned(_key) then + raise Exception.Create(SCantConvertKeyToPythonObject); + try + Result := PyObject_GetItem( AObject, _key ); + CheckError; + finally + Py_XDecRef(_key); + end; // of try + end; // of with + end; // of function + + function SetObjectItem( AObject : PPyObject; const AKey, AValue : TVarData ) : PPyObject; + var + _key, _value : PPyObject; + _result : Integer; + begin + with GetPythonEngine do + begin + PyErr_Clear; + _key := VarDataToPythonObject(AKey); + if not Assigned(_key) then + raise Exception.Create(SCantConvertKeyToPythonObject); + try + _value := VarDataToPythonObject(AValue); + if not Assigned(_value) then + raise Exception.Create(SCantConvertValueToPythonObject); + if PyList_Check(AObject) then + _result := PyList_SetItem( AObject, + {$IFDEF FPC}PtrInt(Variant(AKey)){$ELSE}Variant(AKey){$ENDIF}, _value ) + else if PyTuple_Check(AObject) then + _result := PyTuple_SetItem( AObject, + {$IFDEF FPC}PtrInt(Variant(AKey)){$ELSE}Variant(AKey){$ENDIF}, _value ) + else + try + if PySequence_Check(AObject) <> 0 then + _result := PySequence_SetItem(AObject, + {$IFDEF FPC}PtrInt(Variant(AKey)){$ELSE}Variant(AKey){$ENDIF}, _value) + else + _result := PyObject_SetItem( AObject, _key, _value ); + finally + Py_XDecRef(_value); + end; // of try + CheckError; + Result := PyLong_FromLong(_result); + finally + Py_XDecRef(_key); + end; // of try + end; // of with + end; // of function + + function DeleteObjectItem( AObject : PPyObject; const AKey : TVarData ) : PPyObject; + var + _key : PPyObject; + begin + _key := VarDataToPythonObject(AKey); + with GetPythonEngine do + begin + PyErr_Clear; + if not Assigned(_key) then + raise Exception.Create(SCantConvertKeyToPythonObject); + try + PyObject_DelItem( AObject, _key ); + CheckError; + Result := ReturnNone; + finally + Py_XDecRef(_key); + end; // of try + end; // of with + end; // of function + + procedure ExtractSliceIndexes(AObject : PPyObject; const AStart, AEnd: TVarData; out ASliceStart, ASliceEnd : Integer ); + begin + with GetPythonEngine do + begin + if VarIsSame(Variant(AStart), Ellipsis) then + ASliceStart := 0 + else + ASliceStart := Variant(AStart); + if VarIsSame(Variant(AEnd), Ellipsis) then + ASliceEnd := PySequence_Length(AObject) + else + ASliceEnd := Variant(AEnd); + CheckError; + end; // of with + end; + + function GetSequenceSlice( AObject : PPyObject; const AStart, AEnd: TVarData ) : PPyObject; + var + _start, _end : Integer; + begin + with GetPythonEngine do + begin + PyErr_Clear; + ExtractSliceIndexes(AObject, AStart, AEnd, _start, _end); + Result := PySequence_GetSlice( AObject, _start, _end); + CheckError; + end; // of with + end; // of function + + function SetSequenceSlice( AObject : PPyObject; const AStart, AEnd, AValue : TVarData ) : PPyObject; + var + _start, _end : Integer; + _value : PPyObject; + _result : Integer; + begin + with GetPythonEngine do + begin + PyErr_Clear; + ExtractSliceIndexes(AObject, AStart, AEnd, _start, _end); + _value := VarDataToPythonObject(AValue); + if not Assigned(_value) then + raise Exception.Create(SCantConvertValueToPythonObject); + try + _result := PySequence_SetSlice( AObject, _start, _end, _value); + CheckError; + Result := PyLong_FromLong(_result); + finally + Py_XDecRef(_value); + end; // of try + end; // of with + end; // of function + + function DelSequenceSlice( AObject : PPyObject; const AStart, AEnd: TVarData ) : PPyObject; + var + _start, _end, _result : Integer; + begin + with GetPythonEngine do + begin + PyErr_Clear; + ExtractSliceIndexes(AObject, AStart, AEnd, _start, _end); + _result := PySequence_DelSlice( AObject, _start, _end); + CheckError; + Result := PyLong_FromLong(_result); + end; // of with + end; // of function + + function SequenceContains( AObject : PPyObject; const AValue : TVarData ) : PPyObject; + var + _value : PPyObject; + _result : Integer; + begin + _value := VarDataToPythonObject(AValue); + with GetPythonEngine do + begin + PyErr_Clear; + if not Assigned(_value) then + raise Exception.Create(SCantConvertValueToPythonObject); + try + _result := PySequence_Contains( AObject, _value ); + CheckError; + Result := PyLong_FromLong(_result); + finally + Py_XDecRef(_value); + end; // of try + end; // of with + end; // of function + +var + i : Integer; + _container : PPyObject; + _obj : PPyObject; + _Arg : PPyObject; + _Args : PPyObject; + _ArgLen : Integer; + _KW : PPyObject; +begin + Result := nil; + with GetPythonEngine do + begin + // extract the associated Python object + _container := TPythonVarData(V).VPython.PyObject; + + // extract the key from the container object + _obj := PyObject_GetAttrString(_container, PAnsiChar(AName)); + try + try + // if the container object does not have the key AName + if PyErr_Occurred <> nil then + begin + // here we handle a special case: COM (or Delphi?) doesn't allow you to have index properties + // on a variant except from a true array variant! So if myVar is a Python variant that holds + // a Python list, I can't write something like: myVar[0]! But if the list is a member of a + // Python instance, it will work fine! Like: myInst.myList[0] + // So, to handle this problem we detect some special names: GetItem, SetItem and Length + // that will do the same as: + // myList[0] <-> myList.GetItem(0) + // myDict['Hello'] := 1 <-> myDict.SetItem('Hello', 1) + // len(myList) <-> myList.Length() + // we get some bonus with the slices and in operators also: + // myList = [0, 1, 2, 3]; myList.GetSlice(1, 2) --> [1, 2] + // myList.Contains(2) <-> 2 in myList + + if (Length(Arguments) = 1) and SameText(string(AName), 'GetItem') then + Result := GetObjectItem(_container, Arguments[0]) + else if (Length(Arguments) = 2) and SameText(string(AName), 'SetItem') then + Result := SetObjectItem(_container, Arguments[0], Arguments[1]) + else if (Length(Arguments) = 1) and SameText(string(AName), 'DeleteItem') then + Result := DeleteObjectItem(_container, Arguments[0]) + else if (Length(Arguments) = 2) and SameText(string(AName), 'GetSlice') then + Result := GetSequenceSlice(_container, Arguments[0], Arguments[1]) + else if (Length(Arguments) = 3) and SameText(string(AName), 'SetSlice') then + Result := SetSequenceSlice(_container, Arguments[0], Arguments[1], Arguments[2]) + else if (Length(Arguments) = 2) and SameText(string(AName), 'DelSlice') then + Result := DelSequenceSlice(_container, Arguments[0], Arguments[1]) + else if (Length(Arguments) = 1) and SameText(string(AName), 'Contains') then + Result := SequenceContains(_container, Arguments[0]) + else if SameText(string(AName), 'Length') then + Result := PyLong_FromLong( GetObjectLength(_container) ); + end; // of if + finally + // if the key did not exist, Python generated an exception that we must propagate through CheckError + CheckError; + end; // of try + // exit now if our special functions could apply + if Assigned(Result) then + Exit; + // if we found the key + if Assigned(_obj) then + // if the associated object is callable (a method or a function) + if PyCallable_Check(_obj) <> 0 then + begin + // Prepare the Python arguments for calling the func or method. + + // there's a special case: if we call a Python method without any argument (like myList.sort()), + // the arguments list contains a single error variant. + if (Length(Arguments) = 1) and VarDataIsEmptyParam(Arguments[0]) then + _ArgLen := 0 + else + _ArgLen := Length(Arguments); + if Length(fNamedParams) > 0 then + begin + _KW := PyDict_New; + _ArgLen := fNamedParams[0].Index; + end + else + _KW := nil; + try + _Args := PyTuple_New(_ArgLen); + try + for i := 0 to _ArgLen-1 do + PyTuple_SetItem( _Args, i, ArgAsPythonObject(i) ); + for i := 0 to Length(fNamedParams)-1 do + PyDict_SetItemString(_KW, PAnsiChar(fNamedParams[i].Name), ArgAsPythonObject(fNamedParams[i].Index)); + + // call the func or method, with or without named parameters (KW) + if Assigned(_KW) then + Result := PyEval_CallObjectWithKeywords(_obj, _Args, _KW) + else + Result := PyEval_CallObjectWithKeywords(_obj, _Args, nil); + CheckError(True); + finally + Py_XDecRef(_Args); + end; // of try + finally + Py_XDecRef(_KW); + end; + end // of if + // if we have one argument and our associated object is not callable + // it could mean that we're trying to access an item of a sequence or + // a mapping, like myInst.MyList(1) + else if Length(Arguments) = 1 then + begin + // if we have a sequence or a mapping object + if (PySequence_Check(_obj) <> 0) or (PyMapping_Check(_obj) <> 0) then + begin + // convert the variant argument into a Python object + _Arg := VarDataToPythonObject(Arguments[0]); + try + // get the item + Result := PyObject_GetItem(_obj, _Arg); + CheckError; + finally + Py_XDecRef(_Arg); + end; // of try + end; // of if + end // of else if + else + raise Exception.Create( SMultiDimensionalPropsNotSupported ); + finally + Py_XDecRef(_obj); + end; // of try + end; // of with +end; + +{$IFNDEF FPC} +function TPythonVariantType.FixupIdent(const AText: string): string; +begin + Result := AText; +end; +{$ENDIF FPC} + +function TPythonVariantType.GetInstance(const V: TVarData): TObject; +begin + Result := TPythonVarData(V).VPython; +end; + +function TPythonVariantType.GetProperty(var Dest: TVarData; + const V: TVarData; const AName: string): Boolean; +var + _prop : PPyObject; + _len : Integer; +begin + with GetPythonEngine do + begin + _prop := PyObject_GetAttrString(TPythonVarData(V).VPython.PyObject, PAnsiChar(AnsiString(AName))); + // if we could not find the property + if (PyErr_Occurred <> nil) or not Assigned(_prop) then + begin + // test a special property name for sequences only + if SameText(AName, 'Length') then + begin + // if it's a sequence or a mapping + if (PySequence_Check(TPythonVarData(V).VPython.PyObject) <> 0) or + (PyMapping_Check(TPythonVarData(V).VPython.PyObject) <> 0) then + begin + // clear the error state of Python + PyErr_Clear; + // get the length + _len := PyObject_Length(TPythonVarData(V).VPython.PyObject); + CheckError; + // convert the length into a Python integer + _prop := PyLong_FromLong( _len ); + end; // of if + end; + end; // of if + CheckError; + Result := Assigned(_prop); + if Result then + try + PyhonVarDataCreate(Dest, _prop); + finally + Py_XDecRef(_prop); + end; // of try + end; // of with +end; + +function TPythonVariantType.IsClear(const V: TVarData): Boolean; +begin + Result := (TPythonVarData(V).VPython = nil) or + TPythonVarData(V).VPython.IsNone; +end; + +function TPythonVariantType.LeftPromotion(const V: TVarData; + const AOperator: TVarOp; out RequiredVarType: TVarType): Boolean; +begin + { TypeX Op Python } + if (AOperator = opAdd) and VarDataIsStr(V) then + RequiredVarType := varUString + else + RequiredVarType := VarType; + + Result := True; +end; + +// this method increases the ref count of AObject +procedure TPythonVariantType.PyhonVarDataCreate(var Dest: TVarData; + AObject: PPyObject); +begin + VarDataClear(Dest); + if Assigned(AObject) then + begin + TPythonVarData(Dest).VType := VarPython; + TPythonVarData(Dest).VPython := TPythonData.Create(AObject); + end; +end; + +function TPythonVariantType.RightPromotion(const V: TVarData; + const AOperator: TVarOp; out RequiredVarType: TVarType): Boolean; +begin + { Python Op TypeX } + // Note that the Int64 doesn't is an exception, because the expr Python op Int64, + // won't cast the Int64 to Python. + // See unit Variants, function VarCastRare. + if V.VType <> varInt64 then + begin + RequiredVarType := VarType; + Result := True; + end + else + Result := False; +end; + +function TPythonVariantType.SetProperty({$IFDEF FPC}var{$ELSE}const{$ENDIF} V: TVarData; + const AName: string; const Value: TVarData): Boolean; +var + _newValue : PPyObject; +begin + with GetPythonEngine do + begin + _newValue := VarDataToPythonObject(Value); + try + PyObject_SetAttrString(TPythonVarData(V).VPython.PyObject, PAnsiChar(AnsiString(AName)), _newValue ); + CheckError; + finally + Py_XDecRef(_newValue); + end; // of try + end; // of with + Result := True; +end; + +procedure TPythonVariantType.UnaryOp(var Right: TVarData; + const AOperator: TVarOp); +begin + if Right.VType = VarType then + case AOperator of + opNegate: + TPythonVarData(Right).VPython.DoNegate; + opNot: + TPythonVarData(Right).VPython.DoNot; + else + RaiseInvalidOp; + end // of case + else + RaiseInvalidOp; +end; + +function TPythonVariantType.VarDataToPythonObject(AVarData: TVarData): PPyObject; +var + _PVarData : PVarData; +begin + Result := nil; + // first detect if we have a Python variant as argument and extract its associated Python object + if AVarData.VType = VarType then + begin + Result := TPythonVarData(AVarData).VPython.PyObject; + GetPythonEngine.Py_XINCREF(Result); + end // of if + else if VarDataIsByRef(AVarData) and + ((AVarData.VType and varTypeMask) = varVariant) then + begin + _PVarData := AVarData.VPointer; + if _PVarData^.VType = VarType then + begin + Result := TPythonVarData(_PVarData^).VPython.PyObject; + GetPythonEngine.Py_XINCREF(Result); + end; // of if + end // of if + else if (AVarData.VType and varTypeMask) = varNull then + Result := GetPythonEngine.ReturnNone + else if (AVarData.VType and varTypeMask) = varEmpty then + Result := GetPythonEngine.ReturnNone; + // else try to convert the variant into a Python object + if not Assigned(Result) then + Result := GetPythonEngine.VariantAsPyObject(Variant(AVarData)); +end; + +//------------------------------------------------------------------------------ +{ TPythonData } + +constructor TPythonData.Create(AObject: PPyObject); +begin + PyObject := AObject; +end; + +destructor TPythonData.Destroy; +begin + if PythonOK then + PyObject := nil; + inherited; +end; + +procedure TPythonData.DoAdd(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Add(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoAnd(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_And(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoDivide(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_TrueDivide(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoIntDivide(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_FloorDivide( PyObject, Right.PyObject ); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoModulus(const Right: TPythonData); +var + _item, _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Divmod(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) and (PySequence_Check(_result) <> 0) and + (PySequence_Length(_result) >= 2) then + begin + _item := PySequence_GetItem(_result, 1); + PyObject := _item; + Py_XDecRef(_item); + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoMultiply(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Multiply(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoNegate; +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Negative(PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoNot; +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Invert(PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoOr(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Or(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoShiftLeft(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_LShift(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoShiftRight(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_RShift(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoSubtract(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Subtract(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +procedure TPythonData.DoXor(const Right: TPythonData); +var + _result : PPyObject; +begin + with GetPythonEngine do + begin + _result := PyNumber_Xor(PyObject, Right.PyObject); + CheckError; + if Assigned(_result) then + begin + PyObject := _result; + Py_XDecRef(_result); + end; // of if + end; // of with +end; + +function TPythonData.Equal(const Right: TPythonData): Boolean; +begin + with GetPythonEngine do + begin + Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_EQ) = 1; + CheckError; + end; // of with +end; + +function TPythonData.GetAsAnsiString: AnsiString; +begin + Result := AnsiString(GetAsString); +end; + +function TPythonData.GetAsString: string; +begin + if Assigned(PyObject) then + Result := GetPythonEngine.PyObjectAsString(PyObject) + else + result := ''; +end; + +function TPythonData.GetAsVariant: Variant; +begin + if Assigned(PyObject) then + Result := GetPythonEngine.PyObjectAsVariant(PyObject) + else + Result := Null; +end; + +function TPythonData.GetAsWideString: UnicodeString; +begin + if Assigned(PyObject) and GetPythonEngine.PyUnicode_Check(PyObject) then + Result := GetPythonEngine.PyUnicodeAsString(PyObject) + else + Result := UnicodeString(GetAsString); +end; + +function TPythonData.GreaterOrEqualThan(const Right: TPythonData): Boolean; +begin + with GetPythonEngine do + Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_GE) = 1 +end; + +function TPythonData.GreaterThan(const Right: TPythonData): Boolean; +begin + with GetPythonEngine do + Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_GT) = 1 +end; + +function TPythonData.IsNone: Boolean; +begin + Result := PyObject = GetPythonEngine.Py_None; +end; + +function TPythonData.LessOrEqualThan(const Right: TPythonData): Boolean; +begin + with GetPythonEngine do + Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_LE) = 1 +end; + +function TPythonData.LessThan(const Right: TPythonData): Boolean; +begin + with GetPythonEngine do + Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_LT) = 1 +end; + +procedure TPythonData.SetPyObject(const Value: PPyObject); +begin + with GetPythonEngine do + begin + Py_XDecRef(fPyObject); + fPyObject := Value; + Py_XIncRef(fPyObject); + end; +end; + +{ TVarPyEnumerator } + +constructor TVarPyEnumerator.Create(const AValue: Variant); +begin + FIterator := iter(AValue); +end; + +function TVarPyEnumerator.GetCurrent: Variant; +begin + Result := FCurrent; +end; + +function TVarPyEnumerator.MoveNext: Boolean; +begin + Result := True; + try + FCurrent := BuiltinModule.next(FIterator); + except + on E: EPyStopIteration do + begin + Result := False; + end + else + raise; + end; +end; + +function VarPyIterate(const AValue: Variant): TVarPyEnumerateHelper; +begin + Result := TVarPyEnumerateHelper.Create(AValue); +end; + +{ TVarPyEnumerateHelper } + +constructor TVarPyEnumerateHelper.Create(const AValue: Variant); +begin + FIterable := AValue; +end; + +function TVarPyEnumerateHelper.GetEnumerator: TVarPyEnumerator; +begin + Result := TVarPyEnumerator.Create(FIterable); +end; + +procedure VarPyToStrings(const AValue : Variant; const AStrings: TStrings); +var + V: Variant; +begin + for V in VarPyIterate(AValue) do + AStrings.Add(V) +end; + +initialization + PythonVariantType := TPythonVariantType.Create; + +finalization + FreeAndNil(PythonVariantType); + +end. diff --git a/python4lazarus/python4lazarus_package.lpk b/python4lazarus/python4lazarus_package.lpk index f714e2e..8e0dd01 100644 --- a/python4lazarus/python4lazarus_package.lpk +++ b/python4lazarus/python4lazarus_package.lpk @@ -25,8 +25,8 @@ </CompilerOptions> <Description Value="Wrapper for Python engine, forked from Python4Delphi."/> <License Value="MIT"/> - <Version Major="1" Minor="2"/> - <Files Count="4"> + <Version Major="1" Minor="4" Release="1"/> + <Files Count="5"> <Item1> <Filename Value="python4lazarus_register.pas"/> <HasRegisterProc Value="True"/> @@ -44,6 +44,10 @@ <Filename Value="MethodCallBack.pas"/> <UnitName Value="MethodCallBack"/> </Item4> + <Item5> + <Filename Value="VarPyth.pas"/> + <UnitName Value="VarPyth"/> + </Item5> </Files> <CompatibilityMode Value="True"/> <RequiredPkgs Count="2"> diff --git a/python4lazarus/python4lazarus_package.pas b/python4lazarus/python4lazarus_package.pas index 1c05eca..c2a7864 100644 --- a/python4lazarus/python4lazarus_package.pas +++ b/python4lazarus/python4lazarus_package.pas @@ -9,7 +9,7 @@ interface uses Python4Lazarus_register, PythonEngine, PythonGUIInputOutput, MethodCallBack, - LazarusPackageIntf; + VarPyth, LazarusPackageIntf; implementation