IDE: unit dependencies: overlays for cycles

git-svn-id: trunk@42884 -
This commit is contained in:
mattias 2013-09-19 18:23:56 +00:00
parent 5719113bb6
commit 999cc9e8e6
5 changed files with 116 additions and 110 deletions

View File

@ -9,7 +9,7 @@ object UnitDependenciesWindow: TUnitDependenciesWindow
OnCreate = FormCreate
OnDestroy = FormDestroy
Position = poScreenCenter
LCLVersion = '1.1'
LCLVersion = '1.3'
object MainPageControl: TPageControl
Left = 0
Height = 407
@ -218,7 +218,6 @@ object UnitDependenciesWindow: TUnitDependenciesWindow
ShowHint = True
ShowRoot = False
TabOrder = 1
OnAdvancedCustomDrawItem = AllUnitsTreeViewAdvancedCustomDrawItem
OnMouseDown = UnitsTreeViewMouseDown
OnSelectionChanged = AllUnitsTreeViewSelectionChanged
OnShowHint = UnitsTreeViewShowHint

View File

@ -68,6 +68,7 @@ type
public
SCCNode: TUDSCCNode;
function GetSCCNode: TUDSCCNode;
function HasImplementationUses: boolean;
destructor Destroy; override;
end;
@ -102,6 +103,9 @@ type
Identifier: string; // GroupName, Directory, Filename
Group: string;
HasChildren: boolean;
IntfCycle: boolean;
ImplCycle: boolean;
HasImplementationUses: boolean;
end;
{ TUDNode }
@ -178,9 +182,6 @@ type
procedure AllUnitsSearchPrevSpeedButtonClick(Sender: TObject);
procedure AllUnitsShowDirsSpeedButtonClick(Sender: TObject);
procedure AllUnitsShowGroupNodesSpeedButtonClick(Sender: TObject);
procedure AllUnitsTreeViewAdvancedCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; {%H-}State: TCustomDrawState; Stage: TCustomDrawStage;
var {%H-}PaintImages, {%H-}DefaultDraw: Boolean);
procedure RefreshButtonClick(Sender: TObject);
procedure SelUnitsTreeViewExpanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
@ -228,6 +229,8 @@ type
fImgIndexPackage: integer;
fImgIndexDirectory: integer;
fImgIndexOverlayImplUses: integer;
fImgIndexOverlayIntfCycle: integer;
fImgIndexOverlayImplCycle: integer;
fAllUnitsTVSearchStartNode: TTreeNode;
fSelUnitsTVSearchStartNode: TTreeNode;
function CreateAllUnitsTree: TUDNode;
@ -388,6 +391,17 @@ begin
Result:=SCCNode;
end;
function TUDUnit.HasImplementationUses: boolean;
var
i: Integer;
begin
Result:=false;
if UsesUnits=nil then exit;
for i:=0 to UsesUnits.Count-1 do
if TUDUses(UsesUnits[i]).InImplementation then
exit(true);
end;
destructor TUDUnit.Destroy;
begin
FreeAndNil(SCCNode);
@ -541,6 +555,8 @@ begin
fImgIndexPackage := IDEImages.LoadImage(16, 'pkg_required');
fImgIndexDirectory := IDEImages.LoadImage(16, 'pkg_files');
fImgIndexOverlayImplUses := IDEImages.LoadImage(16, 'pkg_core_overlay');
fImgIndexOverlayIntfCycle := IDEImages.LoadImage(16, 'ce_cycleinterface');
fImgIndexOverlayImplCycle := IDEImages.LoadImage(16, 'ce_cycleimplementation');
AllUnitsTreeView.Images:=IDEImages.Images_16;
SelUnitsTreeView.Images:=IDEImages.Images_16;
@ -601,40 +617,6 @@ begin
IdleConnected:=true;
end;
procedure TUnitDependenciesWindow.AllUnitsTreeViewAdvancedCustomDrawItem(
Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState;
Stage: TCustomDrawStage; var PaintImages, DefaultDraw: Boolean);
var
TV: TTreeView;
NodeRect: Classes.TRect;
x: Integer;
UDNode: TUDNode;
UGUnit: TUGUnit;
UsesImplCnt: Integer;
i: Integer;
y: Integer;
begin
if Stage<>cdPostPaint then exit;
TV:=Sender as TTreeView;
if not (TObject(Node.Data) is TUDNode) then exit;
UDNode:=TUDNode(Node.Data);
if UDNode.Typ<>udnUnit then exit;
UGUnit:=UsesGraph.GetUnit(UDNode.Identifier,false);
if UGUnit=nil then exit;
if (UGUnit.UsesUnits=nil) then exit;
UsesImplCnt:=0;
for i:=0 to UGUnit.UsesUnits.Count-1 do begin
if TUGUses(UGUnit.UsesUnits[i]).InImplementation then
inc(UsesImplCnt);
end;
if UsesImplCnt=0 then exit;
NodeRect:=Node.DisplayRect(False);
x:=Node.DisplayIconLeft+1;
y:=(NodeRect.Top+NodeRect.Bottom-TV.Images.Height) div 2;
TV.Images.Draw(TV.Canvas,x,y,fImgIndexOverlayImplUses);
end;
procedure TUnitDependenciesWindow.RefreshButtonClick(Sender: TObject);
begin
if udwParsing in FFlags then exit;
@ -709,7 +691,7 @@ procedure TUnitDependenciesWindow.UnitsTreeViewShowHint(Sender: TObject;
ImplCnt:=0;
if List=nil then exit;
for i:=0 to List.Count-1 do
if TUGUses(List[i]).InImplementation then
if TUDUses(List[i]).InImplementation then
inc(ImplCnt)
else
inc(IntfCnt);
@ -1075,12 +1057,12 @@ begin
Filename:=AProject.Files[i].Filename;
CurUnit:=UsesGraph.GetUnit(Filename,false);
if CurUnit=nil then continue;
if not (CurUnit is TUGGroupUnit) then begin
if not (CurUnit is TUDUnit) then begin
debugln(['TUnitDependenciesDialog.CreateProjectGroup WARNING: ',CurUnit.Filename,' ',CurUnit.Classname,' should be TUGGroupUnit']);
continue;
end;
if TUGGroupUnit(CurUnit).Group<>nil then continue;
Result.AddUnit(TUGGroupUnit(CurUnit));
if TUDUnit(CurUnit).Group<>nil then continue;
Result.AddUnit(TUDUnit(CurUnit));
end;
end;
@ -1100,9 +1082,9 @@ begin
for i:=0 to APackage.FileCount-1 do begin
Filename:=APackage.Files[i].GetFullFilename;
CurUnit:=UsesGraph.GetUnit(Filename,false);
if CurUnit is TUGGroupUnit then begin
if TUGGroupUnit(CurUnit).Group<>nil then continue;
Result.AddUnit(TUGGroupUnit(CurUnit));
if CurUnit is TUDUnit then begin
if TUDUnit(CurUnit).Group<>nil then continue;
Result.AddUnit(TUDUnit(CurUnit));
end;
end;
end;
@ -1130,7 +1112,7 @@ procedure TUnitDependenciesWindow.CreateFPCSrcGroups;
var
FPCSrcDir: String;
Node: TAVLTreeNode;
CurUnit: TUGGroupUnit;
CurUnit: TUDUnit;
Directory: String;
Grp: TUGGroup;
BaseDir: String;
@ -1142,9 +1124,9 @@ begin
// if in packages/<name>, put in group GroupPrefixFPCSrc+<name>
Node:=UsesGraph.FilesTree.FindLowest;
while Node<>nil do begin
CurUnit:=TUGGroupUnit(Node.Data);
CurUnit:=TUDUnit(Node.Data);
Node:=UsesGraph.FilesTree.FindSuccessor(Node);
if TUGGroupUnit(CurUnit).Group<>nil then continue;
if TUDUnit(CurUnit).Group<>nil then continue;
if CompareFilenames(FPCSrcDir,LeftStr(CurUnit.Filename,length(FPCSrcDir)))<>0
then
continue;
@ -1160,14 +1142,14 @@ begin
if Grp.BaseDir='' then
Grp.BaseDir:=BaseDir;
//debugln(['TUnitDependenciesDialog.CreateFPCSrcGroups ',Grp.Name]);
Grp.AddUnit(TUGGroupUnit(CurUnit));
Grp.AddUnit(TUDUnit(CurUnit));
end;
end;
procedure TUnitDependenciesWindow.GuessGroupOfUnits;
var
Node: TAVLTreeNode;
CurUnit: TUGGroupUnit;
CurUnit: TUDUnit;
Filename: String;
Owners: TFPList;
i: Integer;
@ -1179,7 +1161,7 @@ begin
LastDirectory:='.';
Node:=UsesGraph.FilesTree.FindLowest;
while Node<>nil do begin
CurUnit:=TUGGroupUnit(Node.Data);
CurUnit:=TUDUnit(Node.Data);
if CurUnit.Group=nil then begin
Filename:=CurUnit.Filename;
//debugln(['TUnitDependenciesDialog.GuessGroupOfUnits no group for ',Filename]);
@ -1206,7 +1188,7 @@ begin
Group:=Groups.GetGroup(GroupNone,true);
//debugln(['TUnitDependenciesDialog.GuessGroupOfUnits ',Group.Name]);
end;
Group.AddUnit(TUGGroupUnit(CurUnit));
Group.AddUnit(TUDUnit(CurUnit));
end;
Node:=UsesGraph.FilesTree.FindSuccessor(Node);
end;
@ -1377,7 +1359,7 @@ var
NodeText: String;
RootNode: TUDNode;
Filter: String;
UGUnit: TUGGroupUnit;
UGUnit: TUDUnit;
AVLNode: TAVLTreeNode;
Group: TUGGroup;
GroupNode: TUDNode;
@ -1393,7 +1375,7 @@ begin
ShowDirectories:=AllUnitsShowDirsSpeedButton.Down;
RootNode:=TUDNode.Create;
for AVLNode in UsesGraph.FilesTree do begin
UGUnit:=TUGGroupUnit(AVLNode.Data);
UGUnit:=TUDUnit(AVLNode.Data);
Filename:=UGUnit.Filename;
NodeText:=ExtractFileName(Filename);
if (Filter<>'') and (Pos(Filter, UTF8LowerCase(NodeText))<1) then
@ -1439,6 +1421,9 @@ begin
Node:=ParentNode.GetNode(udnUnit, NodeText, true);
Node.Identifier:=UGUnit.Filename;
Node.Group:=GroupName;
Node.IntfCycle:=UGUnit.GetSCCNode.InIntfCycle;
Node.ImplCycle:=UGUnit.GetSCCNode.InImplCycle;
Node.HasImplementationUses:=UGUnit.HasImplementationUses;
end;
Result:=RootNode;
end;
@ -1541,16 +1526,18 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
NodeTyp: TUDNodeType);
var
i: Integer;
UGUses: TUGUses;
UGUses: TUDUses;
NodeText: String;
SectionUDNode: TUDNode;
InImplementation: Boolean;
UsedBy: Boolean;
OtherUnit: TUGGroupUnit;
OtherUnit: TUDUnit;
Filename: String;
UDNode: TUDNode;
GroupName: String;
Cnt: Integer;
HasIntfCycle: Boolean;
HasImplCycle: Boolean;
begin
if ParentUDNode=nil then exit;
if UsesList=nil then exit;
@ -1561,9 +1548,13 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
// count the number of uses
Cnt:=0;
HasIntfCycle:=false;
HasImplCycle:=false;
for i:=0 to UsesList.Count-1 do begin
UGUses:=TUGUses(UsesList[i]);
UGUses:=TUDUses(UsesList[i]);
if UGUses.InImplementation<>InImplementation then continue;
HasIntfCycle:=HasIntfCycle or UGUses.GetSCCNode.InIntfCycle;
HasImplCycle:=HasImplCycle or UGUses.GetSCCNode.InImplCycle;
inc(Cnt);
end;
if Cnt=0 then exit;
@ -1579,15 +1570,17 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
else exit;
end;
SectionUDNode:=ParentUDNode.GetNode(NodeTyp,NodeText,true);
SectionUDNode.IntfCycle:=HasIntfCycle;
SectionUDNode.ImplCycle:=HasImplCycle;
// create unit nodes
for i:=0 to UsesList.Count-1 do begin
UGUses:=TUGUses(UsesList[i]);
UGUses:=TUDUses(UsesList[i]);
if UGUses.InImplementation<>InImplementation then continue;
if UsedBy then
OtherUnit:=TUGGroupUnit(UGUses.Owner)
OtherUnit:=TUDUnit(UGUses.Owner)
else
OtherUnit:=TUGGroupUnit(UGUses.UsesUnit);
OtherUnit:=TUDUnit(UGUses.UsesUnit);
Filename:=OtherUnit.Filename;
NodeText:=ExtractFileName(Filename);
UDNode:=SectionUDNode.GetNode(udnUnit,NodeText,true);
@ -1600,16 +1593,18 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
UDNode.HasChildren:=
((OtherUnit.UsedByUnits<>nil) and (OtherUnit.UsedByUnits.Count>0))
or ((OtherUnit.UsesUnits<>nil) and (OtherUnit.UsesUnits.Count>0));
UDNode.IntfCycle:=UGUses.GetSCCNode.InIntfCycle;
UDNode.ImplCycle:=UGUses.GetSCCNode.InImplCycle;
end;
end;
var
Filename: String;
UGUnit: TUGGroupUnit;
UGUnit: TUDUnit;
begin
// add connected units
Filename:=UDNode.Identifier;
UGUnit:=TUGGroupUnit(UsesGraph.GetUnit(Filename,false));
UGUnit:=TUDUnit(UsesGraph.GetUnit(Filename,false));
if UGUnit<>nil then begin
AddUses(UDNode,UGUnit.UsesUnits,udnInterface);
AddUses(UDNode,UGUnit.UsesUnits,udnImplementation);
@ -1855,8 +1850,8 @@ var
GroupObj: TObject;
GraphGroup: TLvlGraphNode;
UnitNode: TAVLTreeNode;
GrpUnit: TUGGroupUnit;
UsedUnit: TUGGroupUnit;
GrpUnit: TUDUnit;
UsedUnit: TUDUnit;
begin
Exclude(FFlags,udwNeedUpdateGroupsLvlGraph);
GroupsLvlGraph.BeginUpdate;
@ -1896,11 +1891,11 @@ begin
// add FPC source dependencies
UnitNode:=Group.Units.FindLowest;
while UnitNode<>nil do begin
GrpUnit:=TUGGroupUnit(UnitNode.Data);
GrpUnit:=TUDUnit(UnitNode.Data);
UnitNode:=Group.Units.FindSuccessor(UnitNode);
if GrpUnit.UsesUnits=nil then continue;
for i:=0 to GrpUnit.UsesUnits.Count-1 do begin
UsedUnit:=TUGGroupUnit(TUGUses(GrpUnit.UsesUnits[i]).UsesUnit);
UsedUnit:=TUDUnit(TUDUses(GrpUnit.UsesUnits[i]).UsesUnit);
if (UsedUnit.Group=nil) or (UsedUnit.Group=Group) then continue;
Graph.GetEdge(GraphGroup,Graph.GetNode(UsedUnit.Group.Name,true),true);
end;
@ -1922,15 +1917,15 @@ var
NewUnits: TFilenameToPointerTree;
UnitGroup: TUGGroup;
AVLNode: TAVLTreeNode;
GroupUnit: TUGGroupUnit;
GroupUnit: TUDUnit;
i: Integer;
HasChanged: Boolean;
Graph: TLvlGraph;
CurUses: TUGUses;
CurUses: TUDUses;
SourceGraphNode: TLvlGraphNode;
TargetGraphNode: TLvlGraphNode;
NewGroups: TStringToPointerTree;
UsedUnit: TUGGroupUnit;
UsedUnit: TUDUnit;
begin
Exclude(FFlags,udwNeedUpdateUnitsLvlGraph);
NewGroups:=TStringToPointerTree.Create(false);
@ -1944,7 +1939,7 @@ begin
NewGroups[UnitGroup.Name]:=UnitGroup;
AVLNode:=UnitGroup.Units.FindLowest;
while AVLNode<>nil do begin
GroupUnit:=TUGGroupUnit(AVLNode.Data);
GroupUnit:=TUDUnit(AVLNode.Data);
NewUnits[GroupUnit.Filename]:=GroupUnit;
AVLNode:=UnitGroup.Units.FindSuccessor(AVLNode);
end;
@ -1958,7 +1953,7 @@ begin
i:=0;
AVLNode:=NewUnits.Tree.FindLowest;
while AVLNode<>nil do begin
GroupUnit:=TUGGroupUnit(NewUnits.GetNodeData(AVLNode)^.Value);
GroupUnit:=TUDUnit(NewUnits.GetNodeData(AVLNode)^.Value);
if (Graph.NodeCount<=i) or (Graph.Nodes[i].Data<>Pointer(GroupUnit)) then
begin
HasChanged:=true;
@ -1975,13 +1970,13 @@ begin
Graph.Clear;
AVLNode:=NewUnits.Tree.FindLowest;
while AVLNode<>nil do begin
GroupUnit:=TUGGroupUnit(NewUnits.GetNodeData(AVLNode)^.Value);
GroupUnit:=TUDUnit(NewUnits.GetNodeData(AVLNode)^.Value);
SourceGraphNode:=Graph.GetNode(UnitToCaption(GroupUnit),true);
SourceGraphNode.Data:=GroupUnit;
if GroupUnit.UsesUnits<>nil then begin
for i:=0 to GroupUnit.UsesUnits.Count-1 do begin
CurUses:=TUGUses(GroupUnit.UsesUnits[i]);
UsedUnit:=TUGGroupUnit(CurUses.UsesUnit);
CurUses:=TUDUses(GroupUnit.UsesUnits[i]);
UsedUnit:=TUDUnit(CurUses.UsesUnit);
if UsedUnit.Group=nil then continue;
if not NewGroups.Contains(UsedUnit.Group.Name) then continue;
TargetGraphNode:=Graph.GetNode(UnitToCaption(UsedUnit),true);
@ -2016,6 +2011,14 @@ begin
TVNode.ImageIndex:=GetImgIndex(UDNode);
TVNode.SelectedIndex:=TVNode.ImageIndex;
TVNode.HasChildren:=UDNode.HasChildren;
if UDNode.IntfCycle then
TVNode.OverlayIndex:=fImgIndexOverlayIntfCycle
else if UDNode.ImplCycle then
TVNode.OverlayIndex:=fImgIndexOverlayImplCycle
else if UDNode.HasImplementationUses then
TVNode.OverlayIndex:=fImgIndexOverlayImplUses;
//if TVNode.OverlayIndex>=0 then
// debugln(['TUnitDependenciesWindow.CreateTVNodes ',TVNode.Text,' Overlay=',TVNode.OverlayIndex,' ',TV.Images.Count]);
CreateTVNodes(TV,TVNode,UDNode,Expand);
TVNode.Expanded:=Expand and (TVNode.Count>0);
AVLNode:=ParentUDNode.ChildNodes.FindSuccessor(AVLNode);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 403 B

