diff --git a/.gitignore b/.gitignore index abc738f51..8b755f7fa 100644 --- a/.gitignore +++ b/.gitignore @@ -73,4 +73,5 @@ exec/Resources /dependencies/Indy10-mod-static /dependencies/indy-master /release-notes.md -/install/build \ No newline at end of file +/install/build +/release-notes-old.md diff --git a/build/linux-toolchain.sh b/build/linux-toolchain.sh index 2d4a51f27..3a9e6703d 100755 --- a/build/linux-toolchain.sh +++ b/build/linux-toolchain.sh @@ -14,7 +14,7 @@ echo "Get fpclazup" mkdir tools -wget -q https://github.com/LongDirtyAnimAlf/Reiniero-fpcup/releases/download/v2.2.0b/fpclazup-x86_64-linux -O tools/fpclazup +wget -q https://github.com/LongDirtyAnimAlf/Reiniero-fpcup/releases/download/v2.2.0g/fpclazup-x86_64-linux -O tools/fpclazup chmod +x tools/fpclazup diff --git a/library/ftx/fhir_valuesets.pas b/library/ftx/fhir_valuesets.pas index 9307ed375..953d5cd92 100644 --- a/library/ftx/fhir_valuesets.pas +++ b/library/ftx/fhir_valuesets.pas @@ -169,7 +169,7 @@ TValueSetWorker = class (TFslObject) function sizeInBytesV(magic : integer) : cardinal; override; procedure listDisplays(displays : TCodeDisplays; cs : TCodeSystemProvider; c: TCodeSystemProviderContext); overload; procedure listDisplays(displays : TCodeDisplays; c: TFhirCodeSystemConceptW); overload; - procedure listDisplays(displays: TCodeDisplays; c: TFhirValueSetComposeIncludeConceptW); overload; + procedure listDisplays(displays: TCodeDisplays; c: TFhirValueSetComposeIncludeConceptW; vs : TFHIRValueSetW); overload; public constructor Create(factory : TFHIRFactory; getVS: TGetValueSetEvent; getCS : TGetProviderEvent; getVersions : TGetSystemVersionsEvent; txResources : TFslMetadataResourceList; languages : TIETFLanguageDefinitions); overload; destructor Destroy; override; @@ -185,7 +185,7 @@ TValueSetChecker = class (TValueSetWorker) function determineSystem(code : String) : String; function check(system, version, code : String; abstractOk, implySystem : boolean; displays : TCodeDisplays; var message, ver : String; var cause : TFhirIssueType; op : TFhirOperationOutcomeW; var contentMode : TFhirCodeSystemContentMode) : boolean; overload; function findCode(cs : TFhirCodeSystemW; code: String; list : TFhirCodeSystemConceptListW; displays : TCodeDisplays; out isabstract : boolean): boolean; - function checkConceptSet(cs: TCodeSystemProvider; cset : TFhirValueSetComposeIncludeW; code : String; abstractOk : boolean; displays : TCodeDisplays; var message : String) : boolean; + function checkConceptSet(cs: TCodeSystemProvider; cset : TFhirValueSetComposeIncludeW; code : String; abstractOk : boolean; displays : TCodeDisplays; vs : TFHIRValueSetW; var message : String) : boolean; procedure prepareConceptSet(desc: string; cc: TFhirValueSetComposeIncludeW); function getName: String; protected @@ -220,7 +220,7 @@ TFHIRValueSetExpander = class (TValueSetWorker) procedure handleDefine(cs : TFhirCodeSystemW; list : TFslList; map : TFslMap; limitCount : integer; source : TFhirValueSetCodeSystemW; defines : TFhirCodeSystemConceptListW; filter : TSearchFilterText; expansion : TFhirValueSetExpansionW; imports : TFslList); procedure importValueSet(list : TFslList; map : TFslMap; vs : TFHIRValueSetW; expansion : TFhirValueSetExpansionW; imports : TFslList; offset : integer); procedure excludeValueSet(list: TFslList; map: TFslMap; vs : TFHIRValueSetW; expansion : TFhirValueSetExpansionW; imports : TFslList; offset : integer); - procedure processCodes(doDelete : boolean; list : TFslList; map : TFslMap; limitCount : integer; cset : TFhirValueSetComposeIncludeW; filter : TSearchFilterText; dependencies : TStringList; expansion : TFhirValueSetExpansionW; var notClosed : boolean); + procedure processCodes(doDelete : boolean; list : TFslList; map : TFslMap; limitCount : integer; cset : TFhirValueSetComposeIncludeW; vsSrc : TFHIRValueSetW; filter : TSearchFilterText; dependencies : TStringList; expansion : TFhirValueSetExpansionW; var notClosed : boolean); procedure handleCompose(list : TFslList; map : TFslMap; limitCount : integer; source : TFhirValueSetW; filter : TSearchFilterText; dependencies : TStringList; expansion : TFhirValueSetExpansionW; var notClosed : boolean); function passesImports(imports : TFslList; system, code : String; offset : integer) : boolean; @@ -769,7 +769,7 @@ function TValueSetChecker.check(system, version, code : String; abstractOk, impl raise ETerminologyError.create('Value Set Validation depends on supplement '+s+' on '+cs.systemUri(nil)+' that is not known'); end; - result := ((system = SYSTEM_NOT_APPLICABLE) or (cs.systemUri(nil) = system)) and checkConceptSet(cs, cc, code, abstractOk, displays, message); + result := ((system = SYSTEM_NOT_APPLICABLE) or (cs.systemUri(nil) = system)) and checkConceptSet(cs, cc, code, abstractOk, displays, FValueSet, message); end else result := false; @@ -799,7 +799,7 @@ function TValueSetChecker.check(system, version, code : String; abstractOk, impl if not cs.hasSupplement(s) then raise ETerminologyError.create('Value Set Validation depends on supplement '+s+' on '+cs.systemUri(nil)+' that is not known'); end; - excluded := ((system = SYSTEM_NOT_APPLICABLE) or (cs.systemUri(nil) = system)) and checkConceptSet(cs, cc, code, abstractOk, displays, message); + excluded := ((system = SYSTEM_NOT_APPLICABLE) or (cs.systemUri(nil) = system)) and checkConceptSet(cs, cc, code, abstractOk, displays, FValueSet, message); end; for s in cc.valueSets do begin @@ -1082,7 +1082,7 @@ function TValueSetChecker.check(system, version, code: String; implySystem : boo cs.Close(ctxt); end; -function TValueSetChecker.checkConceptSet(cs: TCodeSystemProvider; cset : TFhirValueSetComposeIncludeW; code: String; abstractOk : boolean; displays : TCodeDisplays; var message : String): boolean; +function TValueSetChecker.checkConceptSet(cs: TCodeSystemProvider; cset : TFhirValueSetComposeIncludeW; code: String; abstractOk : boolean; displays : TCodeDisplays; vs : TFHIRValueSetW; var message : String): boolean; var i : integer; fc : TFhirValueSetComposeIncludeFilterW; @@ -1117,7 +1117,7 @@ function TValueSetChecker.checkConceptSet(cs: TCodeSystemProvider; cset : TFhirV if Loc <> nil then begin listDisplays(displays, cs, loc); - listDisplays(displays, cc); + listDisplays(displays, cc, vs); result := (abstractOk or not cs.IsAbstract(loc)); cs.close(loc); exit; @@ -1463,9 +1463,9 @@ procedure TFHIRValueSetExpander.handleCompose(list: TFslList; map : TFslMap; limitCount : integer; source : TFhirValueSetCodeSystemW; defines : TFhirCodeSystemConceptListW; filter : TSearchFilterText; expansion : TFhirValueSetExpansionW; imports : TFslList); @@ -1506,11 +1506,16 @@ procedure TValueSetWorker.listDisplays(displays : TCodeDisplays; c: TFhirCodeSys displays.see(ccd.language, ccd.value); end; -procedure TValueSetWorker.listDisplays(displays : TCodeDisplays; c: TFhirValueSetComposeIncludeConceptW); +procedure TValueSetWorker.listDisplays(displays : TCodeDisplays; c: TFhirValueSetComposeIncludeConceptW; vs : TFHIRValueSetW); var cd : TFhirValueSetComposeIncludeConceptDesignationW; first : boolean; begin + if c.display <> '' then + begin + displays.Clear; + displays.see(vs.language, c.display, true); + end; first := true; for cd in c.designations.forEnum do begin @@ -1813,7 +1818,7 @@ procedure TFHIRValueSetExpander.checkSource(cset: TFhirValueSetComposeIncludeW; end; end; -procedure TFHIRValueSetExpander.processCodes(doDelete : boolean; list: TFslList; map: TFslMap; limitCount : integer; cset: TFhirValueSetComposeIncludeW; filter : TSearchFilterText; dependencies : TStringList; expansion : TFhirValueSetExpansionW; var notClosed : boolean); +procedure TFHIRValueSetExpander.processCodes(doDelete : boolean; list: TFslList; map: TFslMap; limitCount : integer; cset: TFhirValueSetComposeIncludeW; vsSrc : TFHIRValueSetW; filter : TSearchFilterText; dependencies : TStringList; expansion : TFhirValueSetExpansionW; var notClosed : boolean); var cs : TCodeSystemProvider; i, count, offset : integer; @@ -1986,7 +1991,7 @@ procedure TFHIRValueSetExpander.processCodes(doDelete : boolean; list: TFslList< if (cctxt <> nil) and (not FParams.activeOnly or not cs.IsInactive(cctxt)) and passesFilters(cctxt, 0) then begin listDisplays(cds, cs, cctxt); - listDisplays(cds, cc); + listDisplays(cds, cc, vsSrc); if filter.passes(cds) or filter.passes(cc.code) then processCode(doDelete, limitCount, list, map, cs.systemUri(nil), cs.version(nil), cc.code, cds, cs.Definition(cctxt), expansion, valueSets); end; diff --git a/library/fui/fui_lcl_managers.pas b/library/fui/fui_lcl_managers.pas index cde479bb6..f7a961c09 100644 --- a/library/fui/fui_lcl_managers.pas +++ b/library/fui/fui_lcl_managers.pas @@ -61,12 +61,31 @@ TControlOperation = (copNone, copAdd, copAddSet, copEdit, copDelete, copUp, copDown, copReload, copExecute, copRefresh, copStop, copCopy, copUpdate); + { TControlEntryMenuItem } + + TControlEntryMenuItem = class (TFslObject) + private + FMenuItem: TMenuItem; + FMode: String; + FOp: TControlOperation; + public + function link : TControlEntryMenuItem; overload; + + property menuItem : TMenuItem read FMenuItem write FMenuItem; + property op : TControlOperation read FOp write FOp; + property mode : String read FMode write FMode; + end; + TControlEntry = class (TFslObject) private FControl: TControl; FMode: String; FOp: TControlOperation; + FMenuItems : TFslList; + FMenu : TPopupMenu; public + destructor Destroy; override; + function link : TControlEntry; overload; @@ -93,6 +112,7 @@ TListOrTreeManagerBase = class abstract (TFslObject) procedure doControl(sender : TObject); virtual; abstract; procedure doMnuClick(Sender: TObject); virtual; abstract; procedure updateControls(op : TControlOperation; allowed : boolean); + procedure updateMenuControls; procedure SetImages(AValue: TImagelist); virtual; public constructor Create; override; @@ -106,7 +126,9 @@ TListOrTreeManagerBase = class abstract (TFslObject) procedure getCopyModes(modes : TStringList); virtual; procedure registerControl(c : TControl; op : TControlOperation; mode : String = ''); - function registerMenuEntry(caption : String; imageIndex : integer; op : TControlOperation; mode : String = '') : TMenuItem; + function registerControlForMenu(c : TControl; menu : TPopupMenu) : TControlEntry; + function registerMenuEntry(caption : String; imageIndex : integer; op : TControlOperation; mode : String = '') : TMenuItem; overload; + function registerMenuEntry(grp : TControlEntry; caption : String; imageIndex : integer; op : TControlOperation; mode : String = '') : TMenuItem; overload; function registerSubMenuEntry(parent : TMenuItem; caption : String; imageIndex : integer; op : TControlOperation; mode : String = '') : TMenuItem; end; @@ -555,6 +577,13 @@ TPanelStack = class (TFslObject) Implementation +{ TControlEntryMenuItem } + +function TControlEntryMenuItem.link: TControlEntryMenuItem; +begin + result := TControlEntryMenuItem(inherited link); +end; + { TPanelStackSubPanel } constructor TPanelStackSubPanel.create(container, heading: TPanel); @@ -679,6 +708,12 @@ procedure TObjectManager.registerControl(propName: String; control: TCheckBox); { TControlEntry } +destructor TControlEntry.Destroy; +begin + FMenuItems.Free; + inherited Destroy; +end; + function TControlEntry.link: TControlEntry; begin result := TControlEntry(inherited link); @@ -727,6 +762,20 @@ procedure TListOrTreeManagerBase.registerControl(c : TControl; op : TControlOper end; end; +function TListOrTreeManagerBase.registerControlForMenu(c: TControl; menu : TPopupMenu): TControlEntry; +begin + result := TControlEntry.create; + try + result.control := c; + result.op := copNone; + result.FMenu := menu; + c.enabled := false; + FControls.add(result.link); + finally + result.free; + end; +end; + function TListOrTreeManagerBase.registerMenuEntry(caption: String; imageIndex: integer; op: TControlOperation; mode : String = '') : TMenuItem; var list : TStringList; @@ -758,6 +807,22 @@ function TListOrTreeManagerBase.registerMenuEntry(caption: String; imageIndex: i end; end; +function TListOrTreeManagerBase.registerMenuEntry(grp: TControlEntry; caption: String; imageIndex: integer; op: TControlOperation; mode: String): TMenuItem; +var + list : TStringList; + i : integer; +begin + result := TMenuItem.create(nil); + grp.FMenu.Items.add(result); + result.caption := caption; + result.imageIndex := imageIndex; + result.Tag := Integer(op); + if mode <> '' then + result.name := 'mnuMode'+mode; + if op <> copNone then + result.OnClick := doMnuClick; +end; + function TListOrTreeManagerBase.registerSubMenuEntry(parent: TMenuItem; caption: String; imageIndex: integer; op: TControlOperation; mode: String): TMenuItem; begin result := TMenuItem.create(nil); @@ -783,13 +848,38 @@ procedure TListOrTreeManagerBase.updateControls(op: TControlOperation; allowed: i : integer; begin for entry in FControls do + begin if entry.op = op then entry.control.enabled := allowed; + if (entry.FMenu <> nil) then + for i := 0 to entry.FMenu.Items.Count - 1 do + if (TControlOperation(entry.FMenu.Items[i].tag) = op) then + entry.FMenu.Items[i].enabled := allowed; + end; for i := 0 to FPopup.Items.Count - 1 do if (TControlOperation(FPopup.Items[i].tag) = op) then FPopup.Items[i].enabled := allowed; end; +procedure TListOrTreeManagerBase.updateMenuControls; +var + entry : TControlEntry; + i : integer; + ok : boolean; +begin + for entry in FControls do + begin + if (entry.FMenu <> nil) then + begin + ok := false; + for i := 0 to entry.FMenu.Items.Count - 1 do + if entry.FMenu.Items[i].Enabled then + ok := true; + entry.control.Enabled := ok; + end; + end; +end; + { TListManager } constructor TListManager.Create; @@ -973,6 +1063,7 @@ procedure TListManager.updateStatus; updateControls(copUpdate, opUpdate in ops); updateControls(copStop, opStop in ops); updateControls(copCopy, FHasCopy); + updateMenuControls(); FCanEdit := opEdit in ops; focusItemChange(focus); @@ -2011,6 +2102,7 @@ procedure TTreeManager.updateStatus; updateControls(copUpdate, opUpdate in ops); updateControls(copStop, opStop in ops); updateControls(copCopy, FHasCopy); + updateMenuControls; FCanEdit := opEdit in ops; focusItemChange(focus); @@ -2536,6 +2628,7 @@ procedure TVTreeManager.updateStatus; updateControls(copUpdate, opUpdate in ops); updateControls(copStop, opStop in ops); updateControls(copCopy, FHasCopy); + updateMenuControls; FCanEdit := opEdit in ops; focusItemChange(focus); diff --git a/server/client_cache_manager.pas b/server/client_cache_manager.pas index 6df2852b4..cd4912882 100644 --- a/server/client_cache_manager.pas +++ b/server/client_cache_manager.pas @@ -118,8 +118,11 @@ procedure TClientCacheManagerEntry.update(list: TFslMetadataResourceList); FList.RemoveAll(remove); for i in list do begin - FSize := FSize + i.sizeInBytes(magic); - FList.Add(i.link); + if (i.url <> '') then + begin + FSize := FSize + i.sizeInBytes(magic); + FList.Add(i.link); + end; end; finally remove.Free; diff --git a/server/fhirserver.res b/server/fhirserver.res index 149fd8baf..caa5ca96d 100644 Binary files a/server/fhirserver.res and b/server/fhirserver.res differ diff --git a/toolkit2/fhirtoolkit.lpi b/toolkit2/fhirtoolkit.lpi index 83716ed14..09c60b2c5 100644 --- a/toolkit2/fhirtoolkit.lpi +++ b/toolkit2/fhirtoolkit.lpi @@ -1,3 +1,4 @@ + @@ -16,9 +17,7 @@ - - diff --git a/toolkit2/frames/ftk_frame_igpub.lfm b/toolkit2/frames/ftk_frame_igpub.lfm index 36316b066..643b65b3c 100644 --- a/toolkit2/frames/ftk_frame_igpub.lfm +++ b/toolkit2/frames/ftk_frame_igpub.lfm @@ -115,14 +115,14 @@ object IgPubPageFrame: TIgPubPageFrame ClientWidth = 1177 TabOrder = 3 object Panel6: TPanel - Left = 592 + Left = 656 Height = 44 Top = 1 - Width = 584 + Width = 520 Align = alClient BevelOuter = bvLowered ClientHeight = 44 - ClientWidth = 584 + ClientWidth = 520 TabOrder = 0 object cbxVersions: TComboBox Left = 8 @@ -153,17 +153,17 @@ object IgPubPageFrame: TIgPubPageFrame Left = 1 Height = 44 Top = 1 - Width = 591 + Width = 655 Align = alLeft Caption = 'Panel4' ClientHeight = 44 - ClientWidth = 591 + ClientWidth = 655 TabOrder = 1 object ToolBar1: TToolBar Left = 1 Height = 42 Top = 1 - Width = 589 + Width = 653 ButtonHeight = 40 ButtonWidth = 50 Caption = 'IGs' @@ -175,38 +175,41 @@ object IgPubPageFrame: TIgPubPageFrame Hint = 'Add a folder that contains an IG' Top = 2 Caption = 'Add IG' + DropdownMenu = pmAdd ImageIndex = 4 + PopupMenu = pmAdd + Style = tbsButtonDrop end object ToolButton2: TToolButton - Left = 301 + Left = 211 Height = 40 Top = 2 Caption = 'ToolButton2' Style = tbsSeparator end object tbBuild: TToolButton - Left = 309 + Left = 219 Hint = 'Build the IG' Top = 2 Caption = 'Build' ImageIndex = 1 end object ToolButton4: TToolButton - Left = 409 + Left = 319 Height = 40 Top = 2 Caption = 'ToolButton4' Style = tbsSeparator end object tbStop: TToolButton - Left = 359 + Left = 269 Hint = 'Cancel the running build' Top = 2 Caption = 'Stop' ImageIndex = 5 end object tbOpen: TToolButton - Left = 417 + Left = 327 Hint = 'Open the IG (index.html)' Top = 2 Caption = 'Open' @@ -214,7 +217,7 @@ object IgPubPageFrame: TIgPubPageFrame OnClick = tbOpenClick end object tbQA: TToolButton - Left = 467 + Left = 377 Hint = 'Open the QA page' Top = 2 Caption = 'QA' @@ -222,54 +225,49 @@ object IgPubPageFrame: TIgPubPageFrame OnClick = tbQAClick end object ToolButton8: TToolButton - Left = 517 + Left = 496 Height = 40 Top = 2 Caption = 'ToolButton8' Style = tbsSeparator end object tbConfig: TToolButton - Left = 525 + Left = 504 Hint = 'IG configuration' Top = 2 Caption = 'Config' - ImageIndex = 9 + ImageIndex = 22 OnClick = tbConfigClick end object tbDelete: TToolButton - Left = 151 + Left = 61 Hint = 'Delete the selected IG from the list(but not from the undetlying storage)' Top = 2 Caption = 'Delete' ImageIndex = 12 end object tbUp: TToolButton - Left = 201 + Left = 111 Hint = 'Move up in the list' Top = 2 Caption = 'Up' ImageIndex = 11 end object tbDown: TToolButton - Left = 251 + Left = 161 Hint = 'Move down in the list ' Top = 2 Caption = 'Down' ImageIndex = 10 end - object tbAddSet: TToolButton - Left = 101 - Hint = 'Add a set of IGs (folders) all in the same folder' - Top = 2 - Caption = 'Add IGs' - ImageIndex = 14 - end - object tbGitHub: TToolButton - Left = 51 - Hint = 'Add from GitHub' + object tbDevTools: TToolButton + Left = 427 Top = 2 - Caption = 'GitHub' - ImageIndex = 15 + Caption = 'Dev Tools' + DropdownMenu = pmDev + ImageIndex = 9 + PopupMenu = pmDev + Style = tbsButtonDrop end end end @@ -283,234 +281,323 @@ object IgPubPageFrame: TIgPubPageFrame Left = 46 Top = 104 Bitmap = { - 4C7A110000001000000010000000661C00000000000078DAE59B075454D7D6C7 - 6F62DA4BD4C47CD1449FBE24E6BDA889C6D802F616B1810D451010140141B1A1 - 08E8D01504444001110B22204545A4280888082A458AA0204D8A0C5DCA0C5DFD - 7FE75CBCE30C0C68F2F2D67ADFFA0EFED7CCDC7B7E7BEFB3CF3EE7DECB20E399 - 06E64F0A0C18FADA00E0F1CB2EA4747520AEB31DD7DADB10D0DA8AF32D2DF022 - 3A2E6C8523914D732B784D2D38286C97E093091746FA05088438DB2C84479300 - 2E8D0238340A61D32004EFB910FBEA04D85123C4D62A21746A5A25F8D0F6D66E - AEB12F4E005DC26DAA1040B54C00957249DE9BF87625CC1B4E403821EB4F9C5B - F754801585022C2B92E4E9F8287790E5BAE3D4AD94E4140827F74480B9B902CC - CC95E4AD9B5BDE7062FED68A71731E0B209B23C0D42C2126674BF27B9FB7F6F2 - B7A207378570133385189F2EC4CF1992BC2EC9674F8EC6399DFA7B28C4AFAFB9 - 7169428C4D69C67822715EA5BC858D73D16B8EF547B8891992DCB87B0DF829E9 - 39261089F3CB8A5A3027572CCE3EB89F12EAF0537C0D7E2612E767E5B6488D73 - DCBD46096E5C5C15C6C654E2A79B7C099EE6532A778772B5226E6C7405C65C2F - C74F916512FC2F0FDBF13361C7A734610261E9F8C6139F34CE9F094BFDFD74E3 - 19C6116E5C7809C687154BF0FFCEFAFBB77FF0D76862D00A48D3F8F34B598D3D - F13BAB1F6DE7401A6B11EE0461572BAADAEBFA143D7FBEEC1ABEDFFB1B7AF2F4 - 9C5AB113AB0D85F650293802A52787B0F6B105D63CE26165B62914B2F623B521 - 07237527F6E2A9FD9E2C9538BB3C632F6E5427E19BF563A5F2E22C3D4E7D8BB3 - 4B1FEC96CAD3FC505EDC2F774E9C5D9C6AC0F2C356FE4B2ACFB1D4AFF8798EFD - 3D594F2A4FE784F2E2B9E2CE71DCFCBBDAAC68FE87CAFF209517CF15E797B21C - 3F2741432A4FE793F23D73457D737E29DB174FE793CE7F4F56DC2FA7107EAC54 - 9ED61FAD0D9A1F71517F9C284BFBF5E4A9E89CD2BC72A27DFAD25FB5E6FE3F6A - 85CF7A2C3BB3E64FE550E1BC12B4C20CA01142EAC265E91FB221EFBD0E9BAF6D - 8755D63198DE3F84F5FE9A90B599FB4E36969F5B0BCDABFAB0CC380AF30C0728 - 5FDC84E987E661AAD90C11AF71531F6AD7757BD95B7E56918DD73CDD1E66E947 - 58BF3256B3318537FD0D1B4DD8481D18C49B60DD250DD1719AA78D57B682F7E0 - 080E3EB085929F067EB39C85C90765457D3646E94135420726C98761917E14AB - FD3780E669E9E9D550BBAC8B83698761924AF6145F754CB398894907642462DC - 10AE0D95AB5AD8166B049B87CE304D3E04CD6BFAD00A378071B2358C53ADA078 - 410D53CD676092E96F52F3A518A8C6FAD58A3060C77820CD16462996304AB6C4 - 1A9F0D6C9E7E3599D66FAE699E969E5A0DD54B5BB03FC50A7BEF9B61B5B70A9B - A789C6D3DE699E16B82EC53CA7C5584BE25D796E3D9BA75FF64FFD437542E755 - C67A369BA75F8CA6FCA93AA5799AB06FF2FFC97D42FFD08B1FF46C3A79BA561D - 05DA166D022DB316C1A68382020DD3269EFAFE861FFA6309A7B8D5AA83BFC3FA - 395CFD85F00E6F67E5E22FC0565E35540C6BF94ABBAB15A5B15BAD3B14752CDB - 85361E4D088CED82FD85766C3BD2CAEA884F3B02623A61EE4AAE51DB9F0957EA - 9549D8D0B56C1FAD6DDE5A61EDD1C8B25A562DACB8B6C94C00CD8302F84775E0 - C0D11A2CDB525CB16473C1688E276334DB6E592762375B125908453C193B348C - 1BA16ED400BF8876A8EF2AC242F55C33D1FA356D2AA063B43BDFCE729C3FAE51 - 4ECDF0395477D5C1EA78138E9CACC31CE587051CAF6A54DF7A3EB21DBA364296 - E3FC718D721B76D442657B0D347656C32BA0093314D35B397EFDEEEA56EFB036 - 685B348BE2A4FEB29F74B23CE594F5AAB05EB712EADB2BE1E9D784692B5344FC - 1A838A02A7738DB0F1148AE2A4FE9CCF34C13F44C0724ADA7CACDB5C01DE915A - 1C72A9C4A4657745F1AFD85A6AA66958025F12031727F5C735CAADDD540E458D - 329C0B6CC6AA4D5998209720CADF52ADC2D1729AF915C6767C5CB8DA22F277C4 - B51E7664CE29B746BD946577F28AF0F3EFF115E316C48D9658FB6A8F14E7AA64 - 0BF7D994E3FC2521CC1DC8FDA0EE33A8EA9483675B837324673B0F1661DCC25B - C231F363A5D6E08CB5198AB26BD2F86BB6E4C0C6B9126EDECFE176AE1ED64E15 - 90574FC7D8F9B1FC1FE7DE54EC6F0D4C51B8FFC3A4E57779139724168C974B10 - FCF47BBC60EC82B8821FE7C5F0FE3927FA87FFF6F5BFF7A6C30FBBA3EC783B22 - 6D0AF4C32C04BAA107055A57F61768061BF2D40276F41BBFE14D07C5DD376CF9 - 27D27D71879F8A8CDA1C2457A723A4E8060CA2CCA1ECA7C75F7B5E5BB12F76D7 - 0D5B6148E14D14369720F2592CBC0AFCE0FEC41B7E4F43105F950493047BAC3A - AB2194F75295B061186D3F9AB01541F9D791D75408D7BC33B07B701C36694E70 - C871877D8E1BAC1F3A21A4E43AB645F1B0E4A452C5EF27568BEA87B06687EE79 - E0E1F35CB8117FF6D927607EFF88A87E4D1E1CC2B63B07B1F39E192E3D8DC0A2 - B3EB31CF455E54BF0611D605978A22E14FE2B44C75C441722DDE116BF266FD5E - D28766CC7EA8451BC221CB131649AE98E5B458B47EF4AE99B54696C5C1E19107 - B9FE1E465F4DE5C62EE8DD36C3999C20C83A2C10AD5FED10D3D6C0A230F032EC - B12FCDB25F5E378E87D339C1986A375BC46FBAB4AFC03EED248E64BB63DB5D53 - 68DDDE8575C1DA121C956AD41E1C4AF3C081B8A3F8F5D07451FCEA81BBCC1483 - B722A8281C5B6E9B40236E373B5E715E396207B93FDA0BFFFC70C81E5B88F156 - 5345F953F1DF365AE9824E853E999B80826BA25CB17E23761276275409EBF724 - 0C1B82B653B6629CF9AF12EB7FF5B94D8A0AA7D5855BC28D898D08D892F1E8C4 - F0B025FA200EA79E246C389483B661BCE5542161A5D6E0524F65C545EE8AFCF9 - 9EABC04B3806F74C7FB867F8C338EE087E3BBA80B2FCBE584EF35D57FC30FBD8 - 52DE0CC7DF0B7E3B324F30D9769660A28D4CC178CB29BCB1E6BFFED7AF7F3939 - 53383A9E14C9C0E0382B7AFC6DAC9A9A03F2F25E213919ACFCFD5FC1CDED8548 - 13271EC2DBD8FDFBEB59EDDD5BCB6AE7CE2A56FAFA7C181B43AA8D050B74DFCA - 52696995B236468C50414F3E3CBC55C4D1631C3B73661EFB99B21C2F2BAB2F95 - E7182A7A9C6329C3F1FAFAAFFAE4B938A9A4B11B3716B37C5FF173631467D967 - 04C271EA8FE7FC702CC788DBE88BA7F3BB6E5D6E9F5252CA83A2628E549E6AEE - 5C0D76EEB87ED244D931634CFAAC21CE86B6F64B68683449881EE3D8972F5FF6 - 6983CE0DAD31DA9713FDCCC5DC1FFBDFA04D893B661305113D251212B5135513 - 5DD34C3058D20FF701912FEDEF577A13D13569482A894312D9AF6373AFC23FF7 - 12D4E3F4BA3644EB44AE8FDC3CB007FB2151A2639E0F1EB45421A73E1FE9F5D9 - C820D7C3C7C511C8C9F1417AE679246606C136D9058A21EA592B83543E17E3FD - 6C73BD11DF5C8C7BCD8FF1A8E11132AB33F0A8C01F85C5C12878E08CDCFB0E48 - BEED84D8472130BDE782651714235FB3B3883AE305658868084744E325DCAEBF - 8E9CF2EB7892771AF9D96E78409E4BEF85192022D506279E9E4248E503C87929 - BC58E0BE7425612F9F243146D4A621B4E122929F0722AB26198FC8B3FE935407 - 3C08D7414C8C2E4E3DDE0DAB62439816EE864BE605D8DDF7C5EC630BA3085F16 - 56F7105E653E385373948CFD3A326BEE21236A07D24275909ABC0F4605BAD079 - A200ED5C056CCF5687E14D33F8152460BADD1C3EE15BE21A0B6199678DFD0506 - B855710A694F2F2225401D09B1DB7123DF01FE799AD89F3517FA997250895905 - ADE0EDB8F62C1DD3ACA6B76ADE31688D6B288261160FCE59DB11537216F72E6E - 44F6D58DB8EBA988BB313B1092658AF0440384046AE040E07A6CB8A08BD0F274 - 4C329BD6B6F196FEB3AB24D7D639CEB855688F3BE4793FCD4709F9216A280C51 - 45F2A9E5B8757821AEDB2C44D4A93570F7DB0C6D7F23F8E4C562A2E9E42A520F - D75C7343E05D1C0E9BBBBB10906981243F35645E5C8F922062C77F35EE9D5C86 - 28C7C588F45A0FCB73DA30B9E50CCBB8D394BFA514BE498ED44357444D36F462 - F692FBA6DD888B3440F205553C0D56455180326EBBAEC099406518937C6E70D7 - 857F613C655F116D609F3F02D6871AC51F85676E184CE22D10431E2DEE06EA23 - 37540F8F2F6B23C66B23342FEB43C5632B2C6F7B4237F000EB5B74DD3FBF6610 - A987AC5DD70FE34AD53DC43FF44652982552C279480B3146D4456358A4B9C13B - 3F063A01A694CD27FA46E2BA7F62F120520F9133ECE77679259D4158C219C4DE - 3E8DB83B6770F56128CCE24F51EE05F54BF4755FEBF0379B19ABA758C85C9FC4 - 9BFA8CF46B792D3E512C915A2FA6C74FA8B313FAD3DBBE4F60FB1427F452B4BF - 071EC55F7FAB0DF67CE9DD5EA27C676BE35B6DB0E7CA537B89E3A98A33D24536 - 54A64CC5DB047E06ABD30E6612A236D8F362ED15F9A12DBFB910C74BDDBBCF57 - E7B08A387F1CD7BC5D117ACE0557CF3A4BF2046B6D6B03C8BFAC9A4C0C0D1E06 - E75CE7EEF3B54F5865DF0E9510C7977692BDAB2C9C65332B3331C87F10E4A2E5 - C0E7F3BBF9FA22A9E2F825D9F2F8D4FF53D865DAE2EF97476088EF1044675F07 - BFB8823DFFAAA14CAA387E59A60298B324999E0CDE3BFF1E1CEE1D41494E1172 - B2B3BBF966BE54717C5967398C52F661A0FF402C889C8FACCC7464A5A42325F9 - 5E372FAC952AF1FCBDE804424BC391589484E2FC12A491394E494BEDE6DB1AA5 - 8AE3DFA6579D42A9925687F4D8ABAECE77D27F8AFF23EAC927F8FBA23FBD6DFD - B37DF899BD941C75094FD3EFBDD5067BBE2ABB9728DFD52E7CAB0DF65C4D6E2F - 713C153FFF492F1BCCB02450AD544A82BC62127E99140273A31B405DBE48577D - DC25C4D9A0DC5EB33C728D04826381B3D7007B1F60C9863CFC362D18785ECC2A - 29221077C20390107611B7AFF94BF0E5D5406717E16300CBD3401A09BB840F4C - 5D9607736372B0B10C45190912A23C65A9CFFAA6EE6DA4AD037858D8FDBE5908 - CC218FE15F8DBC0A3455F412C79F0A018EFA01CFAADFEC634D845DB40DF86C16 - F0DED7497825A8EE258EDFE70AE8D901773224F9DF3612760AD83EAF5AEA7A89 - E315C9A37E5C6A37D72820DB7D65F7FB8666E07B05E08BE157A5AE5FF1FCE53E - ED666534802FE703194FBAF9EFA693FC1D24FE3B84BD24CE8F92C9C3BF5675C7 - 4B35645E37FBEB64E2BBAB4DAAC46B88AB1F4E5F0C0F85B959325EBDE8EA53D2 - EA981EEB8F7917FE8FE83FF10C515E5E6E262727C788B7A54B97322E2E2E8CA9 - A929C3E3F1187575F501DCB9C99327ABA4A6A70B38FEECD9B3ED0977EE549353 - 1F717D141414585E4F4F8FF1F4F474F0F2F26A20877FA67D3C3D3C1ED6555777 - 7DFBEDB76CDF556BD69CA303D3DEB2258C7E7EEFBDF7180B0B0BC6C0C0807176 - 76DE535858086565E567AFED8FB430374FA7FD5353536F1A9B98D8EC3536EE2A - 267DD6AF5D1B45F9F9F3E733EEEEEE8C3F69D6D6D6AF88BD9DE2631B366C981A - 57F7D9398FD14616615343035628285CA1E78D8C8C98E4E4E4471A1A1AADE4E3 - 14464A1B33668C61E8D52BB587EC9C2A4DACEDF9C5759D28239B82BE9EAE1FC9 - 59C2A449937249B74F99776C567A8A8F9ADB1AF0B8A40E1B54942BDFD69F1A9E - 399C61FC57324CBADEE06D719A4C7DC3B1C988098B416272068E3B3BDF0AB878 - 9199F0CB2F125C99CDD74C81D5D78CC0653803F7210C7C2727235506F0FA1A3E - C3995A176303F68B88B8A82864656464CC9C395382C7A96F093794E970183ABA - C9737275E7ED8980EFB7285E38E8254D0B99A231645E5E355557E309B99FF0F5 - F52D26C7DFE7F8069BC144C3D7B55D91E944D2CF80CB70444EFE54404ECDE5FA - 8C1A356A3BF10D7E5919EA899D63C78E9588FC7B8F0F410C8937E947C0FC6B38 - FCF0313D37BC677E488D3AF3CBCB617FE448FD93274F403EB3357062E350AF36 - AB2F01E3FFC1E6A1EFDFED2FC7A48E7C131212B067F7EE27E26318C530F213DE - 63ACC58FF5D1E8F94944FF238AFFDF5CAB7DB59EBFFB7DD7BAE3FA8FD0F859A4 - A12BFEF94E76E8F96F0DA7B20AE4C7B0F2290B63456D7076FA62FF693D4BF477 - 1B86398E9895A08EE971EBA196BA97B571A6F4AA541BF4F358B7DF71A72E9DED - B734751716A5E8637EE216918D69D1AB599BD26C707CF2F36CACCEE1B17F8742 - 6D704DDC464F9E63331AF3D8734AF936221B5C138F838E45DC066D1302E4914D - 9E373614D9B3E26C708D8EA5AF18383E4FF014EA25C758BEAF466D509E9B8F9E - 3C9D2F6A83AA67E3C6A09DCE93E0B91C88C7D0330EF1F9A03E684DF5CC3FC7D3 - 39E478F15C52DEB1E88254BEA70D6E2C1C4F39AEAE686DF65783D406371F744E - 694DD098686DF6C7F65C3FD406AD0B2ACAFED975F847B9BF6AFDD398B9F8E958 - FEC8FAA72CCD19CD1DCD21CD2597D7FE724F596E9EE89CD1B9A37348E7929B57 - 6936B8FD8AF6A31CAD155A331C4F6B89D6148D499A0D719ED628E5C5D73FC753 - F5E4E92B5D0B744DD0B541D708B5D1B3713C3716F19C723C5D9B94EFAB717148 - E3E99E4079BA47501B740C5C13CF0315371F3D79BA3771BCF818C47349FBD139 - A575D133073D63105FFF9C0D5A13E26C4F9EEED1E236C4E783E688CE614FBEA7 - 0DDA4F7C2CD4265757DC5AECAB06B9EB1477DDE2AE63DC75ED5DD73FB5217E0D - FD4FADFFBFFADEBFA6A60B91118DE09997427F5B11B66E2B80A14931AE5CAB41 - 557547BFCF1B19192D30362E83D3F17AC4DD69475A760712533B10142E84CEAE - 3268193CC2DD9406F4C5EEDA598AA0CBCDC82B7C892BD19D70B9D00987339D38 - 1DD885E87B2FB0EB40351437A7E3CEFD7A091BB5B55D30312EC7858B02E414BC - 84EDA94E98BB34C2D4A909E627DA61E6DA0123C7760444B6436B4739D66F4D43 - 45559BC84644780378D6357890F382F56776BC0DFBEC9F63BB4DAB84B44C04F0 - 0D69C79C959938175422E20F9A97C12FA40567823BB1DFB1116B35EAA44A6B7F - 332C9D843036AFC6BA6DF745BCDE8E42844475C0FC7827761D6AEC33C70A2AD5 - D8A8FF1CEE679A307B5DBCA8DF96AD05381FDC865D87DBB1D5AAB55F5E4DA706 - EEA79B305D294ED4CFD0B810968ECF61E6D206754301683F695AA95A8D03D68D - D877A00CCBB7DC11F197AE5663B952017C825BA1B4A5116B749EF762E595F958 - B3818F73175A30755522DCFC0A443CADAB2DBBB3B1691BFDDB9D163657ABD46A - 586E850A1FF24A7CAC223AEB23C45ACDC798AB760B65952D12E34C4A7E8E559A - 0FA0A65D82F3FE2D303BDC0055AD6AA8A8578267F31C67BD8558AD9E8BA9ABA3 - 1195C8979AA30452576BB553316B4D1AF69956E198EB7356BB8D9F618AC26DCC - 558DEB93E5F4ACB21567034BB176DB3DCC5189C774C55B58AE93008F8B0528AD - 10FE479ED73FF9E413762FF8E69BE11F9E3CE9F1EAEAD5905E7A9767082B2B2B - FF6BD7AEA1B3B3032F5FBCC00B22FA7D27E1F136FF3C1E2F9076A27CCFF6367E - E1C205C723232370F9F2653C7C9845FC77A2A3A303AFBF6B65F991234732B76F - DF66FBD3DF2388F34B962C71637F874CE26D696961F5E24527EAEAEA10107091 - E5FBCB07E1D99B55A15088A6A626F2FCDF8667E459312828087E7EBEBDC6E3EC - EC5C218D6F68684033E14B4B4B71EEDC39761CE1E1E1EC385EBCCEE76BFE9134 - BEAEB616D5B5D5B872E50A7C7CBC114672696B7B98E4A28D8DA9AD83DDB3E8F3 - 6F8E38BF78F16296AFAAE213DF250809096163A10C1DD31B35B3FCD1A347737A - F87764FDD7D582CF7F86C8C870D4D7D7B3B9A076C4459BA38383042F2F2FFF3A - FF9D2C137BF3266AC938E8786A89B8572ADAECED8F48F043870E9D3B7DFA743F - F24CEE3579F2245B6565E53C9ABBEAAA2A54F1F9DDAAEA166D76767639FD3D03 - CBCACA18D17ECF9E95A3BCBC5442B41D3E7CA85F5E4141C119FD34575797C2FE - F8D9B3671F7AF0E001ADB997642E24949E9E8E9D3B7766FC65EBFFBFE4E7E3A3 - 7110D71F658B5FBEC2B917AF7085BC6E4E7F869EF6FAB2C9B264350793645C7A - AD2BAF15F25A7447F2255B89341BF4D8D1E79D22F5F4D9F39C34DE20AF41D4FF - 5DC6216E87BED7CCA8C39F1D077DAF9652DF2BD6FED4935F97588B9EE3F8235A - 19DFCD73E3A0BB44542710DB05C47575BF52DD22DB5F04B93D39555887E85A81 - 885F1C5D05F17104936DCABCA20BD6FC17B02212BD56BE84695907D4EE96E264 - 49AD681C9C1D6E1C0175807151170E16BF118FEA6917F6E6B7636362293C8A6A - 7BE5811BC779B2CDEC78D489DD8FBB883AB187BC5219E6BE80FEC336ACBF558A - E3F9BD796E1CEEC52FB129B50D5B1E50B5439BBC6A93579D74E23B5988555125 - 707854D3AB9EFE48CE879EB8C3B2028140A4E6E666D4D4D490FDC9150B172E04 - D957F1F1C71FE3ABAFBEC2BC79F3E87507D5D5D51067C415191949AFB3183C78 - 30343535E1E1E181C0C040787A7A62F3E6CD18326408468C1881D0D0D05E367C - 7D7DF1C1071F60E3C68D64DF7D061A4B4FD1EFB3B5B4B43060C0009C3D7B5664 - 23252505E41E024646466CFCD2582ADAB78A5C13C8BD063EFAE823242525B1C7 - E858E7CE9DCBF6217B37BEFFFE7B7A8D24FBFC61181A1AC2DADA1A6E6E6E183F - 7E3CA64D9BC6F65BB4681166CE9C89CCCC4CBA81232A2A8A3D2E2727C77EEE4B - 13264C607D927B11F633CDF5B061C358968E9BBEEF8FFFECB3CFF0E8D123B6FF - A851A3D8F866CC98C17EF6F6F6EE97E544AE7F6CFFF9F3E763CF9E3D229ECED3 - BBF0161616229ED604177F6262E23BF1C1C1C1A2F8333232D863B1B1B1ECB1E5 - CB97F7CBCAC8C8B0F7119C2FCAD0DAA47348DFD3FB0E727F82050B16B0734CFB - BCFFFEFB20D75490FB53B67E393FB2B2B2ECFBBB77EFB2756E6E6E2EAAA98888 - 0809BF5E5E5EA23AA275F1E1871F223E3E5E74ECF4E9D36C5DEAEAEAB2754A63 - 10E7F7EDDB075A7B0606066C3CEEEEEEBDEA93DEBF0E1F3E1C5F7EF925A64C99 - 22C18F1B378E5D8F34D701010112352DBE7E2B2B2BC9FD913D5B9B83060D62D9 - 810307B2736C6B6B8B8A8A0A09A6BF7B8381FF18FADEDBEE1F7655C6308BD29D - 99C14E639853F957986BB5698C4DFEA58F9C8AAF4E534C775E3836CD4EC6B9E5 - F1178E8521CC68A7B1CC07BB196690C9476FFEEF4DD9B5FD7F3F295734C06E24 - E39E1BC85C6FCC5671CCBF947E38EBB46063D82E4CF45D87433571D9CE15B1CB - 7E701ECF0CA0BCE91B3EAEA5FCD9D7CE33C1ECFCE4E4A5CA3B3E7E0DF771E0C1 - 7128F8AA43C6763AC61A7C87B17B7EC4AF1E8B31D2EEC77D1F1B4AFA2F437BD2 - D6584BEC4AB0815B5D02741E1CC3B2206D2C3CBDE6A1ACE334E3D17B062ABFBF - F2FD838C1CC3FF70E5FBF89B0EF3CF8F35DEFCDEC4A3E1FE8DC0CE02B8B56441 - E9BE1D26792C15CA076F92DD16779099E1A3C08CF39367461EFA07C3AC2333B1 - 8451FB5487F962086F9488B7AE4FB8B4A3FC0A5667B96246F46E7CAEF755EB60 - A7B173D7679D60FE71DF9C1992E3C498F0A318BBFBA718395779669CFD1866C4 - 65C537FF672AD7D77D41A2157E89DD81EF6EA86390FD640C759A8EE1C7E7958E - 4EB399C5F58BED7ABA675FA28DEE4F4E93560CF69AF319777C8CE9BF864FF757 - 921F6D22B39599FBD12146E76F973F33FA2E4BB720685D01048AF38236433660 - 2396451AE2F7602D8C3A321D53E28C4C44FF7756E76F8CCC2555E6EF27D63283 - D68D643ED71BC03006EF316AA9C719F210C8C416C66D508D316D97BB638E4977 - CD31FBBE2DAC0B2E8772FCC77E2B984FA2741926C568ECDC62CF4FFD0A229895 - DE2B99C17B3E64066C20F7D257B67EBF326C47F3B484FDF87BD4564C08D1C19E - 44C74B1C1FF4328F0916A4332B320EE7AFCCB26FBD589560B9295467CE8F963F - CB8FB19E7C7D6680F24BD91B3BF17DAC16BE4EDF8DAFDC16E25BDB2909E31D64 - BA6BBBA35BFC921CB5338FDDE0F4D40DCA21EAAF16F8C8BF5A12A88EA9D13AF8 - 36451D430FCB360F39B93466A0CF227CE528F362A0FE4096FFFCF3CF590DFB72 - 28335176CCF655C7164325561572775431267411869D94C160ED1F6B3E5D3C4A - E50BBB993F7DE12EEB38F4A8CCF33EBF7F1BC0CCF946E6EB1B23D68CCC1D38EB - CB7B1FFE3AC8F3B35523BF64BFC71EF01133D069D2879FDBFE63C05BBEBFFB94 - F980FD9E7084C497877FFB84196C359E19643640543FFF0BAB913220 + 4C7A1700000010000000100000006B2700000000000078DAE5BC07581547FBF7 + BFC698E44934ED678946534CB14463178DBD97880DA508888A800DBB08284D10 + 10100105041450010151A42A08A880850E8282F47AE8FDD091EF3BB3B8C7031C + 109F5F9EEBFFFCDF77CDF73AE7ECCEE7BE67EEB9677667770963170BE6DF1418 + 30F4B31AC0AB376D886E6B41586B337C9B9BE0DED8886B0D0D7020BAC86F8419 + 91415D23B46A1B709ADFDC858F229C1F29E75ECF87631D1FB6B5F5B0ACA98769 + 0D1F06D57C6855F171A2A21E07CBF8D853C28772596317DEA7B9B193ABE98DAB + 870AE17616D54336BF1E32055D7967E2DB8A30EFB87AC2F1597FC2DCD69C7AAC + CFACC7DAACAE3C6D1FE54EB35C673D558ABB72E2845BF9BA1E8B52EB312FB52B + AF5FD7F08E13F2B745885BF8AA1E7352EA3133898FE9C95DF9E3558D3DFCADEF + C6CD20DC94443E26C5F3F14742575E85C4B33B47EB3997FA7BC1C7D4B7DC8458 + 3EC647D7611291302F53D0C0D673C55B8EF547B829095DB909CFAA31F1491526 + 1309F36BB31AB03055A89EBD7013C32B30F15119FE2012E6E7A73688ACE78467 + 355DB8096125181F528C890F785D781A4F915C04E5CA05DCF8E0228CBB578089 + 81F95DF83F5F34E30FC24E8AAEC564C2D2F64D223E693DFF202CF537F17E2126 + 106E827F2E26F96577E1FF37E3EF7FFD0FFF8CA678AE87284DBAB686D5F84BCB + 59FD6EB410A2585D7F73F0DB1A51D25CD1ABE8F16BF9BEF8F9F86C74E7E931B9 + 6C7356DB324D2093710E92AFCF62CB2B5D6C7EA9850DC99A104F3A8998EA148C + 5699D283A7F6BBB354C2ECDF09C771BFF409BE931A2F921766E97EEA5B985D13 + 7744244FE3437961BFDC316176558C2ACB0FDFF09B489E63A95FE1E31CBB3C6A + AF489EF609E58563C51DE3B8254F9558D1F80F5BF78B485E38569C5FCA72FCC2 + 7005913CED4FCA778F15F5CDF9A56C6F3CED4FDAFFDD5961BF9CBC79A122799A + 7F3437687C8445FD71A22C2DD79DA7A27D4AE3CA8996E94DFFD498FB7F51EBAF + 4B61EDD5CDFF560CC5AF4942D14F150ADE242F2CD77C908D75CE5BB1CBF700CE + 245D80E6F3B39072DB8139068BFA65E36FA72DD871771FF412CE4327C114D237 + 7762EED9C598A9FD97805778B00F72F7547AD8FBDB5182ADAF4EBC09B4E3CFB1 + 7EC5CE2CC00CADB9EFD860C2062A43F59106B67A2908F6D3386DBFB3075A71E7 + 703ACE0892AE0A98AD371FD34FCF1194D91EB417B201CAD08832846EFC796C72 + DB061AA735573641EEB60A4EC71A422386CC292EF298A53B0FD34E8975A9E336 + 7F25C8DC55C4FE503518BCB08066D459ECF0DD07457F55A847E9433DE60C246E + C861A6CE5F98A6395B64BC243CE458BF8A01AA6C1B4FC51A412D5A0F6A517AD8 + 7C7D1B1BA7A91AB3FA8C358DD31AFB4D90F5DA8D93D16770FCB9363639CBB071 + 9AA23EAB5FFDB4D46A0D169BAFC21652DF0D4E526C9CFE3C39F383F284F6AB98 + FE02364E7FAACDF8B7F294C669F289E9FFBF9C27F69D6DFF65AF41AB96CA9996 + 0C25DDA67A45ED86FA9DA7EB3314346BB5E44F56FFD2174B38893D675A7807F5 + AB60E5C687B37F332B4BB77AECD12A85CCB1729EE491520951EC1EFD160965BD + 66BE816D2D3C42DB6072A319FBCF35B23A77BD19EE21ADD0B122E7A80385FC0D + 7BF3BBD850D16B1EABA4D358A46F5BC3B28A671A5871DB4EED7AEC385D0FB7A0 + 169C3A5F86B5BBB38B56EFCA18CBF1A48DDA07F42A04EC2E3D225DBE80276D87 + 827A0DE4D5AAE11AD00CF9C35958269FAA2D18BF9AB519B48DC6D79A598EF3C7 + 6D94933B5605D9C3153873B116E72E5760A1F48B0C8E9755AB6CBC16D80C1503 + 3ECB71FEB88D72DB0E9643E64019140E95C2C1BD167F49C43772BCD491D24667 + BF2628E9D609EA49FD25BF6E6579CA49EF2D81944A31E40F14C3CEB516B33644 + 0BF8CDAA4519E64E3530B0E30BEA49FD595CAD859B773DCB492AF1B0755711B4 + CE95E3AC6531A6AD7D2AA8FFFA3D79DA3B8EE5C285D481AB27F5C76D94DBB2B3 + 00120AF970F2A8C3C69D4998BC325C10BF358A996357EE482F5237E6E1C6DD06 + 81BF73569530267D4EB9CDF2792C7B482B0B7F2C7F54346169D8D82E635FEEA5 + C4229964FE0983025CF3E243C7945C0FAA144256B9005A46657022313B743A0B + 13963DE48F5B122A3207FFDA92203167732C6FF3EE14185814C3DAB90AD64E95 + D0372FC23AF9788C5F12CAFB7DD10389BEC6C00CF1E7BF4CFBFBA9D694D59119 + 935686D74F5CFEA87EFCD2B08CDF178768FDBA30F897FFF6F17FFC81E92F4782 + 8CB50E061A64ECF3D3AD57F1395DAF78E764C68E5BC7B4E4DC0FF659FF630F4C + 258EDC37E25D8A7741042F0609E529882A8D8777D67DA806E940DA752F6FCB35 + 2589DED8C3F78DF8DE990F9059978BC0C2503864B8C2E6B5335C73BCF1A8E409 + 34C24DB0D15181BFCE41B68B8D63C12663095BE4997E0F69B599B04ABB0AE3B8 + 8B30883587698A0D4C52ACA1FFC21CDEB9F7B03F480BAB2F4B162DBFB449903F + 84D53EFBCC162FAA52614DFC99245F82CEF37382FCD5883B8BFD11A771E89936 + BC7202B0C2510A8B2DD709F25735403FC32B2B106EA49E7A3166384DCEC50743 + 35DE8D5FAF7DD811721272C1C7609A6407DD2756986FBE4A307EF6FA6A3706E6 + 87C1F4A52D39FF1AA2B74DE6FE61EC7DAC8DAB299E9863BA54307E95BC351B3D + B2FCA095608213B17A7DF22A615AB892720B338D1708F89D5E27324C622FE35C + B20DF63FD584E2E3C3D87A4BA90B47251B741467636D712AEC3CA69E9D2BA8BF + BCC7616D895B7BE099E58FDD8F35A01076846DAF302F1D70905C1F1D875BBA3F + E65C58864967660AE227E3B67FACE40DE5A27DA46FDC337C05B162FD061C22EC + 21C812D6F5B51FB6791EA06CD1049DA95DC6FF26A79D12E257E4F9BBFDD5898D + 001891F62887686177F06918C65C26AC3FA43DF76392DE4C3E6145E6E01A3B69 + 89153612BC25761BA1157E0136896EB04970837AD839CC3EBF94B2BCDE584E4B + ACD6FFB2E0C21AADBFCC9667CC3EB7B87EBAD1FCFA2906621993F466688DD799 + FA5F3FFE57AED48499D9658154552FB2A2FBDFC7CAC999222DAD03515160E5E6 + D6016BEB7681A64C398BF7B1274F56B23A7EBC9CD5A14325ACF6EDE3415D1D22 + 6D2C5DAAF25E964A51318FB5316A940CBAF3FEFE8D028EEEE3D879F3D2D8DF94 + E5F83973F689E439868AEEE758CA70FCBE7D1DBDF25C3DA944B1DBB767B37C6F + F5E7DA28CCB26B04C271EA8BE7FC702CC708DBE88DA7FDBB756B6AAF92944C83 + 84448A489E6AD12205B6EFB872A244D971E3347ACD21CE8692D21B2828D47611 + DDC7B16FDEBCE9D506ED1B9A63B42C27FA9BAB735FEC7F8376461E5C40E44994 + 43C4276A262A25F2DD11AEBABA0FEE6322175ADE35EF0182CB62F124370C4FC8 + 7C1D9A7A176EA95E900FDBDBB62D5839502A70D7E06EEC20A248B3B4EB886B28 + 414A653AE22B939140CE87AFB2039092721DF189D71099E809A3284B4878CB27 + 6DF094F94A8877354A75C6A3BA6C3CAB7B8597D52F91589A8097196EC8CCBE85 + 8C380BA43E3745D4637384BEF486E6334BACBD2111F8969D4FD4FAA83E1F01D5 + FE08A8F1C2E3CA7B4829B887D76957909E6C8D38B22E7DE6A78A8018035CCAB1 + 8777711C563A88B72FB559B381B0B72F933A0694C7C2A7FA26A2AA3C90541685 + 9764ADFF3AC61471FECA08095181FDAB2338937D0C9A994760997803C6CF5DB0 + E0C2B220C2E7FB55BC8043FE755C2D3B4FDA7E0F8965CF90107410B13ECA8889 + 3A01B50C1528BF168752AA380E24CBE3D8036DB8668463AEF1421EE11BC26A32 + A197A68F9319AA7858648FD89C9B8876974778E801DC4F37855BDA0E9C4C5A84 + 7D892B2113B2118AB70EC0B7301EB3CECC6DDC11A1DA18569D8563495AB0483A + 80905C473CBBB91DC977B7E3A99D049E861C84779226FC2355E1EDA180531E52 + D87643053E05F198A63DAB69FBC37D857749ACF5532CF030D3041164BD1F7B5D + 12E9DE72C8F4964594FDDF7868B80CF70C9621C87E336C5C7741C94D0DD7D342 + 3145737A09C9075FAB546F3867FBC3E0E961B827EAE289AB1C126F4A21D793D8 + 71DB846797D722C86C15021DA4A0E7A4048D8716D00BBB42F98792FE3B57927C + 680B284BC6DE90E3E4BAE908C202551175431639B76491E52E8DC756EB71D543 + 1AEA249EDB6C54E096F988B21D44DBD8F587BB948FDAA3F3B04BF583C6235D84 + 90A5C5538F7D48F5D98B57B79510E2B01D3B6EEF838CED1EE83DB6838AC729D6 + B7E0BC7F6DF310920F4987EF19E24EC9333C7AE18C277E7A88F6D742ACB73A82 + 6EAA4337D61ACEE9215076D7A46C3AD1775DCEFB97560D21F910F897C9A23687 + 2757E1177E15A18FAF202CE22AEEBEF081F6237BCAB553BF44237A1B87B30DFE + DA344357ECDE34AD9985A45CC35BF1884289E47A30DDFEF95898A32FBDEF7902 + 5B263BBC8782DD6CF1F2D1BDF7DA608FE73DED21CAB736D6BCD7067BAC20A687 + 389E2A3B215E604366C64CBC4FE025B0BA62AADD45D4067B5C68EB20FFE8965E + 97898B79369DC74B5358055CBB085F672BF83859E2AEA345579E608D4D4D00F9 + 2FA92C11C36E0D8745AA45E7F1F2D7AC921FFB7411C7E7B592B92BDF9F65138B + 1331C46D085606AF048FC7EBE42BB3448AE35727AFC3E76E9FC338D108DFDF1E + 856F5CBE4170F23DF0B28BD8E31DD5F922C5F16B13C5C1389260DA3118706D00 + 4C9F9D436E4A165292933BF93A9E48717C7E6B01D4A24F60B0DB602C0D5C82A4 + C4782445C7233AEA5927CF2F1729E1F8B5B7023E79FE88CC7A82ECF45CC4923E + 8E8E8DE9E49B6A448AE3DFA78E56BE4889CA43BAAFA3ADB55FFA4FF11FA2EE7C + B89B0BFAD2FBC63F5B8697D84351415EC8897FF65E1BECF192E41EA27C5B33FF + BD36D86365A93DC4F154BCF4D73D6C30C39F806A83E413AC9378823FA7794347 + ED3E50912ED0DDEB365DC4D9A0DC71ED34728E046E85028EBE80C97560F5B634 + CC9E750BA8CA66F524C00311FEEE08F7BB89C7BE6E5DF88252A0B58DF02180DE + 152096543B9707CC5C9B061D75B2B3261F5909E15D4479CA529F95B59DD34853 + 0BF022B3F37B1D1F584896E14347DF056A8B7A88E3EDBD81F3AE4061E9BB79AC + 96B02BF6035FCC07068C78828EFAD21EE2F81356C05E632022A12B3F7B3B6167 + 802DD3D150D1431C2F4196FA61319D5C4D3D99EE8B3BBF57D7013F8B035F8FBC + 2B72FC0AC72F35A793155300BE5D0224BCEEE47F9A4BE2779AF86FE1F790303F + 462C0DBF6DECAC2FD5378B3BD9A9D389EFB6269112CE212E7F387D3DD2073ADA + 51E8686FEB55A2F298EEEB8BE90FFF21FA4FAC210A0A0AB457AE5CC9086F6BD6 + AC612C2D2D194D4D4D464B4B8B9197971FC81D9B3E7DBA4C4C7C7C3DC73B3A3A + 368747449492439F7065C4C5C5597EEFDEBD8C9D9D9DA983834335D9FD072D63 + 676BFBA2A2B4B4EDC71F7F64CB6EDCBCD989364C69F76E3FFA7BC080018CAEAE + 2EA3AAAACA5858581CCDCCCC84B4B474E15BFBA3757574E269F998989807EA1A + 1A06C7D5D5DBB24919A92D5B8228BF64C912C6C6C68671239BBEBE7E07B17748 + B86DC3870F97E3F23E39E5159AC820ACADAEC67A71F13BF4B89A9A1A131515F5 + 524141A191FC9CC188D8C68D1B77CCE7EE9DF2B3C6E6C51AFA26BCEC8A56E493 + 4961DF5E155712B3F069D3A6A592629F33FDDCCEEC957859D7548D57B915D826 + 235DFCBEF2D4F0BC910CE3B68161E2F77EB93F6C0753597D613A42FC42101995 + 808B16160FDD6FDE6426FFF967172EDF600493716604536F399281CD370C5CA6 + 4721460C701881EB2399724B7555F6414458501092121212E6CD9BD78587FD8F + 841BC6B4980E1B5B6B37BDB4F5F114C0E547642F1BF286868574D138D22F1DB5 + A5A5784DAE275C5C5CB2C9FE8F38BEDAE04BA2915B9BEE88B5E2C91F80E54804 + 4EFFBC9E1C5AC495193366CC01E21BBCFC7C54123B172E5CC815F8779EE48D10 + 52DF27BF033A2360FACBA7F4D8C8EEF121396AC12B2880C9B97395AF5FBF06F9 + CDE6C0A5EDC31C9ACE7C0BA8FF0F760DFBE8695F312679E4121E1E8EA3478EBC + 166EC3188659377900A32FBCAF978D1E9F46F43F82FAFF2FC76A6F5BF77BBFFD + CD3BAEFC28853F041AB6FED77ED9A1C77F3C369395072F84D5F57C3F56D40667 + A737F657FDF982F7368EA598617EB83CE68649412EE6386BE36ADE5D9136E8EF + F1D6CB115111CF965B1373182BA2F76149E46E818D59C19B589BA26C707C5455 + 3236A568B1EFA1501BDC266CA33BCFB1093569EC31C97403810D6E13AE076D8B + B00DBA4D765F8764B2DED89665C28AB3C16DB42DBDD581E3D3EA73209F7B81E5 + 7BDBA80DCA73FDD19DA7FD456D5075DFB83628C56B75E1B91808D7A17B3D84FB + 83FAA039D53DFE1C4FFB90E385634979B3AC1B22F9EE36B8B6703CE5B8BCA2B9 + D9570E521B5C7FD03EA53941EB4473B32FB6FBF8A136685E5051F6DF1D871FCA + FD53E39FD699AB3F6DCB878C7FCAD298D1D8D118D2587271ED2BF694E5FA89F6 + 19ED3BDA87B42FB97E1565839BAF6839CAD15CA139C3F13497684ED13A89B221 + CCD31CA5BCF0F8E778AAEE3CFDA463818E093A36E818A136BA6F1CCFB54538A6 + 1C4FC726E57BDBB87A88E2E99C40793A47501BB40DDC261C072AAE3FBAF3746E + E278E13608C79296A37D4AF3A27B0CBAD74178FC7336684E08B3DD793A470BDB + 10EE0F1A23DA87DDF9EE366839E1B6509B5C5E7163B1B71CE4CE53DC798B3B8F + 71E7B5FE8E7F6A43F81CFA9F1AFFFFF4B57F59591B02036AA0A593877DFBB3B0 + 677F068E6964E38E6F194A4A5BFA5C6F242434405D3D1FE6172B1116D18CD8E4 + 1644C6B4C0D39F0FE5C3F950547D89A7D1D5E88D3D7C280F9EB7EB9096F90677 + 825B6179A315A6575B71C5A30DC1CFDA71F854292476C523E27965171BE5E56D + D0502FC08D9BF548C9780323FB56E858D640D3BC163A979AA16DD50235B366B8 + 073643F16001A4F6C4A2A8A4496023C0BF1A5AFA65884B6967FD695F6CC20993 + 2A1C3068EC22458D7AB8783763E186443879E60AF8D33AF970F56EC0D55BAD38 + 6956832D0A1522A578B20E7AE67CA8EB9462EBFEE7027EEFC14C7807B540E762 + 2B0E9FADE935C6E232A5D8BEAF0A36576BB160EB2341B9DD7B3270ED56130E1B + 3663CF99C63E7939E532D85CA9C55CC93041B963EA99D033AB82B66513E48FD5 + 839613A50DB2A538A55F8313A7F2F1F7EE0801EF75B7147F4B66E0FAAD4648EE + AEC166E5AA1EEC3A691E366FE3C1E94603666E8C84B56B8680A779B5FB483276 + EEA7EFEE34B0B1DA2857C672EB65785827C9C34622C7EB7C6CD9F10A8BE41E22 + BFB8A14B3B9F445561E38E38C829E5E29A5B03B40DAB21AB580A19F962681954 + C1D1998F4DF2A998B9291841913C91310A2779B5452906F337C7E28466092E58 + 55B13AA25E8819E28FB14836AC5796536171231C3DF2B065FF332C947984B912 + 0FF1B772386C6F6620AF88FF1F59AF7FF6D967EC5CF0DD7723075DBE6CDB71F7 + AE770FF5670D71E6CC19375F5F5FB4B6B6E04D7B3BDA89E8F34EC2E37DFEB5B4 + B43C6821CA77DFDEC72F5BB6F4626060006EDFBE8D172F9288FF56B4B4B4E0ED + B356961F3D7A34F3F8F163B63CBD8F20CCAF5EBDDA9ABD874CEADBD0D0C0AABD + BD151515157077BFC9F27DC583F0ECC52A9FCF476D6D2D59FF37A190AC153D3D + 3DE1EAEAD2A33D16161645A2F8EAEA6AD4113E2F2F0F4E4E4E6C3BFCFDFDD976 + B4BF8DE75BFEA528BEA2BC1CA5E5A5B873E70EAE5F77861F89A5919121894513 + 5BA7A61676CEA2EBDF14617ED5AA552C5F52C223BE73E1EDEDCDD68532B44DEF + 54C7F2E7CF9F4FE9E6DF8CF55F510E1EAF108181FEA8ACAC646341ED088B6E66 + A6A65DF875EBD6BD8D7F2BCB843E788072D20EDA9E7222EE938A6E2626E7BAF0 + C3860D5B3477EE5C57B22677983E7D9A91B4B4741A8D5D6949094A78BC4E9574 + 8A6EC6C6C6297DAD81E7CC1153A3E50A0B0B505090D7457433343CDB272F2E2E + 6E813E362B2BCBCCBEF8050B169C8D8B8BA339F786F44517C5C7C7E3D0A14309 + FFD8F8FF2FF9F7E9F93008EB43D9EC371D706AEFC01DF2B92BBE10DDEDF56693 + 65C968BE4582E1F55677DECAFBADE88CE442A6125136E8BEF355AD0275F7D9FD + 98285E35AD5A50BE3FED10B643BFEF48A8C0BFDB0EFA5D2EBAB2475DFB52777E + 6B6439BAB7E343B4E15127CFB583CE1241AD40681B10D6D6F949F5904C7F01E4 + F2C43EB302C1E5F5027E55700984DB718B4C533A456DD0E7B5E30C91E0B3F80D + 34F35B20F7340F9773CB05EDE0EC70ED70AF00D4B3DA703AFB9DB4A872DA703C + BD19DB23F3609B55DE230E5C3BAE9169E6E0CB561C79D546D48AA3E493EA586A + 3BF6BD6882D4C33C5C4CEFC973EDB0C97E839D314DD81D47D50C25F2A9443E95 + E389EF283E3606E5C2F465598F7CFA90980FBB14C1B2F5F5F502D5D5D5A1ACAC + 8CCC4F5658B66C19C8BC8A4F3FFD1443870EC5E2C58BE97907A5A5A510668415 + 181848CFB3F8F2CB2FB163C70ED8DADAC2C3C303767676D8B56B17BEF9E61B8C + 1A350A3E3E3E3D6CB8B8B8E0E38F3FC6F6EDDBC9BC5B085A97EEA2CFB3151515 + 3170E040383A3A0A6C444747835C43404D4D8DADBF28968A962D21E70472AD81 + 4F3EF9044F9E3C61F7D1B62E5AB4882D43E66EFCFCF3CFF41C49E679431C3B76 + 0CFAFAFAB0B6B6C6A44993306BD62CB6DC8A152B306FDE3C242626D2091C4141 + 41ECFE952B57B2BF7BD3E4C993599FE45A84FD4D633D7CF87096A5EDA6DFFBE2 + BFF8E20BBC7CF9922D3F66CC18B67E7FFDF517FBDBD9D9B94F961339FFB1E597 + 2C5982A3478F0A78DA4FFDE1757575053CCD09AEFE919191FDE26FDDBA25A87F + 424202BB2F343494DDF7F7DF7FF7C98A8989B1D7119C2FCAD0DCA47D48BFD3EB + 0E727D82A54B97B27D4CCB7CF4D14720E75490EB53367F393F73E6CC61BF3F7D + FA94CD731D1D1D414E05040474F1EBE0E020C8239A1783060DC2A3478F04FBAE + 5CB9C2E6A58A8A0A9BA7B40EC2FC89132740734F555595AD8F8D8D4D8FFCA4D7 + AF23478EC4B7DF7E8B19336674E1274C98C08E471A6B7777F72E392D3C7E8B8B + 8BC9F591099B9B43860C61D9C18307B37D6C646484A2A2A22E4C5FD706837F18 + 36E07DD70F878B439815F116CC97E6E318FBF43B8C6F792C6390EEF58979F6DD + 5912F116CBC6C71A8B5934BCFADA2CD39B196B3E9EF9F808C30CD1F8E4DDDFDE + E4FB9EFCFEF2CAAC81C6A3199B540FE65E4DB28C59BA57BC61D295FAED7E8731 + C5652BCE9685255B1485AEFDC562123390F29AEFF8B08682C21116F3C01CFAEC + B25771C475D7EAE738157711E22EF210339A8BF1AA3F61FCD1DF31D57615461B + FF7EE2D3635DFDE7A3F9C99E503D1C0E378075453894E32E60ADA712965DD9FC + 628ED92CF5B147074B7FB4E1A3D3CC4A863768C347F89732F3EBA70AEFEE9BD8 + 563FBFEFD19A01EB8624483E37C634DB35FC75B776CED91F769AF9EBBA3833C1 + 751D33FAEC0F0CB395F4C46A46EE7365E6EB6FB4C60878FDCA70AF830577B029 + C90A7F051FC1577B87367E693E7E9154D225E687E73ACC3729E68C062F88317E + 6ECFACB45AC74C3019C78CBA2DF1EE6FA6525D6C96469EC19FA107F1D37D790C + 31998E61E67331F2E2E2BCB1B106F3B972A16D39474F441AA84C349FB6FE4B87 + 855F70FBC769FE3672AE9BE4BAB11A627B98459F9C6594FF75FB0BB59F925432 + 3CB766A05E62B1E72ECC71DF8EB581C7B0FC9622C69C9B8B19616A1A82BF9D55 + FE1723E625CB7C7F690B3364EB68E6ABBD031946750023177391218B40263433 + 6C9B6C8866F3CA081D4C7BAA8305CF8DA09F71DB87E33F755DCF7C16A4C230D1 + 6AE31765DB7DEE9A11C06C70DEC07C79741033701BB996BEB3E7E70D7E07EB66 + 859FC4F7417B30D95B194723CDBC38DEF34D1A73AB3E9E599F6098BE21C9A4F1 + 6649B8DE4E1FE585BFEBFDB16E9CFEF47BF3DCA5DFCCB97F083F872A6244FC11 + 0CB55E861F8D66844F3215EBCCED964EF17253E4AEBEB286798E35A4BDE53B96 + 5E5FD7B1DA431E338395F163B43C8619CEA9FBE6F29A90C1D75760A89958FBE0 + 7D8359FEABAFBE6235FCDB61CC9439E30E6CBCB00A32A1B25819218B713E2B30 + FCB218BE54FABDECF3556364BE369E37F16B9B3966C3CE8B55F5FAFC6D20B3F0 + 3BB111F7476D1E9D3A78FEB7CF064D1D62F7C5C6D1DFB2CFB1077EC20C369F36 + E82BA31F06BEE7F9DDE7CCC7EC73C2515D1E1EFEEB33E6CB33939821DA0305F9 + F3C90EBBC99F2B5E091E2863E1C6C85A7DF9A1CF093E23EC74B74AFCA01F8E8F + A52DA2998D17BEFE107EA08CE5CD31FA8F31DDAD8AD88810D818AA766EC888E3 + A65FBCD7C056E3AF3E96B1783A86F8E76C0C92B34CFCDEFC6ADC18133BF37E55 + 82F8E36C4CBD518231176E142D78968689F6EE098CAEEE47FDB53148CE226ECC + 0597A2A55119904A28C4F70B92DB476DBCFF72F2852BC64375CF8DEA0BA7EDFD + E18263DCF2E80CC82515E1D715E918B7240397726B614BAE5565EF86E44FB170 + B4FC55D5EA53513C8DD54F66F6E6531D3C12C62C4C6EFF636526AE14D6C3AFAA + 1941352DF0AA6884515AD19B59975DE37E30B29CD1C79DE3013F6E097949D97B + D52D886FEC603F9D4BF930C9AFC6D1F4522CB813523CF68293FFF74617978AB2 + 30DBFA8607F547FD52FF943525EC89CC3228BC2AC2EA845C4C7B968EEFCE5FBD + 2F8A9F6AE978CE3EBF122E650DB8CCAB83515E158E659461FBCB4E767A5426BE + F77FDA3AC2D05A49143F4AF7C27495477175B4BE5AD91538F0BA043229855811 + 9F8BA9CF33F0FDE3971861E118CD6CF51C283204A4CFE739DD4E394CDABAEB15 + 0F9B5EE463516C3626D13A3F7A89E1366E99430D2FFDDE577F8EBB70C566636C + 265691FA8A4567E2B72769181E14DB31DCC239E9BB33E67FBC2F9D46E99A0DFD + D5DE339DFAFC3E20EACDF0CBEEAFBF33B1BB34FA88F9BFFA3BB646195D961961 + 76C577B8D1C53DA374753F67FE2FDD16DB64E7CBDF29CEE124E5C1CB59669773 + B0BFFC4E9F921CB73280D38D920E683EADAD94F1E2E5487B16E5481149124978 + 14E648B817E6CCBF94992FCC2BDC2DC9B95AD806FB8256D8E6B5E0524E332CB3 + 9A609ED100D3D77C18A7D5E3ECAB3A9C49A985CE8B1A6CB8999723CC4BDF2ECA + D9E157829D7EA5AC76F85295B052F0E9D476818A2173BBB86DAB4751C1BC4B99 + 6729BFC93D3F673B297BA314FD96414243DB4CB3F415945FEB9A9BB3D3AF277F + 9DC4C1B9B8034EBC37B85AF486CC27EDA48DEDB0CB6F83825F69C154DD1C76AE + 5FEC905578F87125BBDF96C826AF95CC5B2DB898D302CBEC66586435C33CB309 + E7339A6096DE0893D78D58EF921FC7B57FA15D6685767C2DBBFF5C5A038C52F9 + 307CC587C1CB7AE813E9A5D44137B90EDA2F6AA195548B53893558669FED2FE8 + 7FFB2CFEE9C4CEFD9A09D5D088AFC6C9B82AA8C556E1784C258E4557E2485405 + 0E3FAFC0C167E5D817518AB9173304E786A557B29BE87ED56765D8FFB40CFB9E + 94624F642954224AA0145E82DD8F8BA1F8A8183B1FF2B023AC089BBC0B3AA69A + BD5AC1F1B32C335A973965B15A4AE598D5BAC431B3578959A5B771B1FBFF7AFB + 279F238484847CFAE0C183ADC1C1C177EEDFBFFFEADEBD7B6D8181812DFEFEFE + 717E7E7E1E64DDBFD2DBDB7B602FEC44C226D1F5345D2791B589E0BE375DD3E5 + E6E682BE3B45D648115E5E5EDF77E789CF87F4BE79474747AFF75DDBDADAD8F5 + A68787C7B5EE3C59BF97353737BF97A7F7176EDEBC59D69D276D2DA3F7CBE9FA + 8BAE4F1B1B1BD9F2F43E744D4D0DB2B3B3111111C1AE0D5D5D5D7BF064BD5946 + 197A8F9B967DF5EA15BBCE4F4A4A6239121F76BD49D76F376EDCE8C1931897D1 + E716555555AC8FFCFC7CF693C684DE4BA6B1A32A2828A0F7097AF0BEBEBE65F4 + 1E3F6D1F65B2B2B2D8B2B42E515151ECFAFCE1C387AC5D4747C71EFCDDBB77CB + 689FD1F65396BE2347FB2C2323835DAB1F360DC3D86D0F31685908FE677DE09B + 812B82D485F93B77EE94D1F52BB59F9696C6B69DBEA749BF1FBF108E79271271 + 3EA009F75F75E0A87B0326EF8F69FF7859B0AAE019A297571917E7949414BC78 + F182F54DE3387A4B30611B216E057C7312F8D910586C528E81CB83B2399EE444 + 1965691B2827CC0F5A1A823B715DF3E23B9D6A7CBC3444F01C88E4C45AD2AF7C + 7A7F9EE62B8D25ED0FFA3946FA2114AFF209430AAA35135561E09E3C9018140A + C780F4EBCFD7AE5DBBEAE4E454433ED9FB24C42EA4D4BC304EE9397E3EC9C320 + 8D320CD89D858FC543DB07AEB8AFD9DB58B4B3B31B626D6D3DCDD2D2728A9999 + D9A763A422D589BF1C5A67F259D0172B2C0787321C3C98874B974A111DFDE1CF + 1F6FDFAE22F9D70065E55CD8DB972120A0A6DF3692931B49FFBF7BCEEEE3530D + FAACBEBFFCAD5B5582B274587B7A56F69B6D6EEE80AFEFBB770D2223EBC97868 + E9377FEF5E0DEAEAD8E775AC6F77F7CA0F8A1D57D7C2C2165859952230B0FF71 + CBCF6F81AD6D2966CF7E85810363D9FEA3EDE97FDC2A31776E2ACBFEF24B3299 + AF2AFACDD247AE274EE49385692C7EFEF905B66DCB2263A9B1DF7C78781D2424 + 32A1A65640FCC7C1C4A4F883E2E6E4548E091352D8BA2F5DFA1A5E5E55FDE6AB + ABDB212797CDD6FDEBAF13B06B570EE8BEFEF2DEDE5558B0208DE5870E4D04AD + CB87D49DD6554C2C95E5A5A4B2C87C5FF7417C4D4D3B0C0D799095CD021DB76F + 4F65FFD1BF17CEF2320CCFF239CFCFBC790A996E9A4877D144DA750DA45DD3C0 + 4B6735A4389EC08BABC790607F14F176871163730851970E20D25E931F71F148 + 7896D7D937B599F1287BEC8C92202B918A7BFEA4CBE7F2DD4049E44D3CB638F4 + 86FACD203ED36F68B07E53AFA9E3A5931A921D8F23E94AA7DF385BE2D7FA20EB + F799E57E445ED88B88F32A7864AACCB2D3A64DA3EF73B3F75C67CE9CC9DEE39F + 3D7B367BAF79EEDCB9ECBDD4F9F3E7B3F790E973027ADF9BDE6F0E3552C46BE2 + 97323FFDF413FBDC60ECD8B1F8F5D75FF1DB6FBFE1F7DF7FC7F8F1E33171E244 + F6D901BDF73F65CA14D61F7D4E107C76075B678EA7D726F4DE6E7FF97B7ADBD9 + 18D33A72E5E939ECF8F1E32219DA46AE7DF4FE7780B61CDB3FB45DF4FE32BDD6 + A0F7A0FFFCF3CF1E0C170F7ACF9CDE4B5EBF7E3D7C4F6F63634CEFB5D3F253A7 + 4E65192E8E94A1E2181A47EA8B6AF3E6CDB8AB29CDF6CFAA55ABBA305CDC3986 + C67EE1C2856CECE9BD7E1AFFAD5BB7E2B6BA24626D0F09EEE5738C705F71FD45 + EB48B57CF972F6D98D949414BC4E6C41F4A5836C5BB87A717E3886F633C7D098 + 53AD5EBD9ACC6BDBE0794C02CFAD0EB06D919090C0962D5BD87A494A4AB2F6A9 + A4A5A5212323C39697959525F38B1C2B797979781CDD84084B558708F33D6C2E + 8619EFC683B33B11A4AF8040DDEDF027FD4363EC734A1A7734A4705B4D12B748 + 9D3D885F8F239B70E3F026877FF2FD7F1717970C6363E34AA20A11AA3C77EE5C + 5E6F3CC9DB20720DDCDAD77B0FD48E289EB00FC875FE1BFA1CA6AF6DD3E64DE6 + 22AE736EF9FAF8BE21EB0D903546E7DF82BE6917BC2FC3BD83C4BE872A2E6ED8 + 9D3F7FFE7C3A3D46AF95E93B43DCBB43C2A2FB7AE3C9B5552A3DC69625D7FF0D + 4D0D687AFB0E515353A75ADEBE77D30BFF827B7788BE5F2350DDDBCFEA725496 + 97801713829C4B7BDF1C58397DC89AE9BF0D27623E19F811636E6ECEF2B5B5D5 + ACAADF7E722A703B833CA29AB428E404BBA1E1FEE5AA0C4B65FED51D4BBAF095 + 95155D55518EFC1BDA28CDCD407D611AA28CB7E1F525325F3A6BE3B9C9DE1AC2 + 3F20FCD7247E2C5F5E5A2A107D07892ADB551F6DBC5438AC1F01BB4D3FC07ADD + 776D8F4E4BA0C0761FEC64C52A2274A499F36FDB2FFC8E0EFD5E70F5386A5263 + 10672C03EBADE304F1CBBF639C9FE97014813B279612BE868B1F7D5747582F1C + 75107BDB01C5D78EC34E8EFD7FE961DDBA75863521560DBCC0CB70D8FA6B69B8 + 8E7495A9A929CBD3F79EBA2B2BC01135B70D11637E0005F76D91E36D5A534DCE + 53F56117E1AC309B26EF001B1BEBCCCEFE6FEAA266D2EFD9E47C77CFE8002A9C + 8F02093E687C1182EC4BDB705E7C54ED636DA9BA810CF3AD9E9EDE337B7B7BFA + 3CB04394620DE5714F7D3322CEED46D8E92D509BC2C43DD292E4139E19D8C7FA + 7DC9CCC96CFF12D16203620CE523A20CE45A084FB72F3A1F3530CCFF01C3EC80 + A7 } end object Timer1: TTimer @@ -519,4 +606,34 @@ object IgPubPageFrame: TIgPubPageFrame Left = 46 Top = 169 end + object pmDev: TPopupMenu + Images = ImageList1 + Left = 152 + Top = 74 + object MenuItem4: TMenuItem + Caption = 'Clean Generated Files' + ImageIndex = 17 + end + object MenuItem5: TMenuItem + Caption = 'Clear Tx Cache' + ImageIndex = 19 + end + object MenuItem6: TMenuItem + Caption = 'Copy Jekyll Command' + ImageIndex = 20 + end + object MenuItem7: TMenuItem + Caption = 'Command Prompt Here' + ImageIndex = 21 + end + object MenuItem8: TMenuItem + Caption = 'Open Folder' + ImageIndex = 18 + end + end + object pmAdd: TPopupMenu + Images = ImageList1 + Left = 109 + Top = 91 + end end diff --git a/toolkit2/frames/ftk_frame_igpub.pas b/toolkit2/frames/ftk_frame_igpub.pas index dd2f5292a..2ffa96fda 100644 --- a/toolkit2/frames/ftk_frame_igpub.pas +++ b/toolkit2/frames/ftk_frame_igpub.pas @@ -34,7 +34,7 @@ interface uses Classes, SysUtils, Forms, Controls, StdCtrls, ComCtrls, ExtCtrls, Dialogs, Graphics, - LclIntf, Buttons, + LclIntf, Buttons, Menus, fsl_base, fsl_utilities, fsl_json, fsl_fetcher, fsl_threads, fsl_fpc, fsl_versions, fui_lcl_managers, fui_lcl_progress, ftk_context, ftk_store_temp, ftk_worker_base, ftk_engine_igpub, dlg_igpub_config, dlg_igpub_github; @@ -52,14 +52,14 @@ TIGPublicationFolder = class (TFslObject) private FLineCount: integer; FManager : TIGPublicationManager; - FEngine: TIgPublisherBuildEngine; + FEngine: TIgPublisherBuildBaseEngine; FFolder: String; FLines: TStringList; Fname: String; FRunLength: Int64; FStartRun: Int64; FStatus: TIGPublicationFolderStatus; - procedure SetEngine(AValue: TIgPublisherBuildEngine); + procedure SetEngine(AValue: TIgPublisherBuildBaseEngine); procedure emitLine(line : String; repl : boolean); function log : String; @@ -77,7 +77,7 @@ TIGPublicationFolder = class (TFslObject) property name : String read Fname write FName; property folder : String read FFolder write FFolder; property lines : TStringList read FLines; - property engine : TIgPublisherBuildEngine read FEngine write SetEngine; + property engine : TIgPublisherBuildBaseEngine read FEngine write SetEngine; property RunLength : Int64 read FRunLength write FRunLength; property LineCount : integer read FLineCount write FLineCount; property StartRun : Int64 read FStartRun write FStartRun; @@ -151,6 +151,14 @@ TIgPubPageFrame = class(TFrame) cbxVersions: TComboBox; ImageList1: TImageList; lvFolders: TListView; + mnuAddFolder: TMenuItem; + mnuAddGit: TMenuItem; + mnuAddFolders: TMenuItem; + MenuItem4: TMenuItem; + MenuItem5: TMenuItem; + MenuItem6: TMenuItem; + MenuItem7: TMenuItem; + MenuItem8: TMenuItem; mStatus: TMemo; Panel1: TPanel; Panel2: TPanel; @@ -160,14 +168,15 @@ TIgPubPageFrame = class(TFrame) fd: TSelectDirectoryDialog; Panel6: TPanel; Panel7: TPanel; + pmDev: TPopupMenu; + pmAdd: TPopupMenu; ProgressBar1: TProgressBar; Splitter1: TSplitter; Timer1: TTimer; ToolBar1: TToolBar; tbAdd: TToolButton; tbDelete: TToolButton; - tbAddSet: TToolButton; - tbGitHub: TToolButton; + tbDevTools: TToolButton; ToolButton2: TToolButton; tbBuild: TToolButton; tbUp: TToolButton; @@ -178,6 +187,7 @@ TIgPubPageFrame = class(TFrame) tbDown: TToolButton; ToolButton8: TToolButton; tbConfig: TToolButton; + procedure mnuAddFolderClick(Sender: TObject); procedure tbConfigClick(Sender: TObject); procedure tbOpenClick(Sender: TObject); procedure tbQAClick(Sender: TObject); @@ -265,7 +275,7 @@ procedure TIGPublicationManager.updateMemo; finally FLock.Unlock; end; - if (FCurrent.status <> fsRunning) or ((FCurrent.RunLength = 0) and (FCurrent.LineCount = 0)) or (FCurrent.StartRun = 0) then + if (FCurrent.status <> fsRunning) or not FCurrent.engine.trackBuildTime then begin FFrame.ProgressBar1.Enabled := false; FFrame.ProgressBar1.Position := 0; @@ -317,7 +327,8 @@ procedure TIGPublicationManager.updateStatuses; if (o.engine.success) then begin o.status := fsSuccess; - o.RunLength := GetTickCount64 - o.StartRun; + if o.engine.trackBuildTime then + o.RunLength := GetTickCount64 - o.StartRun; o.lineCount := o.lines.count; FFrame.FWorker.lastChange := GetTickCount64; FFrame.FWorker.lastChangeChecked := false; @@ -601,6 +612,8 @@ function TIGPublicationManager.deleteItem(item: TIGPublicationFolder): boolean; end; function TIGPublicationManager.executeItem(item: TIGPublicationFolder; mode: String): boolean; +var + engine : TIgPublisherBuildEngine; begin result := false; if (item.status = fsRunning ) then @@ -609,15 +622,16 @@ function TIGPublicationManager.executeItem(item: TIGPublicationFolder; mode: Str begin item.lines.clear; item.lines.add('fBuilding '+item.name+'. Starting at '+TFslDateTime.makeLocal.toString('c')); - item.engine := TIgPublisherBuildEngine.create; - item.engine.folder := item.folder; - item.engine.OnEmitLine := item.emitLine; - item.engine.javaCmd := FFrame.FJavaCmd; - item.engine.devParams := FFrame.FDevParams; - item.engine.txSrvr := FFrame.FTxServers[FFrame.cbxTxServer.ItemIndex]; - item.engine.version := FFrame.cbxVersions.text; - item.engine.url := FFrame.FIgUrls[FFrame.cbxVersions.ItemIndex]; - item.engine.Start; + engine := TIgPublisherBuildEngine.create; + item.engine := engine; + engine.folder := item.folder; + engine.OnEmitLine := item.emitLine; + engine.javaCmd := FFrame.FJavaCmd; + engine.devParams := FFrame.FDevParams; + engine.txSrvr := FFrame.FTxServers[FFrame.cbxTxServer.ItemIndex]; + engine.version := FFrame.cbxVersions.text; + engine.url := FFrame.FIgUrls[FFrame.cbxVersions.ItemIndex]; + engine.Start; item.status := fsRunning; item.StartRun := GetTickCount64; result := true; @@ -648,10 +662,9 @@ function TIGPublicationManager.updateItem(item: TIGPublicationFolder; mode : Str else begin item.lines.clear; - item.engine := TIgPublisherBuildEngine.create; + item.engine := TIgPublisherUpdateEngine.create; item.engine.folder := item.folder; item.engine.OnEmitLine := item.emitLine; - item.engine.doGit := true; item.engine.Start; item.StartRun := 0; item.status := fsRunning; @@ -696,7 +709,7 @@ procedure TIGPublicationFolder.terminate; // nothing yet end; -procedure TIGPublicationFolder.SetEngine(AValue: TIgPublisherBuildEngine); +procedure TIGPublicationFolder.SetEngine(AValue: TIgPublisherBuildBaseEngine); begin FEngine.Free; FEngine := AValue; @@ -786,6 +799,8 @@ procedure TIgPubPageFrame.getFocus; end; procedure TIgPubPageFrame.init(json: TJsonObject); +var + grp : TControlEntry; begin FIgUrls := TStringList.create; FTxServers := TStringList.create; @@ -793,9 +808,10 @@ procedure TIgPubPageFrame.init(json: TJsonObject); FManager := TIGPublicationManager.create; FManager.FFrame := self; - FManager.registerControl(tbAdd, copAdd); - FManager.registerControl(tbGitHub, copAdd, 'git'); - FManager.registerControl(tbAddSet, copAddSet, 'set'); + grp := FManager.registerControlForMenu(tbAdd, pmAdd); + FManager.registerMenuEntry(grp, 'Folder', 18, copAdd); + FManager.registerMenuEntry(grp, 'From GitHub', 15, copAdd, 'git'); + FManager.registerMenuEntry(grp, 'Sub-Folders', 14, copAddSet); FManager.registerControl(tbDelete, copDelete); FManager.registerControl(tbUp, copUp); FManager.registerControl(tbDown, copDown); @@ -869,6 +885,12 @@ procedure TIgPubPageFrame.tbConfigClick(Sender: TObject); end; end; + +procedure TIgPubPageFrame.mnuAddFolderClick(Sender: TObject); +begin + +end; + procedure TIgPubPageFrame.tbOpenClick(Sender: TObject); begin if FManager.FCurrent <> nil then @@ -989,6 +1011,11 @@ procedure TIgPubPageFrame.updateButtons; begin tbOpen.enabled := FileExists(FilePath([FManager.FCurrent.FFolder, 'output', 'index.html'])); tbQA.enabled := FileExists(FilePath([FManager.FCurrent.FFolder, 'output', 'qa.html'])); + {$IFDEF WINDONWS} + tbDevTools.enabled := FileExists(FilePath([FManager.FCurrent.FFolder, 'clean.bat'])); + {$ELSE} + tbDevTools.enabled := FileExists(FilePath([FManager.FCurrent.FFolder, 'clean.sh'])); + {$ENDIF} end; end; diff --git a/toolkit2/frm_main.pas b/toolkit2/frm_main.pas index 11c6aa9c4..524234d62 100644 --- a/toolkit2/frm_main.pas +++ b/toolkit2/frm_main.pas @@ -548,6 +548,7 @@ TMainToolkitForm = class(TForm) procedure Timer1Timer(Sender: TObject); procedure ToolButton1Click(Sender: TObject); procedure ToolButton2Click(Sender: TObject); + procedure ToolButton32Click(Sender: TObject); procedure tvProjectsChange(Sender: TObject; Node: TTreeNode); procedure tvProjectsChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean); @@ -1071,6 +1072,11 @@ procedure TMainToolkitForm.ToolButton2Click(Sender: TObject); end; +procedure TMainToolkitForm.ToolButton32Click(Sender: TObject); +begin + +end; + procedure TMainToolkitForm.tvProjectsChange(Sender: TObject; Node: TTreeNode); begin end; diff --git a/toolkit2/tasks/ftk_engine_igpub.pas b/toolkit2/tasks/ftk_engine_igpub.pas index 62d72f8cd..db6b0964b 100644 --- a/toolkit2/tasks/ftk_engine_igpub.pas +++ b/toolkit2/tasks/ftk_engine_igpub.pas @@ -39,55 +39,132 @@ interface type TIgPublisherBuildEngineLineEvent = procedure(line : String; repl : boolean) of Object; + { TIgPublisherBuildBaseEngine } + + TIgPublisherBuildBaseEngine = class (TFslThread) + private + FFolder : String; + FStartingDate : TDateTime; + FOnEmitLine: TIgPublisherBuildEngineLineEvent; + FWantStop : boolean; + procedure procEmitLine(sender : TFslExternalProcessThread; line : String; repl : boolean); + procedure doFetcherProgress(sender : TObject; progress : integer); + protected + function GetSuccess: boolean; virtual; + public + function trackBuildTime : boolean; virtual; + procedure terminate; virtual; + + property folder : String read FFolder write FFolder; + property success : boolean read GetSuccess; + property OnEmitLine : TIgPublisherBuildEngineLineEvent read FOnEmitLine write FOnEmitLine; + end; + + { TIgPublisherUpdateEngine } + + TIgPublisherUpdateEngine = class (TIgPublisherBuildBaseEngine) + public + procedure execute; override; + end; + + { TIgPublisherCleanEngine } + + TIgPublisherCleanEngine = class (TIgPublisherBuildBaseEngine) + public + procedure execute; override; + end; + { TIgPublisherBuildEngine } - TIgPublisherBuildEngine = class (TFslThread) + TIgPublisherBuildEngine = class (TIgPublisherBuildBaseEngine) private FDevParams: String; - FDoGit: boolean; - FFolder : String; FJavaCmd: String; - FOnEmitLine: TIgPublisherBuildEngineLineEvent; FTxSrvr : String; FUrl: String; FVersion : String; FJarName : String; - FWantStop : boolean; - FStartingDate : TDateTime; procedure checkJava; procedure checkInstallIgPublisher; - function GetSuccess: boolean; procedure runBuild; - procedure executeGitUpdate; - procedure procEmitLine(sender : TFslExternalProcessThread; line : String; repl : boolean); - procedure doFetcherProgress(sender : TObject; progress : integer); + protected + function GetSuccess: boolean; override; public - destructor Destroy; override; + function trackBuildTime : boolean; override; property javaCmd : String read FJavaCmd write FJavaCmd; property devParams : String read FDevParams write FDevParams; - property folder : String read FFolder write FFolder; property version : String read FVersion write FVersion; property url : String read FUrl write FUrl; property txSrvr : String read FTxSrvr write FTxSrvr; - property doGit : boolean read FDoGit write FDoGit; procedure execute; override; - procedure Terminate; + procedure terminate; override; - property success : boolean read GetSuccess; - property OnEmitLine : TIgPublisherBuildEngineLineEvent read FOnEmitLine write FOnEmitLine; end; implementation -{ TIgPublisherBuildEngine } +{ TIgPublisherCleanEngine } + +procedure TIgPublisherCleanEngine.execute; +begin + raise EFslException.create('todo'); +end; + +{ TIgPublisherBuildBaseEngine } + +procedure TIgPublisherBuildBaseEngine.procEmitLine(sender: TFslExternalProcessThread; line: String; repl : boolean); +begin + FOnEmitLine(line, repl); +end; + +procedure TIgPublisherBuildBaseEngine.doFetcherProgress(sender: TObject; progress: integer); +begin + if FWantStop then + abort; +end; + +function TIgPublisherBuildBaseEngine.GetSuccess: boolean; +begin + result := false; +end; -destructor TIgPublisherBuildEngine.Destroy; +function TIgPublisherBuildBaseEngine.trackBuildTime: boolean; begin - inherited Destroy; + result := false; end; +procedure TIgPublisherBuildBaseEngine.terminate; +begin + // nothing right now +end; + +{ TIgPublisherUpdateEngine } + +procedure TIgPublisherUpdateEngine.execute; +var + p : TFslExternalProcessThread; +begin + FOnEmitLine('git pull', false); + + p := TFslExternalProcessThread.create; + try + p.command := 'git'; + p.parameters.Add('pull'); + p.parameters.Add('--progress'); + p.folder := FFolder; + p.OnEmitLine := procEmitLine; + p.Start; + while p.Running do + sleep(50); + finally + p.free; + end; +end; + +{ TIgPublisherBuildEngine } + procedure TIgPublisherBuildEngine.checkJava; var p : TFslExternalProcessThread; @@ -162,6 +239,11 @@ function TIgPublisherBuildEngine.GetSuccess: boolean; result := false; end; +function TIgPublisherBuildEngine.trackBuildTime: boolean; +begin + Result := true; +end; + procedure TIgPublisherBuildEngine.runBuild; var p : TFslExternalProcessThread; @@ -197,65 +279,28 @@ procedure TIgPublisherBuildEngine.runBuild; end; end; -procedure TIgPublisherBuildEngine.executeGitUpdate; -var - p : TFslExternalProcessThread; -begin - FOnEmitLine('git pull', false); - - p := TFslExternalProcessThread.create; - try - p.command := 'git'; - p.parameters.Add('pull'); - p.parameters.Add('--progress'); - p.folder := FFolder; - p.OnEmitLine := procEmitLine; - p.Start; - while p.Running do - sleep(50); - finally - p.free; - end; -end; - -procedure TIgPublisherBuildEngine.procEmitLine(sender: TFslExternalProcessThread; line: String; repl : boolean); -begin - FOnEmitLine(line, repl); -end; - -procedure TIgPublisherBuildEngine.doFetcherProgress(sender: TObject; progress: integer); -begin - if FWantStop then - abort; -end; - procedure TIgPublisherBuildEngine.execute; begin try - if FDoGit then - executeGitUpdate + if FileExists(FilePath([FFolder, 'output', 'qa.json'])) then + FStartingDate := FileGetModified(FilePath([FFolder, 'output', 'qa.json'])) else - begin - if FileExists(FilePath([FFolder, 'output', 'qa.json'])) then - FStartingDate := FileGetModified(FilePath([FFolder, 'output', 'qa.json'])) - else - FStartingDate := 0; - if FileExists(FilePath([FFolder, 'ig-publisher.kill'])) then - DeleteFile(FilePath([FFolder, 'ig-publisher.kill'])); - if not FWantStop then - checkJava; - if not FWantStop and (url <> '#dev') then - checkInstallIgPublisher; - if not FWantStop then - runBuild; - end; + FStartingDate := 0; + if FileExists(FilePath([FFolder, 'ig-publisher.kill'])) then + DeleteFile(FilePath([FFolder, 'ig-publisher.kill'])); + if not FWantStop then + checkJava; + if not FWantStop and (url <> '#dev') then + checkInstallIgPublisher; + if not FWantStop then + runBuild; except on e : Exception do FOnEmitLine(e.message, false); end; end; -procedure TIgPublisherBuildEngine.Terminate; +procedure TIgPublisherBuildEngine.terminate; begin // java creates a double process (at least on windows) and we can't kill the actual operational process. // instead we ask it to die by creating this file