View File

@ -9362,43 +9362,47 @@ LazarusResources.Add('ce_variable','PNG',[
+#218#0#0#0#0'IEND'#174'B`'#130
]);
LazarusResources.Add('ce_cycleinterface','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#12#0#0#0#12#8#2#0#0#0#217#23#203
+#176#0#0#0#6'tRNS'#0#0#0#0#0#0'n'#166#7#145#0#0#0#9'pHYs'#0#0#15'a'#0#0#15'a'
+#1#168'?'#167'i'#0#0#0#249'IDATx'#218#141#144'?O'#194#0#16#197#127#252'[j'#24
+'@pA\'#4#26'%'#198#164#196#133#129#15'@'#2'qq1q'#128#205#207#0#11'+CG'#190
+#130#3#155'2'#146#16'w:'#18'V'#195'$'#132't'#209#210'BI'#207#193#208'4'#136#9
+'7'#221#189'{'#247'^'#238#193#17#21#9#14'%'#168#195'-'#184#176#8#224'!'#191
+'3@KT'#201#221#224'n'#153#140#223#220#247#250#158#146#1'Z'#177#131'z'#205#183
+#133#235#145#189'Rm'#245#194#25#191#250#26'w '#233'G'#185#127#145'|s'#132'2 '
+'&'#153#170#228'ZB'#254#220''''#245'9'#145'pI'#162#197#143#157'{'#159#144#164
+#154#18#175#149#1#136#2#15'Xx'#6#30#237#221#153#133#176#178#144#181#189#247
+#167#14#194#169#6'C'#16#165'"'#225#167'O'#146')_'#9#232#193's'#164#204#153'f'
+#216'361'#182'q'#152#234#152#203' i'#243'kb'#127#225'88'#230#156#145#142#217
+#253#27'k'#11#4'*p'#9#201#255#178'W'#160#1#133'C'#171#31'm'#151'P '#212#169
+#164#214#0#0#0#0'IEND'#174'B`'#130
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#21#0#0#0#16#8#6#0#0#0#249#218'4%'#0
+#0#0#6'bKGD'#0#255#0#255#0#255#160#189#167#147#0#0#0#9'pHYs'#0#0#15'a'#0#0#15
+'a'#1#168'?'#167'i'#0#0#0#7'tIME'#7#221#9#19#17'6'#3' 96'#217#0#0#1' IDAT8'
+#203#237#146#175'K'#3'q'#24#135#159#155'[9'#153#226#156#6#181#185'Y'#134#229
+#166'ea'#127#192'@'#177'X'#4#131'3'#249'7'#204'b5\'#20#147#213'`'#212'('#12
+#171'xMY1'#136'A'#28#140'3'#200'y'#231#221#216#199'"'#243#7'+'#223'1'#155'O|'
+'y'#223#135#247#229#243#194#31'`'#253'.'#148'A+@'#2'\'#3#183#3'z'#140#164#30
+#200#153#170'Aa'#25#146'.'#220#221'p'#158'\'#177'n('#182'~'#8'K'#7'07'#1#157
+'6'#196#9#216#147'p'#255#196#201#203'1'#187#166#27#175#130'4'#179'%m'#156'J'
+#197#186#154#216#186' #'#205#215#164'BC'#162#168#5#144#145#244#140'q)U'#150
+#210'%=`'#233#171'nI'#249#186#148']S'#197'@'#154#6#216'$'#176#232'y'#208#131
+#253'o'#195#1#130#183#0#244'N8'#236'+'#184' 1-'#7't'#9#146']'#149'R'#219'z&'
+#167#188#233#166#0'G'#160#189#177#10#204':x'#225'#'#196#25#232'f'#129#22'.>'
+#29#131#160#250#210#248#243'`'#194'W'#136'"'#136'|'#218'4q'#241'9'#28#226'W'
+#251'4@'#2'UA'#139#160#156'i'#226#131#176'A;'#160#165'Q'#200#254#25')'#31'`#'
+'wi'#169#23'8'#152#0#0#0#0'IEND'#174'B`'#130
]);
LazarusResources.Add('ce_cycleimplementation','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#12#0#0#0#12#8#6#0#0#0'Vu\'#231#0#0
+#0#9'pHYs'#0#0#11#19#0#0#11#19#1#0#154#156#24#0#0#0#7'tIME'#7#221#9#15#15#26
+#20#150#172#190#237#0#0#1#177'IDAT('#207#149#146'?h'#19'a'#0#197#127#247'}'
+#151#139'I'#233#162'CD*URR'#132#182#161'EZ'#11#130#161#10#1'M'#160#187#136'T'
+''']'#28#20#20'BAp'#209'E'#231' X'#187#138'[T('#136'E4'#189'D'#169'1'#127#170
+'P'#10#157';'#152#164'&6'#189#203'}'#247'9'#180')tp'#240#205#239#7#143#247#30
+#252#167#12#128'J2'#201#216#210#18#0#139#207#195#233'_u='#222#233'h'#128'R'
+#230#225'n'#14#224#237#200#8'Wj'#181'='#0'`{kL'#188'z'#189#241'a8&'#166#143
+#29#21#150#167'4'#155#155#190#187'R'#240#236#248#168#156#185'zc'#199#7#144'='
+' z'#186#181'<'#20#21#23#6'O'#10#217'q4]'#23'"'#17'!'#209#156#202#23'T'#226
+#235#170'zy'#0',d'#195#233#248#168#188'{fX'#202#234#154'O'#222'V'#229#218#15
+#181'%$'#199'cC'#146'v['#159#136'DD'#185'\Q'#235'&'#128#239'sn'#245#187#178
+#222'/{4'#154'~'#169#213'"'#181#253'['#203'FS'#231'B'#161'@<'#26#21#214'g'
+#219#27#7'r'#230#183#169')&n'#21'3@'#6#224#222#157#224#139'p'#136'@'#189#174
+#165#227#128#242'4'#237'?'#176'_'#2'b'#162'X'#228#233#147#144#1'0'#255#224'H'
+#22#152'['#223#240'o'#247#247#27#249#201#179'f'#220#16#176#246'S'#185#134'0J'
+#7#181#238#155'?'#245#245#25#231#167'''%'#141#166#198'S'#16#12'B'#165#170#176
+#191#168#143'o'#222'u'#19#0'f'#15'p'#187#26#211#129']'#7'v:'#224'8'#154'R'
+#217'w'#171'5e'#175#20#188#153'C'#235'=~'#180#23#233#230'u+;w'#205#210#201'K'
+#230#179#139#9's>u9'#144#234'y'#238#15#12#28#158'|!'#22#3'`6'#29'X'#156'M'#7
+#6#255'u'#141#191'O'#19#174#10'H'#217#228'^'#0#0#0#0'IEND'#174'B`'#130
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a'
+#0#0#0#6'bKGD'#0#255#0#255#0#255#160#189#167#147#0#0#0#9'pHYs'#0#0#11#19#0#0
+#11#19#1#0#154#156#24#0#0#0#7'tIME'#7#221#9#19#17'5'#31#31#21'9U'#0#0#1#191
+'IDAT8'#203#237#146'=hSQ'#24#134#159'{'#206#189#137'I'#233#162'CD*URR'#132
+#182#161'EZ'#11#130#161#10#1'M'#160#187#136'T'']'#28#20','#132#130#224#162
+#139#206'A'#176'v'#21#183#168'P'#16#139'h'#154'D'#169'1?U('#133#206#29'LR'#19
+#155#222#228#158'{'#28'l'#22#155#22#193#213'wz'#135#239'{'#248'~^'#248'G'#25
+#0#197'h'#148#145#197'E'#0#22#158#248#227#223'+z'#180#217#212#0#249#196#189
+#157#20#192#171#161'!.'#149#203#221#1#0'['#155'#'#226#249#139#245#183#131'!1'
+'y'#228#176#240'8J'#179#177#225#182#150#179'N&<,'#167'._'#219'v'#187'M ;&x'
+#178#190'4'#16#20#231#250#143#11#217#180'5'#237#22#4#2'B'#162'9'#145#206#170
+#200#167#21#245'l_'#192'|'#210#31#15#15#203#219#167#6#165','#173#186#164'3'
+#170'P'#254#170'6'#133#228'hh@'#210'h'#232'c'#129#128'('#20#138'j'#237'O'#128
+#9#224#186#156'Y'#249#162'<o'#150#28#170'57_'#175#19#219#250#161'e'#181#166
+'S>'#159#21#14#6#133#231'C'#198#25#5'R{'#0#159'''&'#24#187#145'K'#0#9#128';'
+#183#188'O'#253'>'#172'JEK'#219#6#229'h'#26'?a'#247#168'{$'#198'r9'#30'='#244
+#25#0's'#179#135#146#192#204#218#186'{'#179#183#215'H'#143#159'6'#195#134#128
+#213'o'#170'e'#8'#'#191#239#27'w'#155#223#247#244#24'g'''#199'%'#213#154#198
+'Q'#224#245'B'#177#164#200'|T'#239'^'#190'nG'#186#1#204#142'i'#181'5'#166#13
+';6l7'#193#182'5'#249#130#219'*'#149'Uf9'#235'L'#29#152#166#7#247#127#175'p'
+#253#170'''9s'#197#163#163#23#204#199#231'#'#230'\'#236#162#21#235#212#220
+#237#235';8'#146#243#161#16#0#211'qka:n'#245#243'_'#127#173'_'#161'2'#174#10
+#11#198'x'#150#0#0#0#0'IEND'#174'B`'#130
]);
LazarusResources.Add('show_source','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a'